Modern Events Calendar Lite - Version 5.21.1

Version Description

15 July 2021 = - Fixed: Fatal error

Download this release

Release Info

Developer webnus
Plugin Icon 128x128 Modern Events Calendar Lite
Version 5.21.1
Comparing to
See all releases

Code changes from version 5.21.0 to 5.21.1

Files changed (186) hide show
  1. app/composer.json +10 -0
  2. app/composer.lock +254 -0
  3. app/libraries/factory.php +3 -6
  4. app/vendor/autoload.php +7 -0
  5. app/vendor/composer/ClassLoader.php +445 -0
  6. app/vendor/composer/LICENSE +19 -0
  7. app/vendor/composer/autoload_classmap.php +9 -0
  8. app/vendor/composer/autoload_files.php +10 -0
  9. app/vendor/composer/autoload_namespaces.php +10 -0
  10. app/vendor/composer/autoload_psr4.php +13 -0
  11. app/vendor/composer/autoload_real.php +73 -0
  12. app/vendor/composer/autoload_static.php +64 -0
  13. app/vendor/composer/installed.json +246 -0
  14. app/vendor/johngrogg/ics-parser/.editorconfig +11 -0
  15. app/vendor/johngrogg/ics-parser/.github/CONTRIBUTING.md +17 -0
  16. app/vendor/johngrogg/ics-parser/.github/ISSUE_TEMPLATE.md +15 -0
  17. app/vendor/johngrogg/ics-parser/.github/PULL_REQUEST_TEMPLATE.md +9 -0
  18. app/vendor/johngrogg/ics-parser/.github/RELEASE_CHECKLIST.md +8 -0
  19. app/vendor/johngrogg/ics-parser/.gitignore +51 -0
  20. app/vendor/johngrogg/ics-parser/LICENSE +15 -0
  21. app/vendor/johngrogg/ics-parser/README.md +178 -0
  22. app/vendor/johngrogg/ics-parser/composer.json +49 -0
  23. app/vendor/johngrogg/ics-parser/composer.lock +274 -0
  24. app/vendor/johngrogg/ics-parser/examples/ICal.ics +309 -0
  25. app/vendor/johngrogg/ics-parser/examples/index.php +175 -0
  26. app/vendor/johngrogg/ics-parser/src/ICal/Event.php +204 -0
  27. app/vendor/johngrogg/ics-parser/src/ICal/ICal.php +2430 -0
  28. app/vendor/nesbot/carbon/.php_cs.dist +60 -0
  29. app/vendor/nesbot/carbon/LICENSE +19 -0
  30. app/vendor/nesbot/carbon/build.php +87 -0
  31. app/vendor/nesbot/carbon/composer.json +53 -0
  32. app/vendor/nesbot/carbon/readme.md +94 -0
  33. app/vendor/nesbot/carbon/src/Carbon/Carbon.php +4665 -0
  34. app/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php +1130 -0
  35. app/vendor/nesbot/carbon/src/Carbon/CarbonPeriod.php +1445 -0
  36. app/vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php +67 -0
  37. app/vendor/nesbot/carbon/src/Carbon/Lang/af.php +31 -0
  38. app/vendor/nesbot/carbon/src/Carbon/Lang/ar.php +31 -0
  39. app/vendor/nesbot/carbon/src/Carbon/Lang/ar_Shakl.php +31 -0
  40. app/vendor/nesbot/carbon/src/Carbon/Lang/az.php +31 -0
  41. app/vendor/nesbot/carbon/src/Carbon/Lang/bg.php +31 -0
  42. app/vendor/nesbot/carbon/src/Carbon/Lang/bn.php +31 -0
  43. app/vendor/nesbot/carbon/src/Carbon/Lang/bs_BA.php +31 -0
  44. app/vendor/nesbot/carbon/src/Carbon/Lang/ca.php +36 -0
  45. app/vendor/nesbot/carbon/src/Carbon/Lang/cs.php +31 -0
  46. app/vendor/nesbot/carbon/src/Carbon/Lang/cy.php +29 -0
  47. app/vendor/nesbot/carbon/src/Carbon/Lang/da.php +31 -0
  48. app/vendor/nesbot/carbon/src/Carbon/Lang/de.php +46 -0
  49. app/vendor/nesbot/carbon/src/Carbon/Lang/dv_MV.php +31 -0
  50. app/vendor/nesbot/carbon/src/Carbon/Lang/el.php +31 -0
  51. app/vendor/nesbot/carbon/src/Carbon/Lang/en.php +40 -0
  52. app/vendor/nesbot/carbon/src/Carbon/Lang/eo.php +31 -0
  53. app/vendor/nesbot/carbon/src/Carbon/Lang/es.php +36 -0
  54. app/vendor/nesbot/carbon/src/Carbon/Lang/et.php +38 -0
  55. app/vendor/nesbot/carbon/src/Carbon/Lang/eu.php +31 -0
  56. app/vendor/nesbot/carbon/src/Carbon/Lang/fa.php +31 -0
  57. app/vendor/nesbot/carbon/src/Carbon/Lang/fi.php +31 -0
  58. app/vendor/nesbot/carbon/src/Carbon/Lang/fo.php +31 -0
  59. app/vendor/nesbot/carbon/src/Carbon/Lang/fr.php +36 -0
  60. app/vendor/nesbot/carbon/src/Carbon/Lang/gl.php +24 -0
  61. app/vendor/nesbot/carbon/src/Carbon/Lang/gu.php +31 -0
  62. app/vendor/nesbot/carbon/src/Carbon/Lang/he.php +31 -0
  63. app/vendor/nesbot/carbon/src/Carbon/Lang/hi.php +31 -0
  64. app/vendor/nesbot/carbon/src/Carbon/Lang/hr.php +31 -0
  65. app/vendor/nesbot/carbon/src/Carbon/Lang/hu.php +52 -0
  66. app/vendor/nesbot/carbon/src/Carbon/Lang/hy.php +31 -0
  67. app/vendor/nesbot/carbon/src/Carbon/Lang/id.php +31 -0
  68. app/vendor/nesbot/carbon/src/Carbon/Lang/is.php +31 -0
  69. app/vendor/nesbot/carbon/src/Carbon/Lang/it.php +36 -0
  70. app/vendor/nesbot/carbon/src/Carbon/Lang/ja.php +31 -0
  71. app/vendor/nesbot/carbon/src/Carbon/Lang/ka.php +31 -0
  72. app/vendor/nesbot/carbon/src/Carbon/Lang/kk.php +29 -0
  73. app/vendor/nesbot/carbon/src/Carbon/Lang/km.php +31 -0
  74. app/vendor/nesbot/carbon/src/Carbon/Lang/ko.php +31 -0
  75. app/vendor/nesbot/carbon/src/Carbon/Lang/lt.php +38 -0
  76. app/vendor/nesbot/carbon/src/Carbon/Lang/lv.php +47 -0
  77. app/vendor/nesbot/carbon/src/Carbon/Lang/mk.php +24 -0
  78. app/vendor/nesbot/carbon/src/Carbon/Lang/mn.php +62 -0
  79. app/vendor/nesbot/carbon/src/Carbon/Lang/ms.php +31 -0
  80. app/vendor/nesbot/carbon/src/Carbon/Lang/ne.php +31 -0
  81. app/vendor/nesbot/carbon/src/Carbon/Lang/nl.php +36 -0
  82. app/vendor/nesbot/carbon/src/Carbon/Lang/no.php +36 -0
  83. app/vendor/nesbot/carbon/src/Carbon/Lang/oc.php +40 -0
  84. app/vendor/nesbot/carbon/src/Carbon/Lang/pl.php +36 -0
  85. app/vendor/nesbot/carbon/src/Carbon/Lang/ps.php +31 -0
  86. app/vendor/nesbot/carbon/src/Carbon/Lang/pt.php +31 -0
  87. app/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php +31 -0
  88. app/vendor/nesbot/carbon/src/Carbon/Lang/ro.php +31 -0
  89. app/vendor/nesbot/carbon/src/Carbon/Lang/ru.php +31 -0
  90. app/vendor/nesbot/carbon/src/Carbon/Lang/sh.php +31 -0
  91. app/vendor/nesbot/carbon/src/Carbon/Lang/sk.php +38 -0
  92. app/vendor/nesbot/carbon/src/Carbon/Lang/sl.php +43 -0
  93. app/vendor/nesbot/carbon/src/Carbon/Lang/sq.php +31 -0
  94. app/vendor/nesbot/carbon/src/Carbon/Lang/sr.php +37 -0
  95. app/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl.php +43 -0
  96. app/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl_ME.php +43 -0
  97. app/vendor/nesbot/carbon/src/Carbon/Lang/sr_Latn_ME.php +43 -0
  98. app/vendor/nesbot/carbon/src/Carbon/Lang/sr_ME.php +12 -0
  99. app/vendor/nesbot/carbon/src/Carbon/Lang/sv.php +31 -0
  100. app/vendor/nesbot/carbon/src/Carbon/Lang/sw.php +31 -0
  101. app/vendor/nesbot/carbon/src/Carbon/Lang/th.php +31 -0
  102. app/vendor/nesbot/carbon/src/Carbon/Lang/tr.php +31 -0
  103. app/vendor/nesbot/carbon/src/Carbon/Lang/uk.php +31 -0
  104. app/vendor/nesbot/carbon/src/Carbon/Lang/ur.php +24 -0
  105. app/vendor/nesbot/carbon/src/Carbon/Lang/uz.php +31 -0
  106. app/vendor/nesbot/carbon/src/Carbon/Lang/vi.php +31 -0
  107. app/vendor/nesbot/carbon/src/Carbon/Lang/zh.php +31 -0
  108. app/vendor/nesbot/carbon/src/Carbon/Lang/zh_TW.php +31 -0
  109. app/vendor/nesbot/carbon/src/Carbon/Translator.php +143 -0
  110. app/vendor/nesbot/carbon/src/JsonSerializable.php +16 -0
  111. app/vendor/symfony/polyfill-mbstring/LICENSE +19 -0
  112. app/vendor/symfony/polyfill-mbstring/Mbstring.php +791 -0
  113. app/vendor/symfony/polyfill-mbstring/README.md +13 -0
  114. app/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1101 -0
  115. app/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1109 -0
  116. app/vendor/symfony/polyfill-mbstring/bootstrap.php +58 -0
  117. app/vendor/symfony/polyfill-mbstring/composer.json +34 -0
  118. app/vendor/symfony/translation/.gitignore +3 -0
  119. app/vendor/symfony/translation/CHANGELOG.md +108 -0
  120. app/vendor/symfony/translation/Catalogue/AbstractOperation.php +158 -0
  121. app/vendor/symfony/translation/Catalogue/MergeOperation.php +55 -0
  122. app/vendor/symfony/translation/Catalogue/OperationInterface.php +77 -0
  123. app/vendor/symfony/translation/Catalogue/TargetOperation.php +69 -0
  124. app/vendor/symfony/translation/Command/XliffLintCommand.php +270 -0
  125. app/vendor/symfony/translation/DataCollector/TranslationDataCollector.php +167 -0
  126. app/vendor/symfony/translation/DataCollectorTranslator.php +165 -0
  127. app/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php +44 -0
  128. app/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php +49 -0
  129. app/vendor/symfony/translation/DependencyInjection/TranslatorPass.php +79 -0
  130. app/vendor/symfony/translation/Dumper/CsvFileDumper.php +63 -0
  131. app/vendor/symfony/translation/Dumper/DumperInterface.php +31 -0
  132. app/vendor/symfony/translation/Dumper/FileDumper.php +113 -0
  133. app/vendor/symfony/translation/Dumper/IcuResFileDumper.php +106 -0
  134. app/vendor/symfony/translation/Dumper/IniFileDumper.php +45 -0
  135. app/vendor/symfony/translation/Dumper/JsonFileDumper.php +44 -0
  136. app/vendor/symfony/translation/Dumper/MoFileDumper.php +82 -0
  137. app/vendor/symfony/translation/Dumper/PhpFileDumper.php +38 -0
  138. app/vendor/symfony/translation/Dumper/PoFileDumper.php +61 -0
  139. app/vendor/symfony/translation/Dumper/QtFileDumper.php +50 -0
  140. app/vendor/symfony/translation/Dumper/XliffFileDumper.php +205 -0
  141. app/vendor/symfony/translation/Dumper/YamlFileDumper.php +62 -0
  142. app/vendor/symfony/translation/Exception/ExceptionInterface.php +21 -0
  143. app/vendor/symfony/translation/Exception/InvalidArgumentException.php +21 -0
  144. app/vendor/symfony/translation/Exception/InvalidResourceException.php +21 -0
  145. app/vendor/symfony/translation/Exception/LogicException.php +21 -0
  146. app/vendor/symfony/translation/Exception/NotFoundResourceException.php +21 -0
  147. app/vendor/symfony/translation/Exception/RuntimeException.php +21 -0
  148. app/vendor/symfony/translation/Extractor/AbstractFileExtractor.php +80 -0
  149. app/vendor/symfony/translation/Extractor/ChainExtractor.php +60 -0
  150. app/vendor/symfony/translation/Extractor/ExtractorInterface.php +38 -0
  151. app/vendor/symfony/translation/Extractor/PhpExtractor.php +256 -0
  152. app/vendor/symfony/translation/Extractor/PhpStringTokenParser.php +142 -0
  153. app/vendor/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php +30 -0
  154. app/vendor/symfony/translation/Formatter/MessageFormatter.php +48 -0
  155. app/vendor/symfony/translation/Formatter/MessageFormatterInterface.php +30 -0
  156. app/vendor/symfony/translation/IdentityTranslator.php +63 -0
  157. app/vendor/symfony/translation/Interval.php +109 -0
  158. app/vendor/symfony/translation/LICENSE +19 -0
  159. app/vendor/symfony/translation/Loader/ArrayLoader.php +66 -0
  160. app/vendor/symfony/translation/Loader/CsvFileLoader.php +65 -0
  161. app/vendor/symfony/translation/Loader/FileLoader.php +65 -0
  162. app/vendor/symfony/translation/Loader/IcuDatFileLoader.php +61 -0
  163. app/vendor/symfony/translation/Loader/IcuResFileLoader.php +91 -0
  164. app/vendor/symfony/translation/Loader/IniFileLoader.php +28 -0
  165. app/vendor/symfony/translation/Loader/JsonFileLoader.php +64 -0
  166. app/vendor/symfony/translation/Loader/LoaderInterface.php +38 -0
  167. app/vendor/symfony/translation/Loader/MoFileLoader.php +145 -0
  168. app/vendor/symfony/translation/Loader/PhpFileLoader.php +28 -0
  169. app/vendor/symfony/translation/Loader/PoFileLoader.php +148 -0
  170. app/vendor/symfony/translation/Loader/QtFileLoader.php +77 -0
  171. app/vendor/symfony/translation/Loader/XliffFileLoader.php +314 -0
  172. app/vendor/symfony/translation/Loader/YamlFileLoader.php +50 -0
  173. app/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd +2223 -0
  174. app/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd +411 -0
  175. app/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd +309 -0
  176. app/vendor/symfony/translation/LoggingTranslator.php +136 -0
  177. app/vendor/symfony/translation/MessageCatalogue.php +271 -0
  178. app/vendor/symfony/translation/MessageCatalogueInterface.php +136 -0
  179. app/vendor/symfony/translation/MessageSelector.php +94 -0
  180. app/vendor/symfony/translation/MetadataAwareInterface.php +54 -0
  181. app/vendor/symfony/translation/PluralizationRules.php +209 -0
  182. app/vendor/symfony/translation/README.md +13 -0
  183. app/vendor/symfony/translation/Reader/TranslationReader.php +63 -0
  184. app/vendor/symfony/translation/Reader/TranslationReaderInterface.php +30 -0
  185. app/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd +2223 -0
  186. app/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php +0 -0
app/composer.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "require": {
3
+ "johngrogg/ics-parser": "^2"
4
+ },
5
+ "autoload":{
6
+ "psr-4":{
7
+ "MEC\\":"core/src/"
8
+ }
9
+ }
10
+ }
app/composer.lock ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "content-hash": "82778bfd99b4c915557aac3d1e3871cf",
8
+ "packages": [
9
+ {
10
+ "name": "johngrogg/ics-parser",
11
+ "version": "v2.1.5",
12
+ "source": {
13
+ "type": "git",
14
+ "url": "https://github.com/u01jmg3/ics-parser.git",
15
+ "reference": "ffd1788215b19da9813420935715b2bb7919b88e"
16
+ },
17
+ "dist": {
18
+ "type": "zip",
19
+ "url": "https://api.github.com/repos/u01jmg3/ics-parser/zipball/ffd1788215b19da9813420935715b2bb7919b88e",
20
+ "reference": "ffd1788215b19da9813420935715b2bb7919b88e",
21
+ "shasum": ""
22
+ },
23
+ "require": {
24
+ "ext-mbstring": "*",
25
+ "nesbot/carbon": "~1.28",
26
+ "php": ">=5.3.0"
27
+ },
28
+ "require-dev": {
29
+ "squizlabs/php_codesniffer": "~2.9.1"
30
+ },
31
+ "type": "library",
32
+ "autoload": {
33
+ "psr-0": {
34
+ "ICal": "src/"
35
+ }
36
+ },
37
+ "notification-url": "https://packagist.org/downloads/",
38
+ "license": [
39
+ "MIT"
40
+ ],
41
+ "authors": [
42
+ {
43
+ "name": "Martin Thoma",
44
+ "email": "info@martin-thoma.de",
45
+ "role": "Original Developer"
46
+ },
47
+ {
48
+ "name": "John Grogg",
49
+ "email": "john.grogg@gmail.com",
50
+ "role": "Developer/Prior Owner"
51
+ },
52
+ {
53
+ "name": "Jonathan Goode",
54
+ "role": "Developer/Owner"
55
+ }
56
+ ],
57
+ "description": "ICS Parser",
58
+ "homepage": "https://github.com/u01jmg3/ics-parser",
59
+ "keywords": [
60
+ "iCalendar",
61
+ "ical",
62
+ "ical-parser",
63
+ "ics",
64
+ "ics-parser",
65
+ "ifb"
66
+ ],
67
+ "time": "2018-05-24T14:12:00+00:00"
68
+ },
69
+ {
70
+ "name": "nesbot/carbon",
71
+ "version": "1.30.0",
72
+ "source": {
73
+ "type": "git",
74
+ "url": "https://github.com/briannesbitt/Carbon.git",
75
+ "reference": "863a1a651ea324e1838da3a52753a4239b9d4bea"
76
+ },
77
+ "dist": {
78
+ "type": "zip",
79
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/863a1a651ea324e1838da3a52753a4239b9d4bea",
80
+ "reference": "863a1a651ea324e1838da3a52753a4239b9d4bea",
81
+ "shasum": ""
82
+ },
83
+ "require": {
84
+ "php": ">=5.3.9",
85
+ "symfony/translation": "~2.6 || ~3.0 || ~4.0"
86
+ },
87
+ "require-dev": {
88
+ "friendsofphp/php-cs-fixer": "~2",
89
+ "phpunit/phpunit": "^4.8.35 || ^5.7"
90
+ },
91
+ "type": "library",
92
+ "autoload": {
93
+ "psr-4": {
94
+ "": "src/"
95
+ }
96
+ },
97
+ "notification-url": "https://packagist.org/downloads/",
98
+ "license": [
99
+ "MIT"
100
+ ],
101
+ "authors": [
102
+ {
103
+ "name": "Brian Nesbitt",
104
+ "email": "brian@nesbot.com",
105
+ "homepage": "http://nesbot.com"
106
+ }
107
+ ],
108
+ "description": "A simple API extension for DateTime.",
109
+ "homepage": "http://carbon.nesbot.com",
110
+ "keywords": [
111
+ "date",
112
+ "datetime",
113
+ "time"
114
+ ],
115
+ "time": "2018-06-15T11:52:26+00:00"
116
+ },
117
+ {
118
+ "name": "symfony/polyfill-mbstring",
119
+ "version": "v1.8.0",
120
+ "source": {
121
+ "type": "git",
122
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
123
+ "reference": "3296adf6a6454a050679cde90f95350ad604b171"
124
+ },
125
+ "dist": {
126
+ "type": "zip",
127
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
128
+ "reference": "3296adf6a6454a050679cde90f95350ad604b171",
129
+ "shasum": ""
130
+ },
131
+ "require": {
132
+ "php": ">=5.3.3"
133
+ },
134
+ "suggest": {
135
+ "ext-mbstring": "For best performance"
136
+ },
137
+ "type": "library",
138
+ "extra": {
139
+ "branch-alias": {
140
+ "dev-master": "1.8-dev"
141
+ }
142
+ },
143
+ "autoload": {
144
+ "psr-4": {
145
+ "Symfony\\Polyfill\\Mbstring\\": ""
146
+ },
147
+ "files": [
148
+ "bootstrap.php"
149
+ ]
150
+ },
151
+ "notification-url": "https://packagist.org/downloads/",
152
+ "license": [
153
+ "MIT"
154
+ ],
155
+ "authors": [
156
+ {
157
+ "name": "Nicolas Grekas",
158
+ "email": "p@tchwork.com"
159
+ },
160
+ {
161
+ "name": "Symfony Community",
162
+ "homepage": "https://symfony.com/contributors"
163
+ }
164
+ ],
165
+ "description": "Symfony polyfill for the Mbstring extension",
166
+ "homepage": "https://symfony.com",
167
+ "keywords": [
168
+ "compatibility",
169
+ "mbstring",
170
+ "polyfill",
171
+ "portable",
172
+ "shim"
173
+ ],
174
+ "time": "2018-04-26T10:06:28+00:00"
175
+ },
176
+ {
177
+ "name": "symfony/translation",
178
+ "version": "v4.1.0",
179
+ "source": {
180
+ "type": "git",
181
+ "url": "https://github.com/symfony/translation.git",
182
+ "reference": "16328f5b217cebc8dd4adfe4aeeaa8c377581f5a"
183
+ },
184
+ "dist": {
185
+ "type": "zip",
186
+ "url": "https://api.github.com/repos/symfony/translation/zipball/16328f5b217cebc8dd4adfe4aeeaa8c377581f5a",
187
+ "reference": "16328f5b217cebc8dd4adfe4aeeaa8c377581f5a",
188
+ "shasum": ""
189
+ },
190
+ "require": {
191
+ "php": "^7.1.3",
192
+ "symfony/polyfill-mbstring": "~1.0"
193
+ },
194
+ "conflict": {
195
+ "symfony/config": "<3.4",
196
+ "symfony/dependency-injection": "<3.4",
197
+ "symfony/yaml": "<3.4"
198
+ },
199
+ "require-dev": {
200
+ "psr/log": "~1.0",
201
+ "symfony/config": "~3.4|~4.0",
202
+ "symfony/console": "~3.4|~4.0",
203
+ "symfony/dependency-injection": "~3.4|~4.0",
204
+ "symfony/finder": "~2.8|~3.0|~4.0",
205
+ "symfony/intl": "~3.4|~4.0",
206
+ "symfony/yaml": "~3.4|~4.0"
207
+ },
208
+ "suggest": {
209
+ "psr/log-implementation": "To use logging capability in translator",
210
+ "symfony/config": "",
211
+ "symfony/yaml": ""
212
+ },
213
+ "type": "library",
214
+ "extra": {
215
+ "branch-alias": {
216
+ "dev-master": "4.1-dev"
217
+ }
218
+ },
219
+ "autoload": {
220
+ "psr-4": {
221
+ "Symfony\\Component\\Translation\\": ""
222
+ },
223
+ "exclude-from-classmap": [
224
+ "/Tests/"
225
+ ]
226
+ },
227
+ "notification-url": "https://packagist.org/downloads/",
228
+ "license": [
229
+ "MIT"
230
+ ],
231
+ "authors": [
232
+ {
233
+ "name": "Fabien Potencier",
234
+ "email": "fabien@symfony.com"
235
+ },
236
+ {
237
+ "name": "Symfony Community",
238
+ "homepage": "https://symfony.com/contributors"
239
+ }
240
+ ],
241
+ "description": "Symfony Translation Component",
242
+ "homepage": "https://symfony.com",
243
+ "time": "2018-05-30T07:26:09+00:00"
244
+ }
245
+ ],
246
+ "packages-dev": [],
247
+ "aliases": [],
248
+ "minimum-stability": "stable",
249
+ "stability-flags": [],
250
+ "prefer-stable": false,
251
+ "prefer-lowest": false,
252
+ "platform": [],
253
+ "platform-dev": []
254
+ }
app/libraries/factory.php CHANGED
@@ -26,12 +26,9 @@ class MEC_factory extends MEC_base
26
  */
27
  public function __construct()
28
  {
29
- if($this->getPRO())
30
- {
31
- // Load Vendors
32
- require_once MEC_ABSPATH.'app/vendor/autoload.php';
33
- }
34
-
35
  // MEC Main library
36
  $this->main = $this->getMain();
37
 
26
  */
27
  public function __construct()
28
  {
29
+ // Load Vendors
30
+ require_once MEC_ABSPATH.'app/vendor/autoload.php';
31
+
 
 
 
32
  // MEC Main library
33
  $this->main = $this->getMain();
34
 
app/vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInitb7dce439a575ff5721c0c0e7d0a0abac::getLoader();
app/vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17
+ *
18
+ * $loader = new \Composer\Autoload\ClassLoader();
19
+ *
20
+ * // register classes with namespaces
21
+ * $loader->add('Symfony\Component', __DIR__.'/component');
22
+ * $loader->add('Symfony', __DIR__.'/framework');
23
+ *
24
+ * // activate the autoloader
25
+ * $loader->register();
26
+ *
27
+ * // to enable searching the include path (eg. for PEAR packages)
28
+ * $loader->setUseIncludePath(true);
29
+ *
30
+ * In this example, if you try to use a class in the Symfony\Component
31
+ * namespace or one of its children (Symfony\Component\Console for instance),
32
+ * the autoloader will first look for the class under the component/
33
+ * directory, and it will then fallback to the framework/ directory if not
34
+ * found before giving up.
35
+ *
36
+ * This class is loosely based on the Symfony UniversalClassLoader.
37
+ *
38
+ * @author Fabien Potencier <fabien@symfony.com>
39
+ * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+ private $classMapAuthoritative = false;
57
+ private $missingClasses = array();
58
+ private $apcuPrefix;
59
+
60
+ public function getPrefixes()
61
+ {
62
+ if (!empty($this->prefixesPsr0)) {
63
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
64
+ }
65
+
66
+ return array();
67
+ }
68
+
69
+ public function getPrefixesPsr4()
70
+ {
71
+ return $this->prefixDirsPsr4;
72
+ }
73
+
74
+ public function getFallbackDirs()
75
+ {
76
+ return $this->fallbackDirsPsr0;
77
+ }
78
+
79
+ public function getFallbackDirsPsr4()
80
+ {
81
+ return $this->fallbackDirsPsr4;
82
+ }
83
+
84
+ public function getClassMap()
85
+ {
86
+ return $this->classMap;
87
+ }
88
+
89
+ /**
90
+ * @param array $classMap Class to filename map
91
+ */
92
+ public function addClassMap(array $classMap)
93
+ {
94
+ if ($this->classMap) {
95
+ $this->classMap = array_merge($this->classMap, $classMap);
96
+ } else {
97
+ $this->classMap = $classMap;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Registers a set of PSR-0 directories for a given prefix, either
103
+ * appending or prepending to the ones previously set for this prefix.
104
+ *
105
+ * @param string $prefix The prefix
106
+ * @param array|string $paths The PSR-0 root directories
107
+ * @param bool $prepend Whether to prepend the directories
108
+ */
109
+ public function add($prefix, $paths, $prepend = false)
110
+ {
111
+ if (!$prefix) {
112
+ if ($prepend) {
113
+ $this->fallbackDirsPsr0 = array_merge(
114
+ (array) $paths,
115
+ $this->fallbackDirsPsr0
116
+ );
117
+ } else {
118
+ $this->fallbackDirsPsr0 = array_merge(
119
+ $this->fallbackDirsPsr0,
120
+ (array) $paths
121
+ );
122
+ }
123
+
124
+ return;
125
+ }
126
+
127
+ $first = $prefix[0];
128
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
129
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
130
+
131
+ return;
132
+ }
133
+ if ($prepend) {
134
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
135
+ (array) $paths,
136
+ $this->prefixesPsr0[$first][$prefix]
137
+ );
138
+ } else {
139
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
140
+ $this->prefixesPsr0[$first][$prefix],
141
+ (array) $paths
142
+ );
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Registers a set of PSR-4 directories for a given namespace, either
148
+ * appending or prepending to the ones previously set for this namespace.
149
+ *
150
+ * @param string $prefix The prefix/namespace, with trailing '\\'
151
+ * @param array|string $paths The PSR-4 base directories
152
+ * @param bool $prepend Whether to prepend the directories
153
+ *
154
+ * @throws \InvalidArgumentException
155
+ */
156
+ public function addPsr4($prefix, $paths, $prepend = false)
157
+ {
158
+ if (!$prefix) {
159
+ // Register directories for the root namespace.
160
+ if ($prepend) {
161
+ $this->fallbackDirsPsr4 = array_merge(
162
+ (array) $paths,
163
+ $this->fallbackDirsPsr4
164
+ );
165
+ } else {
166
+ $this->fallbackDirsPsr4 = array_merge(
167
+ $this->fallbackDirsPsr4,
168
+ (array) $paths
169
+ );
170
+ }
171
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
172
+ // Register directories for a new namespace.
173
+ $length = strlen($prefix);
174
+ if ('\\' !== $prefix[$length - 1]) {
175
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
176
+ }
177
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
178
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
179
+ } elseif ($prepend) {
180
+ // Prepend directories for an already registered namespace.
181
+ $this->prefixDirsPsr4[$prefix] = array_merge(
182
+ (array) $paths,
183
+ $this->prefixDirsPsr4[$prefix]
184
+ );
185
+ } else {
186
+ // Append directories for an already registered namespace.
187
+ $this->prefixDirsPsr4[$prefix] = array_merge(
188
+ $this->prefixDirsPsr4[$prefix],
189
+ (array) $paths
190
+ );
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Registers a set of PSR-0 directories for a given prefix,
196
+ * replacing any others previously set for this prefix.
197
+ *
198
+ * @param string $prefix The prefix
199
+ * @param array|string $paths The PSR-0 base directories
200
+ */
201
+ public function set($prefix, $paths)
202
+ {
203
+ if (!$prefix) {
204
+ $this->fallbackDirsPsr0 = (array) $paths;
205
+ } else {
206
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Registers a set of PSR-4 directories for a given namespace,
212
+ * replacing any others previously set for this namespace.
213
+ *
214
+ * @param string $prefix The prefix/namespace, with trailing '\\'
215
+ * @param array|string $paths The PSR-4 base directories
216
+ *
217
+ * @throws \InvalidArgumentException
218
+ */
219
+ public function setPsr4($prefix, $paths)
220
+ {
221
+ if (!$prefix) {
222
+ $this->fallbackDirsPsr4 = (array) $paths;
223
+ } else {
224
+ $length = strlen($prefix);
225
+ if ('\\' !== $prefix[$length - 1]) {
226
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
227
+ }
228
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
229
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Turns on searching the include path for class files.
235
+ *
236
+ * @param bool $useIncludePath
237
+ */
238
+ public function setUseIncludePath($useIncludePath)
239
+ {
240
+ $this->useIncludePath = $useIncludePath;
241
+ }
242
+
243
+ /**
244
+ * Can be used to check if the autoloader uses the include path to check
245
+ * for classes.
246
+ *
247
+ * @return bool
248
+ */
249
+ public function getUseIncludePath()
250
+ {
251
+ return $this->useIncludePath;
252
+ }
253
+
254
+ /**
255
+ * Turns off searching the prefix and fallback directories for classes
256
+ * that have not been registered with the class map.
257
+ *
258
+ * @param bool $classMapAuthoritative
259
+ */
260
+ public function setClassMapAuthoritative($classMapAuthoritative)
261
+ {
262
+ $this->classMapAuthoritative = $classMapAuthoritative;
263
+ }
264
+
265
+ /**
266
+ * Should class lookup fail if not found in the current class map?
267
+ *
268
+ * @return bool
269
+ */
270
+ public function isClassMapAuthoritative()
271
+ {
272
+ return $this->classMapAuthoritative;
273
+ }
274
+
275
+ /**
276
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
+ *
278
+ * @param string|null $apcuPrefix
279
+ */
280
+ public function setApcuPrefix($apcuPrefix)
281
+ {
282
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283
+ }
284
+
285
+ /**
286
+ * The APCu prefix in use, or null if APCu caching is not enabled.
287
+ *
288
+ * @return string|null
289
+ */
290
+ public function getApcuPrefix()
291
+ {
292
+ return $this->apcuPrefix;
293
+ }
294
+
295
+ /**
296
+ * Registers this instance as an autoloader.
297
+ *
298
+ * @param bool $prepend Whether to prepend the autoloader or not
299
+ */
300
+ public function register($prepend = false)
301
+ {
302
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
303
+ }
304
+
305
+ /**
306
+ * Unregisters this instance as an autoloader.
307
+ */
308
+ public function unregister()
309
+ {
310
+ spl_autoload_unregister(array($this, 'loadClass'));
311
+ }
312
+
313
+ /**
314
+ * Loads the given class or interface.
315
+ *
316
+ * @param string $class The name of the class
317
+ * @return bool|null True if loaded, null otherwise
318
+ */
319
+ public function loadClass($class)
320
+ {
321
+ if ($file = $this->findFile($class)) {
322
+ includeFile($file);
323
+
324
+ return true;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Finds the path to the file where the class is defined.
330
+ *
331
+ * @param string $class The name of the class
332
+ *
333
+ * @return string|false The path if found, false otherwise
334
+ */
335
+ public function findFile($class)
336
+ {
337
+ // class map lookup
338
+ if (isset($this->classMap[$class])) {
339
+ return $this->classMap[$class];
340
+ }
341
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342
+ return false;
343
+ }
344
+ if (null !== $this->apcuPrefix) {
345
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346
+ if ($hit) {
347
+ return $file;
348
+ }
349
+ }
350
+
351
+ $file = $this->findFileWithExtension($class, '.php');
352
+
353
+ // Search for Hack files if we are running on HHVM
354
+ if (false === $file && defined('HHVM_VERSION')) {
355
+ $file = $this->findFileWithExtension($class, '.hh');
356
+ }
357
+
358
+ if (null !== $this->apcuPrefix) {
359
+ apcu_add($this->apcuPrefix.$class, $file);
360
+ }
361
+
362
+ if (false === $file) {
363
+ // Remember that this class does not exist.
364
+ $this->missingClasses[$class] = true;
365
+ }
366
+
367
+ return $file;
368
+ }
369
+
370
+ private function findFileWithExtension($class, $ext)
371
+ {
372
+ // PSR-4 lookup
373
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
374
+
375
+ $first = $class[0];
376
+ if (isset($this->prefixLengthsPsr4[$first])) {
377
+ $subPath = $class;
378
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
379
+ $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
+ if (isset($this->prefixDirsPsr4[$search])) {
382
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
384
+ if (file_exists($file = $dir . $pathEnd)) {
385
+ return $file;
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+
392
+ // PSR-4 fallback dirs
393
+ foreach ($this->fallbackDirsPsr4 as $dir) {
394
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
395
+ return $file;
396
+ }
397
+ }
398
+
399
+ // PSR-0 lookup
400
+ if (false !== $pos = strrpos($class, '\\')) {
401
+ // namespaced class name
402
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
403
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
404
+ } else {
405
+ // PEAR-like class name
406
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
407
+ }
408
+
409
+ if (isset($this->prefixesPsr0[$first])) {
410
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
411
+ if (0 === strpos($class, $prefix)) {
412
+ foreach ($dirs as $dir) {
413
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
414
+ return $file;
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+
421
+ // PSR-0 fallback dirs
422
+ foreach ($this->fallbackDirsPsr0 as $dir) {
423
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
424
+ return $file;
425
+ }
426
+ }
427
+
428
+ // PSR-0 include paths.
429
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
430
+ return $file;
431
+ }
432
+
433
+ return false;
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Scope isolated include.
439
+ *
440
+ * Prevents access to $this/self from included files.
441
+ */
442
+ function includeFile($file)
443
+ {
444
+ include $file;
445
+ }
app/vendor/composer/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) Nils Adermann, Jordi Boggiano
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
app/vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
app/vendor/composer/autoload_files.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_files.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
10
+ );
app/vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'ICal' => array($vendorDir . '/johngrogg/ics-parser/src'),
10
+ );
app/vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
10
+ 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
11
+ 'MEC\\' => array($baseDir . '/core/src'),
12
+ '' => array($vendorDir . '/nesbot/carbon/src'),
13
+ );
app/vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInitb7dce439a575ff5721c0c0e7d0a0abac
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
+ public static function getLoader()
20
+ {
21
+ if (null !== self::$loader) {
22
+ return self::$loader;
23
+ }
24
+
25
+ spl_autoload_register(array('ComposerAutoloaderInitb7dce439a575ff5721c0c0e7d0a0abac', 'loadClassLoader'), true, true);
26
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInitb7dce439a575ff5721c0c0e7d0a0abac', 'loadClassLoader'));
28
+
29
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
+ if ($useStaticLoader) {
31
+ require_once __DIR__ . '/autoload_static.php';
32
+
33
+ call_user_func(\Composer\Autoload\ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac::getInitializer($loader));
34
+ } else {
35
+ $map = require __DIR__ . '/autoload_namespaces.php';
36
+ foreach ($map as $namespace => $path) {
37
+ $loader->set($namespace, $path);
38
+ }
39
+
40
+ $map = require __DIR__ . '/autoload_psr4.php';
41
+ foreach ($map as $namespace => $path) {
42
+ $loader->setPsr4($namespace, $path);
43
+ }
44
+
45
+ $classMap = require __DIR__ . '/autoload_classmap.php';
46
+ if ($classMap) {
47
+ $loader->addClassMap($classMap);
48
+ }
49
+ }
50
+
51
+ $loader->register(true);
52
+
53
+ if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac::$files;
55
+ } else {
56
+ $includeFiles = require __DIR__ . '/autoload_files.php';
57
+ }
58
+ foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequireb7dce439a575ff5721c0c0e7d0a0abac($fileIdentifier, $file);
60
+ }
61
+
62
+ return $loader;
63
+ }
64
+ }
65
+
66
+ function composerRequireb7dce439a575ff5721c0c0e7d0a0abac($fileIdentifier, $file)
67
+ {
68
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
+ require $file;
70
+
71
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
72
+ }
73
+ }
app/vendor/composer/autoload_static.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac
8
+ {
9
+ public static $files = array (
10
+ '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
11
+ );
12
+
13
+ public static $prefixLengthsPsr4 = array (
14
+ 'S' =>
15
+ array (
16
+ 'Symfony\\Polyfill\\Mbstring\\' => 26,
17
+ 'Symfony\\Component\\Translation\\' => 30,
18
+ ),
19
+ 'M' =>
20
+ array (
21
+ 'MEC\\' => 4,
22
+ ),
23
+ );
24
+
25
+ public static $prefixDirsPsr4 = array (
26
+ 'Symfony\\Polyfill\\Mbstring\\' =>
27
+ array (
28
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
29
+ ),
30
+ 'Symfony\\Component\\Translation\\' =>
31
+ array (
32
+ 0 => __DIR__ . '/..' . '/symfony/translation',
33
+ ),
34
+ 'MEC\\' =>
35
+ array (
36
+ 0 => __DIR__ . '/../..' . '/core/src',
37
+ ),
38
+ );
39
+
40
+ public static $fallbackDirsPsr4 = array (
41
+ 0 => __DIR__ . '/..' . '/nesbot/carbon/src',
42
+ );
43
+
44
+ public static $prefixesPsr0 = array (
45
+ 'I' =>
46
+ array (
47
+ 'ICal' =>
48
+ array (
49
+ 0 => __DIR__ . '/..' . '/johngrogg/ics-parser/src',
50
+ ),
51
+ ),
52
+ );
53
+
54
+ public static function getInitializer(ClassLoader $loader)
55
+ {
56
+ return \Closure::bind(function () use ($loader) {
57
+ $loader->prefixLengthsPsr4 = ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac::$prefixLengthsPsr4;
58
+ $loader->prefixDirsPsr4 = ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac::$prefixDirsPsr4;
59
+ $loader->fallbackDirsPsr4 = ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac::$fallbackDirsPsr4;
60
+ $loader->prefixesPsr0 = ComposerStaticInitb7dce439a575ff5721c0c0e7d0a0abac::$prefixesPsr0;
61
+
62
+ }, null, ClassLoader::class);
63
+ }
64
+ }
app/vendor/composer/installed.json ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "symfony/polyfill-mbstring",
4
+ "version": "v1.8.0",
5
+ "version_normalized": "1.8.0.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
9
+ "reference": "3296adf6a6454a050679cde90f95350ad604b171"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
14
+ "reference": "3296adf6a6454a050679cde90f95350ad604b171",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "php": ">=5.3.3"
19
+ },
20
+ "suggest": {
21
+ "ext-mbstring": "For best performance"
22
+ },
23
+ "time": "2018-04-26T10:06:28+00:00",
24
+ "type": "library",
25
+ "extra": {
26
+ "branch-alias": {
27
+ "dev-master": "1.8-dev"
28
+ }
29
+ },
30
+ "installation-source": "dist",
31
+ "autoload": {
32
+ "psr-4": {
33
+ "Symfony\\Polyfill\\Mbstring\\": ""
34
+ },
35
+ "files": [
36
+ "bootstrap.php"
37
+ ]
38
+ },
39
+ "notification-url": "https://packagist.org/downloads/",
40
+ "license": [
41
+ "MIT"
42
+ ],
43
+ "authors": [
44
+ {
45
+ "name": "Nicolas Grekas",
46
+ "email": "p@tchwork.com"
47
+ },
48
+ {
49
+ "name": "Symfony Community",
50
+ "homepage": "https://symfony.com/contributors"
51
+ }
52
+ ],
53
+ "description": "Symfony polyfill for the Mbstring extension",
54
+ "homepage": "https://symfony.com",
55
+ "keywords": [
56
+ "compatibility",
57
+ "mbstring",
58
+ "polyfill",
59
+ "portable",
60
+ "shim"
61
+ ]
62
+ },
63
+ {
64
+ "name": "symfony/translation",
65
+ "version": "v4.1.0",
66
+ "version_normalized": "4.1.0.0",
67
+ "source": {
68
+ "type": "git",
69
+ "url": "https://github.com/symfony/translation.git",
70
+ "reference": "16328f5b217cebc8dd4adfe4aeeaa8c377581f5a"
71
+ },
72
+ "dist": {
73
+ "type": "zip",
74
+ "url": "https://api.github.com/repos/symfony/translation/zipball/16328f5b217cebc8dd4adfe4aeeaa8c377581f5a",
75
+ "reference": "16328f5b217cebc8dd4adfe4aeeaa8c377581f5a",
76
+ "shasum": ""
77
+ },
78
+ "require": {
79
+ "php": "^7.1.3",
80
+ "symfony/polyfill-mbstring": "~1.0"
81
+ },
82
+ "conflict": {
83
+ "symfony/config": "<3.4",
84
+ "symfony/dependency-injection": "<3.4",
85
+ "symfony/yaml": "<3.4"
86
+ },
87
+ "require-dev": {
88
+ "psr/log": "~1.0",
89
+ "symfony/config": "~3.4|~4.0",
90
+ "symfony/console": "~3.4|~4.0",
91
+ "symfony/dependency-injection": "~3.4|~4.0",
92
+ "symfony/finder": "~2.8|~3.0|~4.0",
93
+ "symfony/intl": "~3.4|~4.0",
94
+ "symfony/yaml": "~3.4|~4.0"
95
+ },
96
+ "suggest": {
97
+ "psr/log-implementation": "To use logging capability in translator",
98
+ "symfony/config": "",
99
+ "symfony/yaml": ""
100
+ },
101
+ "time": "2018-05-30T07:26:09+00:00",
102
+ "type": "library",
103
+ "extra": {
104
+ "branch-alias": {
105
+ "dev-master": "4.1-dev"
106
+ }
107
+ },
108
+ "installation-source": "dist",
109
+ "autoload": {
110
+ "psr-4": {
111
+ "Symfony\\Component\\Translation\\": ""
112
+ },
113
+ "exclude-from-classmap": [
114
+ "/Tests/"
115
+ ]
116
+ },
117
+ "notification-url": "https://packagist.org/downloads/",
118
+ "license": [
119
+ "MIT"
120
+ ],
121
+ "authors": [
122
+ {
123
+ "name": "Fabien Potencier",
124
+ "email": "fabien@symfony.com"
125
+ },
126
+ {
127
+ "name": "Symfony Community",
128
+ "homepage": "https://symfony.com/contributors"
129
+ }
130
+ ],
131
+ "description": "Symfony Translation Component",
132
+ "homepage": "https://symfony.com"
133
+ },
134
+ {
135
+ "name": "nesbot/carbon",
136
+ "version": "1.30.0",
137
+ "version_normalized": "1.30.0.0",
138
+ "source": {
139
+ "type": "git",
140
+ "url": "https://github.com/briannesbitt/Carbon.git",
141
+ "reference": "863a1a651ea324e1838da3a52753a4239b9d4bea"
142
+ },
143
+ "dist": {
144
+ "type": "zip",
145
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/863a1a651ea324e1838da3a52753a4239b9d4bea",
146
+ "reference": "863a1a651ea324e1838da3a52753a4239b9d4bea",
147
+ "shasum": ""
148
+ },
149
+ "require": {
150
+ "php": ">=5.3.9",
151
+ "symfony/translation": "~2.6 || ~3.0 || ~4.0"
152
+ },
153
+ "require-dev": {
154
+ "friendsofphp/php-cs-fixer": "~2",
155
+ "phpunit/phpunit": "^4.8.35 || ^5.7"
156
+ },
157
+ "time": "2018-06-15T11:52:26+00:00",
158
+ "type": "library",
159
+ "installation-source": "dist",
160
+ "autoload": {
161
+ "psr-4": {
162
+ "": "src/"
163
+ }
164
+ },
165
+ "notification-url": "https://packagist.org/downloads/",
166
+ "license": [
167
+ "MIT"
168
+ ],
169
+ "authors": [
170
+ {
171
+ "name": "Brian Nesbitt",
172
+ "email": "brian@nesbot.com",
173
+ "homepage": "http://nesbot.com"
174
+ }
175
+ ],
176
+ "description": "A simple API extension for DateTime.",
177
+ "homepage": "http://carbon.nesbot.com",
178
+ "keywords": [
179
+ "date",
180
+ "datetime",
181
+ "time"
182
+ ]
183
+ },
184
+ {
185
+ "name": "johngrogg/ics-parser",
186
+ "version": "v2.1.5",
187
+ "version_normalized": "2.1.5.0",
188
+ "source": {
189
+ "type": "git",
190
+ "url": "https://github.com/u01jmg3/ics-parser.git",
191
+ "reference": "ffd1788215b19da9813420935715b2bb7919b88e"
192
+ },
193
+ "dist": {
194
+ "type": "zip",
195
+ "url": "https://api.github.com/repos/u01jmg3/ics-parser/zipball/ffd1788215b19da9813420935715b2bb7919b88e",
196
+ "reference": "ffd1788215b19da9813420935715b2bb7919b88e",
197
+ "shasum": ""
198
+ },
199
+ "require": {
200
+ "ext-mbstring": "*",
201
+ "nesbot/carbon": "~1.28",
202
+ "php": ">=5.3.0"
203
+ },
204
+ "require-dev": {
205
+ "squizlabs/php_codesniffer": "~2.9.1"
206
+ },
207
+ "time": "2018-05-24T14:12:00+00:00",
208
+ "type": "library",
209
+ "installation-source": "dist",
210
+ "autoload": {
211
+ "psr-0": {
212
+ "ICal": "src/"
213
+ }
214
+ },
215
+ "notification-url": "https://packagist.org/downloads/",
216
+ "license": [
217
+ "MIT"
218
+ ],
219
+ "authors": [
220
+ {
221
+ "name": "Martin Thoma",
222
+ "email": "info@martin-thoma.de",
223
+ "role": "Original Developer"
224
+ },
225
+ {
226
+ "name": "John Grogg",
227
+ "email": "john.grogg@gmail.com",
228
+ "role": "Developer/Prior Owner"
229
+ },
230
+ {
231
+ "name": "Jonathan Goode",
232
+ "role": "Developer/Owner"
233
+ }
234
+ ],
235
+ "description": "ICS Parser",
236
+ "homepage": "https://github.com/u01jmg3/ics-parser",
237
+ "keywords": [
238
+ "iCalendar",
239
+ "ical",
240
+ "ical-parser",
241
+ "ics",
242
+ "ics-parser",
243
+ "ifb"
244
+ ]
245
+ }
246
+ ]
app/vendor/johngrogg/ics-parser/.editorconfig ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://editorconfig.org/
2
+
3
+ root = true
4
+
5
+ [*]
6
+ charset = utf-8
7
+ end_of_line = lf
8
+ indent_size = 4
9
+ indent_style = space
10
+ insert_final_newline = true
11
+ trim_trailing_whitespace = true
app/vendor/johngrogg/ics-parser/.github/CONTRIBUTING.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Contributing
2
+
3
+ ICS Parser is an open source project. It is licensed under the [MIT license](https://opensource.org/licenses/MIT).
4
+ We appreciate pull requests, here are our guidelines:
5
+
6
+ 1. Firstly, check if your issue is present within the latest version (`dev-master`) as the problem may already have been fixed.
7
+ 1. Log a bug in our [issue tracker](https://github.com/u01jmg3/ics-parser/issues) (if there isn't one already).
8
+ - If your patch is going to be large it might be a good idea to get the discussion started early.
9
+ - We are happy to discuss it in an issue beforehand.
10
+ - If you could provide an iCal snippet causing the parser to behave incorrectly it is extremely useful for debugging
11
+ - Please remove all irrelevant events
12
+ 1. Please follow the coding standard already present in the file you are editing _before_ committing
13
+ - Adhere to the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) coding standard
14
+ - Use *4 spaces* instead of tabs for indentation
15
+ - Trim all trailing whitespace and blank lines
16
+ - Use single quotes (`'`) where possible instead of double
17
+ - Abide by the [1TBS](https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS_.28OTBS.29) indentation style
app/vendor/johngrogg/ics-parser/.github/ISSUE_TEMPLATE.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ > :information_source:
2
+ > - Firstly, check you are using the latest version (`dev-master`) as the problem may already have been fixed.
3
+ > - It is **essential** to be provided with the offending iCal causing the parser to behave incorrectly.
4
+ > - Best to upload the iCal file directly to this issue
5
+
6
+ - PHP Version: `5.#.#`
7
+ - PHP date.timezone: `[Country]/[City]`
8
+ - ICS Parser Version: `2.#.#`
9
+ - Windows/Mac/Linux
10
+
11
+ ### Description of the Issue:
12
+
13
+
14
+ ### Steps to Reproduce:
15
+
app/vendor/johngrogg/ics-parser/.github/PULL_REQUEST_TEMPLATE.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ > :information_source:
2
+ > - File a bug on our [issue tracker](https://github.com/u01jmg3/ics-parser/issues) (if there isn't one already).
3
+ > - If your patch is going to be large it might be a good idea to get the discussion started early. We are happy to discuss it in a new issue beforehand.
4
+ > - Please follow the coding standards already adhered to in the file you're editing before committing
5
+ > - This includes the use of *4 spaces* over tabs for indentation
6
+ > - Trimming all trailing whitespace
7
+ > - Using single quotes (`'`) where possible
8
+ > - Using the [1TBS](https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS_.28OTBS.29) indent style
9
+ > - If a function is added or changed, please remember to update the [API documentation in the README](https://github.com/u01jmg3/ics-parser/blob/master/README.md#api)
app/vendor/johngrogg/ics-parser/.github/RELEASE_CHECKLIST.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ # Release Checklist
2
+
3
+ - [ ] Ensure the documentation is up to date
4
+ - [ ] Push the code changes to GitHub (`git push`)
5
+ - [ ] Tag the release (`git tag v1.2.3`)
6
+ - [ ] Push the tag (`git push --tag`)
7
+ - [ ] Check [Packagist](https://packagist.org/packages/johngrogg/ics-parser) is updated
8
+ - [ ] Notify anyone who opened [an issue or PR](https://github.com/u01jmg3/ics-parser/issues?q=is%3Aopen) of the fix
app/vendor/johngrogg/ics-parser/.gitignore ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ###################
2
+ # Compiled Source #
3
+ ###################
4
+ *.com
5
+ *.class
6
+ *.dll
7
+ *.exe
8
+ *.o
9
+ *.so
10
+
11
+ ############
12
+ # Packages #
13
+ ############
14
+ *.7z
15
+ *.dmg
16
+ *.gz
17
+ *.iso
18
+ *.jar
19
+ *.rar
20
+ *.tar
21
+ *.zip
22
+
23
+ ######################
24
+ # Logs and Databases #
25
+ ######################
26
+ *.log
27
+ *.sqlite
28
+
29
+ ######################
30
+ # OS Generated Files #
31
+ ######################
32
+ .DS_Store
33
+ .DS_Store?
34
+ ._*
35
+ .Spotlight-V100
36
+ .Trashes
37
+ ehthumbs.db
38
+ Thumbs.db
39
+ workbench
40
+
41
+ ####################
42
+ # Package Managers #
43
+ ####################
44
+ auth.json
45
+ node_modules
46
+ vendor
47
+
48
+ ##########
49
+ # Custom #
50
+ ##########
51
+ *-report.*
app/vendor/johngrogg/ics-parser/LICENSE ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+ Copyright (c) 2017
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
6
+ modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7
+ Software is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
10
+ Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
15
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
app/vendor/johngrogg/ics-parser/README.md ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PHP ICS Parser
2
+
3
+ [![Latest Stable Release](https://poser.pugx.org/johngrogg/ics-parser/v/stable.png "Latest Stable Release")](https://packagist.org/packages/johngrogg/ics-parser)
4
+ [![Total Downloads](https://poser.pugx.org/johngrogg/ics-parser/downloads.png "Total Downloads")](https://packagist.org/packages/johngrogg/ics-parser)
5
+
6
+ ---
7
+
8
+ ## Installation
9
+
10
+ ### Requirements
11
+ - PHP 5 (≥ 5.3.0)
12
+ - [Valid ICS](https://icalendar.org/validator.html) (`.ics`, `.ical`, `.ifb`) file
13
+ - [IANA](https://www.iana.org/time-zones) or [Unicode CLDR](http://cldr.unicode.org/translation/timezones) Time Zones
14
+
15
+ ### Setup
16
+
17
+ - Install [Composer](https://getcomposer.org/)
18
+ - Add the following dependency to `composer.json`
19
+ - :warning: **Note with Composer the owner is `johngrogg` and not `u01jmg3`**
20
+ - To access the latest stable branch (`v2`) use the following
21
+ - To access new features you can require [`dev-master`](https://getcomposer.org/doc/articles/aliases.md#branch-alias)
22
+
23
+ ```yaml
24
+ {
25
+ "require": {
26
+ "johngrogg/ics-parser": "^2"
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## How to use
32
+
33
+ ### How to instantiate the Parser
34
+
35
+ - Using the example script as a guide, [refer to this code](https://github.com/u01jmg3/ics-parser/blob/master/examples/index.php#L1-L22)
36
+
37
+ #### What will the parser return?
38
+
39
+ - Each key/value pair from the iCal file will be parsed creating an associative array for both the calendar and every event it contains.
40
+ - Also injected will be content under `dtstart_tz` and `dtend_tz` for accessing start and end dates with time zone data applied.
41
+ - Where possible [`DateTime`](https://secure.php.net/manual/en/class.datetime.php) objects are used and returned.
42
+
43
+ ```php
44
+ // Dump the whole calendar
45
+ var_dump($ical->cal);
46
+
47
+ // Dump every event
48
+ var_dump($ical->events());
49
+ ```
50
+
51
+ - Also included are special `{property}_array` arrays which further resolve the contents of a key/value pair.
52
+
53
+ ```php
54
+ // Dump a parsed event's start date
55
+ var_dump($event->dtstart_array);
56
+
57
+ // array (size=4)
58
+ // 0 =>
59
+ // array (size=1)
60
+ // 'TZID' => string 'America/Detroit' (length=15)
61
+ // 1 => string '20160409T090000' (length=15)
62
+ // 2 => int 1460192400
63
+ // 3 => string 'TZID=America/Detroit:20160409T090000' (length=36)
64
+ ```
65
+
66
+ ---
67
+
68
+ ## API
69
+
70
+ ### `ICal` API
71
+
72
+ #### Variables
73
+
74
+ | Name | Description | Configurable | Default Value |
75
+ |--------------------------------|---------------------------------------------------------------------|:------------------------:|-------------------------------------------------------------------------------------------|
76
+ | `$defaultSpan` | The value in years to use for indefinite, recurring events | :ballot_box_with_check: | `2` |
77
+ | `$defaultTimeZone` | Enables customisation of the default time zone | :ballot_box_with_check: | [System default](https://secure.php.net/manual/en/function.date-default-timezone-get.php) |
78
+ | `$defaultWeekStart` | The two letter representation of the first day of the week | :ballot_box_with_check: | `MO` |
79
+ | `$disableCharacterReplacement` | Toggles whether to disable all character replacement | :ballot_box_with_check: | `false` |
80
+ | `$skipRecurrence` | Toggles whether to skip the parsing of recurrence rules | :ballot_box_with_check: | `false` |
81
+ | `$useTimeZoneWithRRules` | Toggles whether to use time zone info when parsing recurrence rules | :ballot_box_with_check: | `false` |
82
+ | `$alarmCount` | Tracks the number of alarms in the current iCal feed | :heavy_multiplication_x: | N/A |
83
+ | `$cal` | The parsed calendar | :heavy_multiplication_x: | N/A |
84
+ | `$eventCount` | Tracks the number of events in the current iCal feed | :heavy_multiplication_x: | N/A |
85
+ | `$freeBusyCount` | Tracks the free/busy count in the current iCal feed | :heavy_multiplication_x: | N/A |
86
+ | `$todoCount` | Tracks the number of todos in the current iCal feed | :heavy_multiplication_x: | N/A |
87
+
88
+ #### Methods
89
+
90
+ | Method | Parameter(s) | Visibility | Description |
91
+ |---------------------------------------|------------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------------|
92
+ | `__construct` | `$files = false`, `$options = array()` | `public` | Creates the ICal object |
93
+ | `initFile` | `$file` | `protected` | Initialises lines from a file |
94
+ | `initLines` | `$lines` | `protected` | Initialises the parser using an array containing each line of iCal content |
95
+ | `initString` | `$string` | `protected` | Initialises lines from a string |
96
+ | `initUrl` | `$url` | `protected` | Initialises lines from a URL |
97
+ | `addCalendarComponentWithKeyAndValue` | `$component`, `$keyword`, `$value` | `protected` | Add one key and value pair to the `$this->cal` array |
98
+ | `calendarDescription` | - | `public` | Returns the calendar description |
99
+ | `calendarName` | - | `public` | Returns the calendar name |
100
+ | `calendarTimeZone` | `$ignoreUtc` | `public` | Returns the calendar time zone |
101
+ | `cleanData` | `$data` | `protected` | Replaces curly quotes and other special characters with their standard equivalents |
102
+ | `convertDayOrdinalToPositive` | `$dayNumber`, `$weekday`, `$timestamp` | `protected` | Converts a negative day ordinal to its equivalent positive form |
103
+ | `eventsFromInterval` | `$interval` | `public` | Returns a sorted array of events following a given string, or `false` if no events exist in the range |
104
+ | `eventsFromRange` | `$rangeStart = false`, `$rangeEnd = false` | `public` | Returns a sorted array of events in a given range, or an empty array if no events exist in the range |
105
+ | `events` | - | `public` | Returns an array of Events |
106
+ | `fileOrUrl` | `$filename` | `protected` | Reads an entire file or URL into an array |
107
+ | `freeBusyEvents` | - | `public` | Returns an array of arrays with all free/busy events |
108
+ | `hasEvents` | - | `public` | Returns a boolean value whether the current calendar has events or not |
109
+ | `iCalDateToDateTime` | `$icalDate`, `$forceTimeZone = false`, `$forceUtc = false` | `public` | Returns a `DateTime` object from an iCal date time format |
110
+ | `iCalDateToUnixTimestamp` | `$icalDate`, `$forceTimeZone = false`, `$forceUtc = false` | `public` | Returns a Unix timestamp from an iCal date time format |
111
+ | `iCalDateWithTimeZone` | `$event`, `$key`, `$format = DATE_TIME_FORMAT` | `public` | Returns a date adapted to the calendar time zone depending on the event `TZID` |
112
+ | `isExdateMatch` | `$exdate`, `$anEvent`, `$recurringOffset` | `protected` | Checks if an excluded date matches a given date by reconciling time zones |
113
+ | `isFileOrUrl` | `$filename` | `protected` | Checks if a filename exists as a file or URL |
114
+ | `isValidDate` | `$value` | `public` | Checks if a date string is a valid date |
115
+ | `isValidTimeZoneId` | `$timeZone` | `protected` | Checks if a time zone is valid (IANA or CLDR) |
116
+ | `isValidIanaTimeZoneId` | `$timeZone` | `protected` | Checks if a time zone is a valid IANA time zone |
117
+ | `isValidCldrTimeZoneId` | `$timeZone`, `doConversion = false` | `protected` | Checks if a time zone is a valid CLDR time zone |
118
+ | `keyValueFromString` | `$text` | `protected` | Gets the key value pair from an iCal string |
119
+ | `mb_chr` | `$code` | `protected` | Provides a polyfill for PHP 7.2's `mb_chr()`, which is a multibyte safe version of `chr()` |
120
+ | `mb_str_replace` | `$search`, `$replace`, `$subject`, `$count = 0` | `protected` | Replaces all occurrences of a search string with a given replacement string |
121
+ | `numberOfDays` | `$days`, `$start`, `$end` | `protected` | Gets the number of days between a start and end date |
122
+ | `parseDuration` | `$date`, `$duration`, `$format = 'U'` | `protected` | Parses a duration and applies it to a date |
123
+ | `parseExdates` | `$event` | `public` | Parses a list of excluded dates to be applied to an Event |
124
+ | `processDateConversions` | - | `protected` | Processes date conversions using the time zone |
125
+ | `processEventIcalDateTime` | `$event`, `$index = 3` | `protected` | Extends the `{DTSTART\|DTEND\|RECURRENCE-ID}_array` array to include an iCal date time for each event |
126
+ | `processEvents` | - | `protected` | Performs admin tasks on all events as read from the iCal file |
127
+ | `processRecurrences` | - | `protected` | Processes recurrence rules |
128
+ | `removeUnprintableChars` | `$data` | `protected` | Removes unprintable ASCII and UTF-8 characters |
129
+ | `sortEventsWithOrder` | `$events`, `$sortOrder = SORT_ASC` | `public` | Sorts events based on a given sort order |
130
+ | `trimToRecurrenceCount` | `$rrules`, `$recurrenceEvents` | `protected` | Ensures the recurrence count is enforced against generated recurrence events |
131
+ | `unfold` | `$lines` | `protected` | Unfolds an iCal file in preparation for parsing |
132
+
133
+ #### Constants
134
+
135
+ | Name | Description |
136
+ |---------------------------|-----------------------------------------------|
137
+ | `DATE_TIME_FORMAT_PRETTY` | Default pretty date time format to use |
138
+ | `DATE_TIME_FORMAT` | Default date time format to use |
139
+ | `ICAL_DATE_TIME_TEMPLATE` | String template to generate an iCal date time |
140
+ | `RECURRENCE_EVENT` | Used to isolate generated recurrence events |
141
+ | `SECONDS_IN_A_WEEK` | The number of seconds in a week |
142
+ | `TIME_FORMAT` | Default time format to use |
143
+ | `TIME_ZONE_UTC` | UTC time zone string |
144
+ | `UNIX_FORMAT` | Unix timestamp date format |
145
+ | `UNIX_MIN_YEAR` | The year Unix time began |
146
+
147
+ ---
148
+
149
+ ### `Event` API (extends `ICal` API)
150
+
151
+ #### Methods
152
+
153
+ | Method | Parameter(s) | Visibility | Description |
154
+ |---------------|---------------------------------------------|-------------|---------------------------------------------------------------------|
155
+ | `__construct` | `$data = array()` | `public` | Creates the Event object |
156
+ | `prepareData` | `$value` | `protected` | Prepares the data for output |
157
+ | `printData` | `$html = HTML_TEMPLATE` | `public` | Returns Event data excluding anything blank within an HTML template |
158
+ | `snakeCase` | `$input`, `$glue = '_'`, `$separator = '-'` | `protected` | Converts the given input to snake_case |
159
+
160
+ #### Constants
161
+
162
+ | Name | Description |
163
+ |-----------------|-----------------------------------------------------|
164
+ | `HTML_TEMPLATE` | String template to use when pretty printing content |
165
+
166
+ ---
167
+
168
+ ## Credits
169
+ - [Jonathan Goode](https://github.com/u01jmg3) (programming, bug fixing, enhancement, coding standard)
170
+ - [John Grogg](john.grogg@gmail.com) (programming, addition of event recurrence handling)
171
+
172
+ ---
173
+
174
+ ## Tools for Testing
175
+
176
+ - [iCal Validator](https://icalendar.org/validator.html)
177
+ - [Recurrence Rule Tester](https://jakubroztocil.github.io/rrule/)
178
+ - [Unix Timestamp Converter](https://www.unixtimestamp.com)
app/vendor/johngrogg/ics-parser/composer.json ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "johngrogg/ics-parser",
3
+ "description": "ICS Parser",
4
+ "homepage": "https://github.com/u01jmg3/ics-parser",
5
+ "keywords": [
6
+ "icalendar",
7
+ "ics",
8
+ "ics-parser",
9
+ "ical",
10
+ "ical-parser",
11
+ "ifb"
12
+ ],
13
+ "type": "library",
14
+ "license": "MIT",
15
+ "authors": [
16
+ {
17
+ "name": "Jonathan Goode",
18
+ "role": "Developer/Owner"
19
+ },
20
+ {
21
+ "name": "John Grogg",
22
+ "email": "john.grogg@gmail.com",
23
+ "role": "Developer/Prior Owner"
24
+ },
25
+ {
26
+ "name": "Martin Thoma",
27
+ "email": "info@martin-thoma.de",
28
+ "role": "Original Developer"
29
+ }
30
+ ],
31
+ "require": {
32
+ "php": ">=5.3.0",
33
+ "ext-mbstring": "*",
34
+ "nesbot/carbon": "~1.28"
35
+ },
36
+ "require-dev": {
37
+ "squizlabs/php_codesniffer": "~2.9.1"
38
+ },
39
+ "autoload": {
40
+ "psr-0": {
41
+ "ICal": "src/"
42
+ }
43
+ },
44
+ "config": {
45
+ "platform": {
46
+ "php": "5.3.29"
47
+ }
48
+ }
49
+ }
app/vendor/johngrogg/ics-parser/composer.lock ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "content-hash": "bd0091adbd9e5072ec5c42d44b6643fe",
8
+ "packages": [
9
+ {
10
+ "name": "nesbot/carbon",
11
+ "version": "1.28.0",
12
+ "source": {
13
+ "type": "git",
14
+ "url": "https://github.com/briannesbitt/Carbon.git",
15
+ "reference": "00149d95fc91ef10f19d3a66889bc3bb7500fa7b"
16
+ },
17
+ "dist": {
18
+ "type": "zip",
19
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/00149d95fc91ef10f19d3a66889bc3bb7500fa7b",
20
+ "reference": "00149d95fc91ef10f19d3a66889bc3bb7500fa7b",
21
+ "shasum": ""
22
+ },
23
+ "require": {
24
+ "php": ">=5.3.9",
25
+ "symfony/translation": "~2.6 || ~3.0 || ~4.0"
26
+ },
27
+ "require-dev": {
28
+ "friendsofphp/php-cs-fixer": "~2",
29
+ "phpunit/phpunit": "^4.8.35 || ^5.7"
30
+ },
31
+ "type": "library",
32
+ "autoload": {
33
+ "psr-4": {
34
+ "": "src/"
35
+ }
36
+ },
37
+ "notification-url": "https://packagist.org/downloads/",
38
+ "license": [
39
+ "MIT"
40
+ ],
41
+ "authors": [
42
+ {
43
+ "name": "Brian Nesbitt",
44
+ "email": "brian@nesbot.com",
45
+ "homepage": "http://nesbot.com"
46
+ }
47
+ ],
48
+ "description": "A simple API extension for DateTime.",
49
+ "homepage": "http://carbon.nesbot.com",
50
+ "keywords": [
51
+ "date",
52
+ "datetime",
53
+ "time"
54
+ ],
55
+ "time": "2018-05-18T15:26:18+00:00"
56
+ },
57
+ {
58
+ "name": "symfony/polyfill-mbstring",
59
+ "version": "v1.8.0",
60
+ "source": {
61
+ "type": "git",
62
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
63
+ "reference": "3296adf6a6454a050679cde90f95350ad604b171"
64
+ },
65
+ "dist": {
66
+ "type": "zip",
67
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
68
+ "reference": "3296adf6a6454a050679cde90f95350ad604b171",
69
+ "shasum": ""
70
+ },
71
+ "require": {
72
+ "php": ">=5.3.3"
73
+ },
74
+ "suggest": {
75
+ "ext-mbstring": "For best performance"
76
+ },
77
+ "type": "library",
78
+ "extra": {
79
+ "branch-alias": {
80
+ "dev-master": "1.8-dev"
81
+ }
82
+ },
83
+ "autoload": {
84
+ "psr-4": {
85
+ "Symfony\\Polyfill\\Mbstring\\": ""
86
+ },
87
+ "files": [
88
+ "bootstrap.php"
89
+ ]
90
+ },
91
+ "notification-url": "https://packagist.org/downloads/",
92
+ "license": [
93
+ "MIT"
94
+ ],
95
+ "authors": [
96
+ {
97
+ "name": "Nicolas Grekas",
98
+ "email": "p@tchwork.com"
99
+ },
100
+ {
101
+ "name": "Symfony Community",
102
+ "homepage": "https://symfony.com/contributors"
103
+ }
104
+ ],
105
+ "description": "Symfony polyfill for the Mbstring extension",
106
+ "homepage": "https://symfony.com",
107
+ "keywords": [
108
+ "compatibility",
109
+ "mbstring",
110
+ "polyfill",
111
+ "portable",
112
+ "shim"
113
+ ],
114
+ "time": "2018-04-26T10:06:28+00:00"
115
+ },
116
+ {
117
+ "name": "symfony/translation",
118
+ "version": "v2.8.40",
119
+ "source": {
120
+ "type": "git",
121
+ "url": "https://github.com/symfony/translation.git",
122
+ "reference": "c6a27966a92fa361bf2c3a938abc6dee91f7ad67"
123
+ },
124
+ "dist": {
125
+ "type": "zip",
126
+ "url": "https://api.github.com/repos/symfony/translation/zipball/c6a27966a92fa361bf2c3a938abc6dee91f7ad67",
127
+ "reference": "c6a27966a92fa361bf2c3a938abc6dee91f7ad67",
128
+ "shasum": ""
129
+ },
130
+ "require": {
131
+ "php": ">=5.3.9",
132
+ "symfony/polyfill-mbstring": "~1.0"
133
+ },
134
+ "conflict": {
135
+ "symfony/config": "<2.7"
136
+ },
137
+ "require-dev": {
138
+ "psr/log": "~1.0",
139
+ "symfony/config": "~2.8",
140
+ "symfony/intl": "~2.7.25|^2.8.18|~3.2.5",
141
+ "symfony/yaml": "~2.2|~3.0.0"
142
+ },
143
+ "suggest": {
144
+ "psr/log-implementation": "To use logging capability in translator",
145
+ "symfony/config": "",
146
+ "symfony/yaml": ""
147
+ },
148
+ "type": "library",
149
+ "extra": {
150
+ "branch-alias": {
151
+ "dev-master": "2.8-dev"
152
+ }
153
+ },
154
+ "autoload": {
155
+ "psr-4": {
156
+ "Symfony\\Component\\Translation\\": ""
157
+ },
158
+ "exclude-from-classmap": [
159
+ "/Tests/"
160
+ ]
161
+ },
162
+ "notification-url": "https://packagist.org/downloads/",
163
+ "license": [
164
+ "MIT"
165
+ ],
166
+ "authors": [
167
+ {
168
+ "name": "Fabien Potencier",
169
+ "email": "fabien@symfony.com"
170
+ },
171
+ {
172
+ "name": "Symfony Community",
173
+ "homepage": "https://symfony.com/contributors"
174
+ }
175
+ ],
176
+ "description": "Symfony Translation Component",
177
+ "homepage": "https://symfony.com",
178
+ "time": "2018-05-21T09:59:10+00:00"
179
+ }
180
+ ],
181
+ "packages-dev": [
182
+ {
183
+ "name": "squizlabs/php_codesniffer",
184
+ "version": "2.9.1",
185
+ "source": {
186
+ "type": "git",
187
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
188
+ "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62"
189
+ },
190
+ "dist": {
191
+ "type": "zip",
192
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62",
193
+ "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62",
194
+ "shasum": ""
195
+ },
196
+ "require": {
197
+ "ext-simplexml": "*",
198
+ "ext-tokenizer": "*",
199
+ "ext-xmlwriter": "*",
200
+ "php": ">=5.1.2"
201
+ },
202
+ "require-dev": {
203
+ "phpunit/phpunit": "~4.0"
204
+ },
205
+ "bin": [
206
+ "scripts/phpcs",
207
+ "scripts/phpcbf"
208
+ ],
209
+ "type": "library",
210
+ "extra": {
211
+ "branch-alias": {
212
+ "dev-master": "2.x-dev"
213
+ }
214
+ },
215
+ "autoload": {
216
+ "classmap": [
217
+ "CodeSniffer.php",
218
+ "CodeSniffer/CLI.php",
219
+ "CodeSniffer/Exception.php",
220
+ "CodeSniffer/File.php",
221
+ "CodeSniffer/Fixer.php",
222
+ "CodeSniffer/Report.php",
223
+ "CodeSniffer/Reporting.php",
224
+ "CodeSniffer/Sniff.php",
225
+ "CodeSniffer/Tokens.php",
226
+ "CodeSniffer/Reports/",
227
+ "CodeSniffer/Tokenizers/",
228
+ "CodeSniffer/DocGenerators/",
229
+ "CodeSniffer/Standards/AbstractPatternSniff.php",
230
+ "CodeSniffer/Standards/AbstractScopeSniff.php",
231
+ "CodeSniffer/Standards/AbstractVariableSniff.php",
232
+ "CodeSniffer/Standards/IncorrectPatternException.php",
233
+ "CodeSniffer/Standards/Generic/Sniffs/",
234
+ "CodeSniffer/Standards/MySource/Sniffs/",
235
+ "CodeSniffer/Standards/PEAR/Sniffs/",
236
+ "CodeSniffer/Standards/PSR1/Sniffs/",
237
+ "CodeSniffer/Standards/PSR2/Sniffs/",
238
+ "CodeSniffer/Standards/Squiz/Sniffs/",
239
+ "CodeSniffer/Standards/Zend/Sniffs/"
240
+ ]
241
+ },
242
+ "notification-url": "https://packagist.org/downloads/",
243
+ "license": [
244
+ "BSD-3-Clause"
245
+ ],
246
+ "authors": [
247
+ {
248
+ "name": "Greg Sherwood",
249
+ "role": "lead"
250
+ }
251
+ ],
252
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
253
+ "homepage": "http://www.squizlabs.com/php-codesniffer",
254
+ "keywords": [
255
+ "phpcs",
256
+ "standards"
257
+ ],
258
+ "time": "2017-05-22T02:43:20+00:00"
259
+ }
260
+ ],
261
+ "aliases": [],
262
+ "minimum-stability": "stable",
263
+ "stability-flags": [],
264
+ "prefer-stable": false,
265
+ "prefer-lowest": false,
266
+ "platform": {
267
+ "php": ">=5.3.0",
268
+ "ext-mbstring": "*"
269
+ },
270
+ "platform-dev": [],
271
+ "platform-overrides": {
272
+ "php": "5.3.29"
273
+ }
274
+ }
app/vendor/johngrogg/ics-parser/examples/ICal.ics ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ BEGIN:VCALENDAR
2
+ PRODID:-//Google Inc//Google Calendar 70.9054//EN
3
+ VERSION:2.0
4
+ CALSCALE:GREGORIAN
5
+ METHOD:PUBLISH
6
+ X-WR-CALNAME:Testkalender
7
+ X-WR-TIMEZONE:UTC
8
+ X-WR-CALDESC:Nur zum testen vom Google Kalender
9
+ BEGIN:VFREEBUSY
10
+ UID:f06ff6b3564b2f696bf42d393f8dea59
11
+ ORGANIZER:MAILTO:jane_smith@host1.com
12
+ DTSTAMP:20170316T204607Z
13
+ DTSTART:20170213T204607Z
14
+ DTEND:20180517T204607Z
15
+ URL:https://www.host.com/calendar/busytime/jsmith.ifb
16
+ FREEBUSY;FBTYPE=BUSY:20170623T070000Z/20170223T110000Z
17
+ FREEBUSY;FBTYPE=BUSY:20170624T131500Z/20170316T151500Z
18
+ FREEBUSY;FBTYPE=BUSY:20170715T131500Z/20170416T150000Z
19
+ FREEBUSY;FBTYPE=BUSY:20170716T131500Z/20170516T100500Z
20
+ END:VFREEBUSY
21
+ BEGIN:VEVENT
22
+ DTSTART:20171032T000000
23
+ DTEND:20171101T2300
24
+ DESCRIPTION:Invalid date - parser will skip the event
25
+ SUMMARY:Invalid date - parser will skip the event
26
+ DTSTAMP:20170406T063924
27
+ LOCATION:
28
+ UID:f81b0b41a2e138ae0903daee0a966e1e
29
+ SEQUENCE:0
30
+ END:VEVENT
31
+ BEGIN:VEVENT
32
+ DTSTART;VALUE=DATE;TZID=America/Los_Angeles:19410512
33
+ DTEND;VALUE=DATE;TZID=America/Los_Angeles:19410512
34
+ DTSTAMP;TZID=America/Los_Angeles:19410512T195741Z
35
+ UID:dh3fki5du0opa7cs5n5s87ca02@google.com
36
+ CREATED:20380101T141901Z
37
+ DESCRIPTION;LANGUAGE=en-gb:
38
+ LAST-MODIFIED:20380101T141901Z
39
+ LOCATION:
40
+ SEQUENCE:0
41
+ STATUS:CONFIRMED
42
+ SUMMARY;LANGUAGE=en-gb:Before 1970-Test: Konrad Zuse invents the Z3, the "first
43
+ digital Computer"
44
+ TRANSP:TRANSPARENT
45
+ END:VEVENT
46
+ BEGIN:VEVENT
47
+ DTSTART;VALUE=DATE:20380201
48
+ DTEND;VALUE=DATE:20380202
49
+ DTSTAMP;TZID="GMT Standard Time":20380101T195741Z
50
+ UID:dh3fki5du0opa7cs5n5s87ca01@google.com
51
+ CREATED:20380101T141901Z
52
+ DESCRIPTION;LANGUAGE=en-gb:
53
+ LAST-MODIFIED:20380101T141901Z
54
+ LOCATION:
55
+ SEQUENCE:0
56
+ STATUS:CONFIRMED
57
+ SUMMARY;LANGUAGE=en-gb:Year 2038 problem test
58
+ TRANSP:TRANSPARENT
59
+ END:VEVENT
60
+ BEGIN:VEVENT
61
+ DTSTART:20160105T090000Z
62
+ DTEND:20160107T173000Z
63
+ DTSTAMP;TZID="Greenwich Mean Time:Dublin; Edinburgh; Lisbon; London":20110121T195741Z
64
+ UID:15lc1nvupht8dtfiptenljoiv4@google.com
65
+ CREATED:20110121T195616Z
66
+ DESCRIPTION;LANGUAGE=en-gb:This is a short description\nwith a new line. Some "special" 's
67
+ igns' may be interesting\, too.
68
+ LAST-MODIFIED:20150409T150000Z
69
+ LOCATION:Kansas
70
+ SEQUENCE:2
71
+ STATUS:CONFIRMED
72
+ SUMMARY;LANGUAGE=en-gb:My Holidays
73
+ TRANSP:TRANSPARENT
74
+ ORGANIZER;CN="My Name":mailto:my.name@mydomain.com
75
+ END:VEVENT
76
+ BEGIN:VEVENT
77
+ ATTENDEE;CN="Page, Larry <l.page@google.com> (l.page@google.com)";ROLE=REQ-PARTICIPANT;RSVP=FALSE:mailto:l.page@google.com
78
+ ATTENDEE;CN="Brin, Sergey <s.brin@google.com> (s.brin@google.com)";ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:s.brin@google.com
79
+ DTSTART;VALUE=DATE:20160112
80
+ DTEND;VALUE=DATE:20160116
81
+ DTSTAMP;TZID="GMT Standard Time":20110121T195741Z
82
+ UID:1koigufm110c5hnq6ln57murd4@google.com
83
+ CREATED:20110119T142901Z
84
+ DESCRIPTION;LANGUAGE=en-gb:Project xyz Review Meeting Minutes\n
85
+ Agenda\n1. Review of project version 1.0 requirements.\n2.
86
+ Definition
87
+ of project processes.\n3. Review of project schedule.\n
88
+ Participants: John Smith, Jane Doe, Jim Dandy\n-It was
89
+ decided that the requirements need to be signed off by
90
+ product marketing.\n-Project processes were accepted.\n
91
+ -Project schedule needs to account for scheduled holidays
92
+ and employee vacation time. Check with HR for specific
93
+ dates.\n-New schedule will be distributed by Friday.\n-
94
+ Next weeks meeting is cancelled. No meeting until 3/23.
95
+ LAST-MODIFIED:20150409T150000Z
96
+ LOCATION:
97
+ SEQUENCE:2
98
+ STATUS:CONFIRMED
99
+ SUMMARY;LANGUAGE=en-gb:Test 2
100
+ TRANSP:TRANSPARENT
101
+ END:VEVENT
102
+ BEGIN:VEVENT
103
+ DTSTART;VALUE=DATE:20160119
104
+ DTEND;VALUE=DATE:20160120
105
+ DTSTAMP;TZID="GMT Standard Time":20110121T195741Z
106
+ UID:rq8jng4jgq0m1lvpj8486fttu0@google.com
107
+ CREATED:20110119T141904Z
108
+ DESCRIPTION;LANGUAGE=en-gb:
109
+ LAST-MODIFIED:20150409T150000Z
110
+ LOCATION:
111
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
112
+ SEQUENCE:0
113
+ STATUS:CONFIRMED
114
+ SUMMARY;LANGUAGE=en-gb:DST Change
115
+ TRANSP:TRANSPARENT
116
+ END:VEVENT
117
+ BEGIN:VEVENT
118
+ DTSTART;VALUE=DATE:20160119
119
+ DTEND;VALUE=DATE:20160120
120
+ DTSTAMP;TZID="GMT Standard Time":20110121T195741Z
121
+ UID:dh3fki5du0opa7cs5n5s87ca00@google.com
122
+ CREATED:20110119T141901Z
123
+ DESCRIPTION;LANGUAGE=en-gb:
124
+ LAST-MODIFIED:20150409T150000Z
125
+ LOCATION:
126
+ RRULE:FREQ=WEEKLY;COUNT=5;INTERVAL=2;BYDAY=TU
127
+ SEQUENCE:0
128
+ STATUS:CONFIRMED
129
+ SUMMARY;LANGUAGE=en-gb:Test 1
130
+ TRANSP:TRANSPARENT
131
+ END:VEVENT
132
+ BEGIN:VEVENT
133
+ SUMMARY:Duration Test
134
+ DTSTART:20160425T150000Z
135
+ DTSTAMP:20160424T150000Z
136
+ DURATION:PT1H15M5S
137
+ RRULE:FREQ=DAILY;COUNT=2
138
+ UID:calendar-62-e7c39bf02382917349672271dd781c89
139
+ END:VEVENT
140
+ BEGIN:VEVENT
141
+ SUMMARY:BYMONTHDAY Test
142
+ DTSTART:20160922T130000Z
143
+ DTEND:20160922T150000Z
144
+ DTSTAMP:20160921T130000Z
145
+ RRULE:FREQ=MONTHLY;UNTIL=20170923T000000Z;INTERVAL=1;BYMONTHDAY=23
146
+ UID:33844fe8df15fbfc13c97fc41c0c4b00392c6870@google.com
147
+ END:VEVENT
148
+ BEGIN:VEVENT
149
+ DTSTART;TZID=Europe/Paris:20160921T080000
150
+ DTEND;TZID=Europe/Paris:20160921T090000
151
+ RRULE:FREQ=WEEKLY;BYDAY=2WE
152
+ DTSTAMP:20161117T165045Z
153
+ UID:884bc8350185031337d9ec49d2e7e101dd5ae5fb@google.com
154
+ CREATED:20160920T133918Z
155
+ DESCRIPTION:
156
+ LAST-MODIFIED:20160920T133923Z
157
+ LOCATION:
158
+ SEQUENCE:1
159
+ STATUS:CONFIRMED
160
+ SUMMARY:Paris Timezone Test
161
+ TRANSP:OPAQUE
162
+ END:VEVENT
163
+ BEGIN:VEVENT
164
+ DTSTART:20160215T080000Z
165
+ DTEND:20160515T090000Z
166
+ DTSTAMP:20161121T113027Z
167
+ CREATED:20161121T113027Z
168
+ UID:65323c541a30dd1f180e2bbfa2724995
169
+ DESCRIPTION:
170
+ LAST-MODIFIED:20161121T113027Z
171
+ LOCATION:
172
+ SEQUENCE:1
173
+ STATUS:CONFIRMED
174
+ SUMMARY:Long event covering the range from example with special chars:
175
+ ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÕÖÒÓÔØÙÚÛÜÝÞß
176
+ àáâãäåæçèéêėëìíîïðñòóôõöøùúûüūýþÿž
177
+ ‘ ’ ‚ ‛ “ ” „ ‟ – — …
178
+ TRANSP:OPAQUE
179
+ END:VEVENT
180
+ BEGIN:VEVENT
181
+ CLASS:PUBLIC
182
+ CREATED:20160706T161104Z
183
+ DTEND;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160409T110000
184
+ DTSTAMP:20160706T150005Z
185
+ DTSTART;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160409T090000
186
+ EXDATE;TZID="(UTC-05:00) Eastern Time (US & Canada)":
187
+ 20160528T090000,
188
+ 20160625T090000
189
+ LAST-MODIFIED:20160707T182011Z
190
+ EXDATE;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160709T090000
191
+ EXDATE;TZID="(UTC-05:00) Eastern Time (US & Canada)":20160723T090000
192
+ LOCATION:Sanctuary
193
+ PRIORITY:5
194
+ RRULE:FREQ=WEEKLY;COUNT=15;BYDAY=SA
195
+ SEQUENCE:0
196
+ SUMMARY:Microsoft Unicode CLDR EXDATE Test
197
+ TRANSP:OPAQUE
198
+ UID:040000008200E00074C5B7101A82E0080000000020F6512D0B48CF0100000000000000001000000058BFB8CBB85D504CB99FBA637BCFD6BF
199
+ X-MICROSOFT-CDO-BUSYSTATUS:BUSY
200
+ X-MICROSOFT-CDO-IMPORTANCE:1
201
+ X-MICROSOFT-DISALLOW-COUNTER:FALSE
202
+ END:VEVENT
203
+ BEGIN:VEVENT
204
+ DTSTART;VALUE=DATE:20170118
205
+ DTEND;VALUE=DATE:20170118
206
+ DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
207
+ RRULE:FREQ=MONTHLY;BYSETPOS=3;BYDAY=WE;COUNT=5
208
+ UID:4dnsuc3nknin15kv25cn7ridss@google.com
209
+ CREATED:20170119T142059Z
210
+ DESCRIPTION;LANGUAGE=en-gb:BYDAY Test 1
211
+ LAST-MODIFIED:20170409T150000Z
212
+ SEQUENCE:0
213
+ STATUS:CONFIRMED
214
+ SUMMARY;LANGUAGE=en-gb:BYDAY Test 1
215
+ TRANSP:TRANSPARENT
216
+ END:VEVENT
217
+ BEGIN:VEVENT
218
+ DTSTART;VALUE=DATE:20170301
219
+ DTEND;VALUE=DATE:20170301
220
+ DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
221
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=WE
222
+ UID:h6f7sdjbpt47v3dkral8lnsgcc@google.com
223
+ CREATED:20170119T142040Z
224
+ DESCRIPTION;LANGUAGE=en-gb:BYDAY Test 2
225
+ LAST-MODIFIED:20170409T150000Z
226
+ SEQUENCE:0
227
+ STATUS:CONFIRMED
228
+ SUMMARY;LANGUAGE=en-gb:BYDAY Test 2
229
+ TRANSP:TRANSPARENT
230
+ END:VEVENT
231
+ BEGIN:VEVENT
232
+ DTSTART;VALUE=DATE:20170111
233
+ DTEND;VALUE=DATE:20170111
234
+ DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
235
+ RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=5;BYMONTH=1,2,3
236
+ UID:f50e8b89a4a3b0070e0b687d03@google.com
237
+ CREATED:20170119T142040Z
238
+ DESCRIPTION;LANGUAGE=en-gb:BYMONTH Multiple Test 1
239
+ LAST-MODIFIED:20170409T150000Z
240
+ SEQUENCE:0
241
+ STATUS:CONFIRMED
242
+ SUMMARY;LANGUAGE=en-gb:BYMONTH Multiple Test 1
243
+ TRANSP:TRANSPARENT
244
+ END:VEVENT
245
+ BEGIN:VEVENT
246
+ DTSTART;VALUE=DATE:20170405
247
+ DTEND;VALUE=DATE:20170405
248
+ DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
249
+ RRULE:FREQ=YEARLY;BYMONTH=4,5,6;BYDAY=WE;COUNT=5
250
+ UID:675f06aa795665ae50904ebf0e@google.com
251
+ CREATED:20170119T142040Z
252
+ DESCRIPTION;LANGUAGE=en-gb:BYMONTH Multiple Test 2
253
+ LAST-MODIFIED:20170409T150000Z
254
+ SEQUENCE:0
255
+ STATUS:CONFIRMED
256
+ SUMMARY;LANGUAGE=en-gb:BYMONTH Multiple Test 2
257
+ TRANSP:TRANSPARENT
258
+ END:VEVENT
259
+ BEGIN:VEVENT
260
+ BEGIN:VALARM
261
+ TRIGGER;VALUE=DURATION:-PT30M
262
+ ACTION:DISPLAY
263
+ DESCRIPTION:Buzz buzz
264
+ END:VALARM
265
+ DTSTART;VALUE=DATE;TZID=Germany/Berlin:20170123
266
+ DTEND;VALUE=DATE;TZID=Germany/Berlin:20170123
267
+ DTSTAMP;TZID="GMT Standard Time":20170121T195741Z
268
+ RRULE:FREQ=MONTHLY;BYDAY=-2MO;COUNT=5
269
+ EXDATE;VALUE=DATE:20171020
270
+ UID:d287b7ec808fcf084983f10837@google.com
271
+ CREATED:20170119T142040Z
272
+ DESCRIPTION;LANGUAGE=en-gb:Negative BYDAY
273
+ LAST-MODIFIED:20170409T150000Z
274
+ SEQUENCE:0
275
+ STATUS:CONFIRMED
276
+ SUMMARY;LANGUAGE=en-gb:Negative BYDAY
277
+ TRANSP:TRANSPARENT
278
+ END:VEVENT
279
+ BEGIN:VEVENT
280
+ DTSTART;TZID=Australia/Sydney:20170813T190000
281
+ DTEND;TZID=Australia/Sydney:20170813T213000
282
+ RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=2SU;COUNT=2
283
+ DTSTAMP:20170809T114431Z
284
+ UID:testuid@google.com
285
+ CREATED:20170802T135539Z
286
+ DESCRIPTION:
287
+ LAST-MODIFIED:20170802T135935Z
288
+ LOCATION:
289
+ SEQUENCE:1
290
+ STATUS:CONFIRMED
291
+ SUMMARY:Parent Recurrence Event
292
+ TRANSP:OPAQUE
293
+ END:VEVENT
294
+ BEGIN:VEVENT
295
+ DTSTART;TZID=Australia/Sydney:20170813T190000
296
+ DTEND;TZID=Australia/Sydney:20170813T213000
297
+ DTSTAMP:20170809T114431Z
298
+ UID:testuid@google.com
299
+ RECURRENCE-ID;TZID=Australia/Sydney:20170813T190000
300
+ CREATED:20170802T135539Z
301
+ DESCRIPTION:
302
+ LAST-MODIFIED:20170809T105604Z
303
+ LOCATION:Melbourne VIC\, Australia
304
+ SEQUENCE:1
305
+ STATUS:CONFIRMED
306
+ SUMMARY:Override Parent Recurrence Event
307
+ TRANSP:OPAQUE
308
+ END:VEVENT
309
+ END:VCALENDAR
app/vendor/johngrogg/ics-parser/examples/index.php ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // phpcs:disable Generic.Arrays.DisallowLongArraySyntax.Found
3
+
4
+ require_once '../vendor/autoload.php';
5
+
6
+ use ICal\ICal;
7
+
8
+ try {
9
+ $ical = new ICal('ICal.ics', array(
10
+ 'defaultSpan' => 2, // Default value
11
+ 'defaultTimeZone' => 'UTC',
12
+ 'defaultWeekStart' => 'MO', // Default value
13
+ 'disableCharacterReplacement' => false, // Default value
14
+ 'skipRecurrence' => false, // Default value
15
+ 'useTimeZoneWithRRules' => false, // Default value
16
+ ));
17
+ // $ical->initFile('ICal.ics');
18
+ // $ical->initUrl('https://raw.githubusercontent.com/u01jmg3/ics-parser/master/examples/ICal.ics');
19
+ } catch (\Exception $e) {
20
+ die($e);
21
+ }
22
+
23
+ $forceTimeZone = false;
24
+ ?>
25
+ <!DOCTYPE html>
26
+ <html lang="en">
27
+ <head>
28
+ <meta charset="UTF-8">
29
+ <!-- Latest compiled and minified CSS -->
30
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
31
+ <title>PHP ICS Parser example</title>
32
+ <style>body { background-color: #eee } .caption { overflow-x: auto }</style>
33
+ </head>
34
+ <body>
35
+ <div class="container-fluid">
36
+ <h3>PHP ICS Parser example</h3>
37
+ <ul class="list-group">
38
+ <li class="list-group-item">
39
+ <span class="badge"><?php echo $ical->eventCount ?></span>
40
+ The number of events
41
+ </li>
42
+ <li class="list-group-item">
43
+ <span class="badge"><?php echo $ical->freeBusyCount ?></span>
44
+ The number of free/busy time slots
45
+ </li>
46
+ <li class="list-group-item">
47
+ <span class="badge"><?php echo $ical->todoCount ?></span>
48
+ The number of todos
49
+ </li>
50
+ <li class="list-group-item">
51
+ <span class="badge"><?php echo $ical->alarmCount ?></span>
52
+ The number of alarms
53
+ </li>
54
+ </ul>
55
+
56
+ <?php
57
+ $showExample = array(
58
+ 'interval' => true,
59
+ 'range' => true,
60
+ 'all' => true,
61
+ );
62
+ ?>
63
+
64
+ <?php
65
+ if ($showExample['interval']) {
66
+ $events = $ical->eventsFromInterval('1 week');
67
+
68
+ if ($events) {
69
+ echo '<h4>Events in the next 7 days:</h4>';
70
+ }
71
+
72
+ $count = 1;
73
+ ?>
74
+ <div class="row">
75
+ <?php
76
+ foreach ($events as $event) : ?>
77
+ <div class="col-md-4">
78
+ <div class="thumbnail">
79
+ <div class="caption">
80
+ <h3><?php
81
+ $dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3], $forceTimeZone);
82
+ echo $event->summary . ' (' . $dtstart->format('d-m-Y H:i') . ')';
83
+ ?></h3>
84
+ <?php echo $event->printData() ?>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ <?php
89
+ if ($count > 1 && $count % 3 === 0) {
90
+ echo '</div><div class="row">';
91
+ }
92
+
93
+ $count++;
94
+ ?>
95
+ <?php
96
+ endforeach
97
+ ?>
98
+ </div>
99
+ <?php } ?>
100
+
101
+ <?php
102
+ if ($showExample['range']) {
103
+ $events = $ical->eventsFromRange('2017-03-01 12:00:00', '2017-04-31 17:00:00');
104
+
105
+ if ($events) {
106
+ echo '<h4>Events March through April:</h4>';
107
+ }
108
+
109
+ $count = 1;
110
+ ?>
111
+ <div class="row">
112
+ <?php
113
+ foreach ($events as $event) : ?>
114
+ <div class="col-md-4">
115
+ <div class="thumbnail">
116
+ <div class="caption">
117
+ <h3><?php
118
+ $dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3], $forceTimeZone);
119
+ echo $event->summary . ' (' . $dtstart->format('d-m-Y H:i') . ')';
120
+ ?></h3>
121
+ <?php echo $event->printData() ?>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ <?php
126
+ if ($count > 1 && $count % 3 === 0) {
127
+ echo '</div><div class="row">';
128
+ }
129
+
130
+ $count++;
131
+ ?>
132
+ <?php
133
+ endforeach
134
+ ?>
135
+ </div>
136
+ <?php } ?>
137
+
138
+ <?php
139
+ if ($showExample['all']) {
140
+ $events = $ical->sortEventsWithOrder($ical->events());
141
+
142
+ if ($events) {
143
+ echo '<h4>All Events:</h4>';
144
+ }
145
+ ?>
146
+ <div class="row">
147
+ <?php
148
+ $count = 1;
149
+ foreach ($events as $event) : ?>
150
+ <div class="col-md-4">
151
+ <div class="thumbnail">
152
+ <div class="caption">
153
+ <h3><?php
154
+ $dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3], $forceTimeZone);
155
+ echo $event->summary . ' (' . $dtstart->format('d-m-Y H:i') . ')';
156
+ ?></h3>
157
+ <?php echo $event->printData() ?>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ <?php
162
+ if ($count > 1 && $count % 3 === 0) {
163
+ echo '</div><div class="row">';
164
+ }
165
+
166
+ $count++;
167
+ ?>
168
+ <?php
169
+ endforeach
170
+ ?>
171
+ </div>
172
+ <?php } ?>
173
+ </div>
174
+ </body>
175
+ </html>
app/vendor/johngrogg/ics-parser/src/ICal/Event.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace ICal;
4
+
5
+ class Event
6
+ {
7
+ // phpcs:disable Generic.Arrays.DisallowLongArraySyntax.Found
8
+
9
+ const HTML_TEMPLATE = '<p>%s: %s</p>';
10
+
11
+ /**
12
+ * https://www.kanzaki.com/docs/ical/summary.html
13
+ *
14
+ * @var $summary
15
+ */
16
+ public $summary;
17
+
18
+ /**
19
+ * https://www.kanzaki.com/docs/ical/dtstart.html
20
+ *
21
+ * @var $dtstart
22
+ */
23
+ public $dtstart;
24
+
25
+ /**
26
+ * https://www.kanzaki.com/docs/ical/dtend.html
27
+ *
28
+ * @var $dtend
29
+ */
30
+ public $dtend;
31
+
32
+ /**
33
+ * https://www.kanzaki.com/docs/ical/duration.html
34
+ *
35
+ * @var $duration
36
+ */
37
+ public $duration;
38
+
39
+ /**
40
+ * https://www.kanzaki.com/docs/ical/dtstamp.html
41
+ *
42
+ * @var $dtstamp
43
+ */
44
+ public $dtstamp;
45
+
46
+ /**
47
+ * https://www.kanzaki.com/docs/ical/uid.html
48
+ *
49
+ * @var $uid
50
+ */
51
+ public $uid;
52
+
53
+ /**
54
+ * https://www.kanzaki.com/docs/ical/created.html
55
+ *
56
+ * @var $created
57
+ */
58
+ public $created;
59
+
60
+ /**
61
+ * https://www.kanzaki.com/docs/ical/lastModified.html
62
+ *
63
+ * @var $lastmodified
64
+ */
65
+ public $lastmodified;
66
+
67
+ /**
68
+ * https://www.kanzaki.com/docs/ical/description.html
69
+ *
70
+ * @var $description
71
+ */
72
+ public $description;
73
+
74
+ /**
75
+ * https://www.kanzaki.com/docs/ical/location.html
76
+ *
77
+ * @var $location
78
+ */
79
+ public $location;
80
+
81
+ /**
82
+ * https://www.kanzaki.com/docs/ical/sequence.html
83
+ *
84
+ * @var $sequence
85
+ */
86
+ public $sequence;
87
+
88
+ /**
89
+ * https://www.kanzaki.com/docs/ical/status.html
90
+ *
91
+ * @var $status
92
+ */
93
+ public $status;
94
+
95
+ /**
96
+ * https://www.kanzaki.com/docs/ical/transp.html
97
+ *
98
+ * @var $transp
99
+ */
100
+ public $transp;
101
+
102
+ /**
103
+ * https://www.kanzaki.com/docs/ical/organizer.html
104
+ *
105
+ * @var $organizer
106
+ */
107
+ public $organizer;
108
+
109
+ /**
110
+ * https://www.kanzaki.com/docs/ical/attendee.html
111
+ *
112
+ * @var $attendee
113
+ */
114
+ public $attendee;
115
+
116
+ /**
117
+ * Creates the Event object
118
+ *
119
+ * @param array $data
120
+ * @return void
121
+ */
122
+ public function __construct(array $data = array())
123
+ {
124
+ if (!empty($data)) {
125
+ foreach ($data as $key => $value) {
126
+ $variable = self::snakeCase($key);
127
+ $this->{$variable} = self::prepareData($value);
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Prepares the data for output
134
+ *
135
+ * @param mixed $value
136
+ * @return mixed
137
+ */
138
+ protected function prepareData($value)
139
+ {
140
+ if (is_string($value)) {
141
+ return stripslashes(trim(str_replace('\n', "\n", $value)));
142
+ } elseif (is_array($value)) {
143
+ return array_map('self::prepareData', $value);
144
+ }
145
+
146
+ return $value;
147
+ }
148
+
149
+ /**
150
+ * Returns Event data excluding anything blank
151
+ * within an HTML template
152
+ *
153
+ * @param string $html HTML template to use
154
+ * @return string
155
+ */
156
+ public function printData($html = self::HTML_TEMPLATE)
157
+ {
158
+ $data = array(
159
+ 'SUMMARY' => $this->summary,
160
+ 'DTSTART' => $this->dtstart,
161
+ 'DTEND' => $this->dtend,
162
+ 'DTSTART_TZ' => $this->dtstart_tz,
163
+ 'DTEND_TZ' => $this->dtend_tz,
164
+ 'DURATION' => $this->duration,
165
+ 'DTSTAMP' => $this->dtstamp,
166
+ 'UID' => $this->uid,
167
+ 'CREATED' => $this->created,
168
+ 'LAST-MODIFIED' => $this->lastmodified,
169
+ 'DESCRIPTION' => $this->description,
170
+ 'LOCATION' => $this->location,
171
+ 'SEQUENCE' => $this->sequence,
172
+ 'STATUS' => $this->status,
173
+ 'TRANSP' => $this->transp,
174
+ 'ORGANISER' => $this->organizer,
175
+ 'ATTENDEE(S)' => $this->attendee,
176
+ );
177
+
178
+ $data = array_filter($data); // Remove any blank values
179
+ $output = '';
180
+
181
+ foreach ($data as $key => $value) {
182
+ $output .= sprintf($html, $key, $value);
183
+ }
184
+
185
+ return $output;
186
+ }
187
+
188
+ /**
189
+ * Converts the given input to snake_case
190
+ *
191
+ * @param string $input
192
+ * @param string $glue
193
+ * @param string $separator
194
+ * @return string
195
+ */
196
+ protected static function snakeCase($input, $glue = '_', $separator = '-')
197
+ {
198
+ $input = preg_split('/(?<=[a-z])(?=[A-Z])/x', $input);
199
+ $input = join($input, $glue);
200
+ $input = str_replace($separator, $glue, $input);
201
+
202
+ return strtolower($input);
203
+ }
204
+ }
app/vendor/johngrogg/ics-parser/src/ICal/ICal.php ADDED
@@ -0,0 +1,2430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This PHP class will read an ICS (`.ics`, `.ical`, `.ifb`) file, parse it and return an
4
+ * array of its contents.
5
+ *
6
+ * PHP 5 (≥ 5.3.0)
7
+ *
8
+ * @author Jonathan Goode <https://github.com/u01jmg3>
9
+ * @license https://opensource.org/licenses/mit-license.php MIT License
10
+ * @version 2.1.4
11
+ */
12
+
13
+ namespace ICal;
14
+
15
+ use Carbon\Carbon;
16
+
17
+ class ICal
18
+ {
19
+ // phpcs:disable Generic.Arrays.DisallowLongArraySyntax.Found
20
+
21
+ const DATE_TIME_FORMAT = 'Ymd\THis';
22
+ const DATE_TIME_FORMAT_PRETTY = 'F Y H:i:s';
23
+ const ICAL_DATE_TIME_TEMPLATE = 'TZID=%s:';
24
+ const RECURRENCE_EVENT = 'Generated recurrence event';
25
+ const SECONDS_IN_A_WEEK = 604800;
26
+ const TIME_FORMAT = 'His';
27
+ const TIME_ZONE_UTC = 'UTC';
28
+ const UNIX_FORMAT = 'U';
29
+ const UNIX_MIN_YEAR = 1970;
30
+
31
+ /**
32
+ * Tracks the number of alarms in the current iCal feed
33
+ *
34
+ * @var integer
35
+ */
36
+ public $alarmCount = 0;
37
+
38
+ /**
39
+ * Tracks the number of events in the current iCal feed
40
+ *
41
+ * @var integer
42
+ */
43
+ public $eventCount = 0;
44
+
45
+ /**
46
+ * Tracks the free/busy count in the current iCal feed
47
+ *
48
+ * @var integer
49
+ */
50
+ public $freeBusyCount = 0;
51
+
52
+ /**
53
+ * Tracks the number of todos in the current iCal feed
54
+ *
55
+ * @var integer
56
+ */
57
+ public $todoCount = 0;
58
+
59
+ /**
60
+ * The value in years to use for indefinite, recurring events
61
+ *
62
+ * @var integer
63
+ */
64
+ public $defaultSpan = 2;
65
+
66
+ /**
67
+ * Enables customisation of the default time zone
68
+ *
69
+ * @var string
70
+ */
71
+ public $defaultTimeZone;
72
+
73
+ /**
74
+ * The two letter representation of the first day of the week
75
+ *
76
+ * @var string
77
+ */
78
+ public $defaultWeekStart = 'MO';
79
+
80
+ /**
81
+ * Toggles whether to skip the parsing of recurrence rules
82
+ *
83
+ * @var boolean
84
+ */
85
+ public $skipRecurrence = false;
86
+
87
+ /**
88
+ * Toggles whether to use time zone info when parsing recurrence rules
89
+ *
90
+ * @var boolean
91
+ */
92
+ public $useTimeZoneWithRRules = false;
93
+
94
+ /**
95
+ * Toggles whether to disable all character replacement.
96
+ *
97
+ * @var boolean
98
+ */
99
+ public $disableCharacterReplacement = false;
100
+
101
+ /**
102
+ * The parsed calendar
103
+ *
104
+ * @var array
105
+ */
106
+ public $cal = array();
107
+
108
+ /**
109
+ * Tracks the VFREEBUSY component
110
+ *
111
+ * @var integer
112
+ */
113
+ protected $freeBusyIndex = 0;
114
+
115
+ /**
116
+ * Variable to track the previous keyword
117
+ *
118
+ * @var string
119
+ */
120
+ protected $lastKeyword;
121
+
122
+ /**
123
+ * Cache valid time zones to avoid unnecessary lookups
124
+ *
125
+ * @var array
126
+ */
127
+ protected $validTimeZones = array();
128
+
129
+ /**
130
+ * Event recurrence instances that have been altered
131
+ *
132
+ * @var array
133
+ */
134
+ protected $alteredRecurrenceInstances = array();
135
+
136
+ /**
137
+ * An associative array containing ordinal data
138
+ *
139
+ * @var array
140
+ */
141
+ protected $dayOrdinals = array(
142
+ 1 => 'first',
143
+ 2 => 'second',
144
+ 3 => 'third',
145
+ 4 => 'fourth',
146
+ 5 => 'fifth',
147
+ );
148
+
149
+ /**
150
+ * An associative array containing weekday conversion data
151
+ *
152
+ * @var array
153
+ */
154
+ protected $weekdays = array(
155
+ 'SU' => 'sunday',
156
+ 'MO' => 'monday',
157
+ 'TU' => 'tuesday',
158
+ 'WE' => 'wednesday',
159
+ 'TH' => 'thursday',
160
+ 'FR' => 'friday',
161
+ 'SA' => 'saturday',
162
+ );
163
+
164
+ /**
165
+ * An associative array containing week conversion data
166
+ * (UK = SU, Europe = MO)
167
+ *
168
+ * @var array
169
+ */
170
+ protected $weeks = array(
171
+ 'SA' => array('SA', 'SU', 'MO', 'TU', 'WE', 'TH', 'FR'),
172
+ 'SU' => array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'),
173
+ 'MO' => array('MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'),
174
+ );
175
+
176
+ /**
177
+ * An associative array containing month names
178
+ *
179
+ * @var array
180
+ */
181
+ protected $monthNames = array(
182
+ 1 => 'January',
183
+ 2 => 'February',
184
+ 3 => 'March',
185
+ 4 => 'April',
186
+ 5 => 'May',
187
+ 6 => 'June',
188
+ 7 => 'July',
189
+ 8 => 'August',
190
+ 9 => 'September',
191
+ 10 => 'October',
192
+ 11 => 'November',
193
+ 12 => 'December',
194
+ );
195
+
196
+ /**
197
+ * An associative array containing frequency conversion terms
198
+ *
199
+ * @var array
200
+ */
201
+ protected $frequencyConversion = array(
202
+ 'DAILY' => 'day',
203
+ 'WEEKLY' => 'week',
204
+ 'MONTHLY' => 'month',
205
+ 'YEARLY' => 'year',
206
+ );
207
+
208
+ /**
209
+ * Define which variables can be configured
210
+ *
211
+ * @var array
212
+ */
213
+ private static $configurableOptions = array(
214
+ 'defaultSpan',
215
+ 'defaultTimeZone',
216
+ 'defaultWeekStart',
217
+ 'disableCharacterReplacement',
218
+ 'skipRecurrence',
219
+ 'useTimeZoneWithRRules',
220
+ );
221
+
222
+ /**
223
+ * Creates the ICal object
224
+ *
225
+ * @param mixed $files
226
+ *
227
+ * @param array $options
228
+ * @return void
229
+ */
230
+ public function __construct($files = false, array $options = array())
231
+ {
232
+ ini_set('auto_detect_line_endings', '1');
233
+
234
+ foreach ($options as $option => $value) {
235
+ if (in_array($option, self::$configurableOptions)) {
236
+ $this->{$option} = $value;
237
+ }
238
+ }
239
+
240
+ // Fallback to use the system default time zone
241
+ if (!isset($this->defaultTimeZone) || !$this->isValidTimeZoneId($this->defaultTimeZone)) {
242
+ $this->defaultTimeZone = date_default_timezone_get();
243
+ }
244
+
245
+ if ($files !== false) {
246
+ $files = is_array($files) ? $files : array($files);
247
+
248
+ foreach ($files as $file) {
249
+ if ($this->isFileOrUrl($file)) {
250
+ $lines = $this->fileOrUrl($file);
251
+ } else {
252
+ $lines = is_array($file) ? $file : array($file);
253
+ }
254
+
255
+ $this->initLines($lines);
256
+ }
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Initialises lines from a string
262
+ *
263
+ * @param string $string
264
+ * @return ICal
265
+ */
266
+ public function initString($string)
267
+ {
268
+ if (empty($this->cal)) {
269
+ $lines = explode(PHP_EOL, $string);
270
+
271
+ $this->initLines($lines);
272
+ } else {
273
+ trigger_error('ICal::initString: Calendar already initialised in constructor', E_USER_NOTICE);
274
+ }
275
+
276
+ return $this;
277
+ }
278
+
279
+ /**
280
+ * Initialises lines from a file
281
+ *
282
+ * @param string $file
283
+ * @return ICal
284
+ */
285
+ public function initFile($file)
286
+ {
287
+ if (empty($this->cal)) {
288
+ $lines = $this->fileOrUrl($file);
289
+
290
+ $this->initLines($lines);
291
+ } else {
292
+ trigger_error('ICal::initFile: Calendar already initialised in constructor', E_USER_NOTICE);
293
+ }
294
+
295
+ return $this;
296
+ }
297
+
298
+ /**
299
+ * Initialises lines from a URL
300
+ *
301
+ * @param string $url
302
+ * @return ICal
303
+ */
304
+ public function initUrl($url)
305
+ {
306
+ $this->initFile($url);
307
+
308
+ return $this;
309
+ }
310
+
311
+ /**
312
+ * Initialises the parser using an array
313
+ * containing each line of iCal content
314
+ *
315
+ * @param array $lines
316
+ * @return void
317
+ */
318
+ protected function initLines(array $lines)
319
+ {
320
+ $lines = $this->unfold($lines);
321
+
322
+ if (stristr($lines[0], 'BEGIN:VCALENDAR') !== false) {
323
+ $component = '';
324
+ foreach ($lines as $line) {
325
+ $line = rtrim($line); // Trim trailing whitespace
326
+ $line = $this->removeUnprintableChars($line);
327
+
328
+ if (!$this->disableCharacterReplacement) {
329
+ $line = $this->cleanData($line);
330
+ }
331
+
332
+ $add = $this->keyValueFromString($line);
333
+
334
+ $keyword = $add[0];
335
+ $values = $add[1]; // May be an array containing multiple values
336
+
337
+ if (!is_array($values)) {
338
+ if (!empty($values)) {
339
+ $values = array($values); // Make an array as not already
340
+ $blankArray = array(); // Empty placeholder array
341
+ array_push($values, $blankArray);
342
+ } else {
343
+ $values = array(); // Use blank array to ignore this line
344
+ }
345
+ } elseif (empty($values[0])) {
346
+ $values = array(); // Use blank array to ignore this line
347
+ }
348
+
349
+ // Reverse so that our array of properties is processed first
350
+ $values = array_reverse($values);
351
+
352
+ foreach ($values as $value) {
353
+ switch ($line) {
354
+ // https://www.kanzaki.com/docs/ical/vtodo.html
355
+ case 'BEGIN:VTODO':
356
+ if (!is_array($value)) {
357
+ $this->todoCount++;
358
+ }
359
+
360
+ $component = 'VTODO';
361
+ break;
362
+
363
+ // https://www.kanzaki.com/docs/ical/vevent.html
364
+ case 'BEGIN:VEVENT':
365
+ if (!is_array($value)) {
366
+ $this->eventCount++;
367
+ }
368
+
369
+ $component = 'VEVENT';
370
+ break;
371
+
372
+ // https://www.kanzaki.com/docs/ical/vfreebusy.html
373
+ case 'BEGIN:VFREEBUSY':
374
+ if (!is_array($value)) {
375
+ $this->freeBusyIndex++;
376
+ }
377
+
378
+ $component = 'VFREEBUSY';
379
+ break;
380
+
381
+ case 'BEGIN:VALARM':
382
+ if (!is_array($value)) {
383
+ $this->alarmCount++;
384
+ }
385
+
386
+ $component = 'VALARM';
387
+ break;
388
+
389
+ case 'END:VALARM':
390
+ $component = 'VEVENT';
391
+ break;
392
+
393
+ case 'BEGIN:DAYLIGHT':
394
+ case 'BEGIN:STANDARD':
395
+ case 'BEGIN:VCALENDAR':
396
+ case 'BEGIN:VTIMEZONE':
397
+ $component = $value;
398
+ break;
399
+
400
+ case 'END:DAYLIGHT':
401
+ case 'END:STANDARD':
402
+ case 'END:VCALENDAR':
403
+ case 'END:VEVENT':
404
+ case 'END:VFREEBUSY':
405
+ case 'END:VTIMEZONE':
406
+ case 'END:VTODO':
407
+ $component = 'VCALENDAR';
408
+ break;
409
+
410
+ default:
411
+ $this->addCalendarComponentWithKeyAndValue($component, $keyword, $value);
412
+ break;
413
+ }
414
+ }
415
+ }
416
+
417
+ $this->processEvents();
418
+
419
+ if (!$this->skipRecurrence) {
420
+ $this->processRecurrences();
421
+
422
+ // Apply changes to altered recurrence instances
423
+ if (!empty($this->alteredRecurrenceInstances)) {
424
+ $events = $this->cal['VEVENT'];
425
+
426
+ foreach ($this->alteredRecurrenceInstances as $alteredRecurrenceInstance) {
427
+ if (isset($alteredRecurrenceInstance['altered-event'])) {
428
+ $alteredEvent = $alteredRecurrenceInstance['altered-event'];
429
+ $key = key($alteredEvent);
430
+ $events[$key] = $alteredEvent[$key];
431
+ }
432
+ }
433
+
434
+ $this->cal['VEVENT'] = $events;
435
+ }
436
+ }
437
+
438
+ $this->processDateConversions();
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Unfolds an iCal file in preparation for parsing
444
+ * (https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html)
445
+ *
446
+ * @param array $lines
447
+ * @return string
448
+ */
449
+ protected function unfold(array $lines)
450
+ {
451
+ $string = implode(PHP_EOL, $lines);
452
+ $string = preg_replace('/' . PHP_EOL . '[ \t]/', '', $string);
453
+ $lines = explode(PHP_EOL, $string);
454
+
455
+ return $lines;
456
+ }
457
+
458
+ /**
459
+ * Add one key and value pair to the `$this->cal` array
460
+ *
461
+ * @param string $component
462
+ * @param string|boolean $keyword
463
+ * @param string $value
464
+ * @return void
465
+ */
466
+ protected function addCalendarComponentWithKeyAndValue($component, $keyword, $value)
467
+ {
468
+ if ($keyword == false) {
469
+ $keyword = $this->lastKeyword;
470
+ }
471
+
472
+ switch ($component) {
473
+ case 'VALARM':
474
+ $key1 = 'VEVENT';
475
+ $key2 = ($this->eventCount - 1);
476
+ $key3 = $component;
477
+
478
+ if (!isset($this->cal[$key1][$key2][$key3]["{$keyword}_array"])) {
479
+ $this->cal[$key1][$key2][$key3]["{$keyword}_array"] = array();
480
+ }
481
+
482
+ if (is_array($value)) {
483
+ // Add array of properties to the end
484
+ array_push($this->cal[$key1][$key2][$key3]["{$keyword}_array"], $value);
485
+ } else {
486
+ if (!isset($this->cal[$key1][$key2][$key3][$keyword])) {
487
+ $this->cal[$key1][$key2][$key3][$keyword] = $value;
488
+ }
489
+
490
+ if ($this->cal[$key1][$key2][$key3][$keyword] !== $value) {
491
+ $this->cal[$key1][$key2][$key3][$keyword] .= ',' . $value;
492
+ }
493
+ }
494
+ break;
495
+
496
+ case 'VEVENT':
497
+ $key1 = $component;
498
+ $key2 = ($this->eventCount - 1);
499
+
500
+ if (!isset($this->cal[$key1][$key2]["{$keyword}_array"])) {
501
+ $this->cal[$key1][$key2]["{$keyword}_array"] = array();
502
+ }
503
+
504
+ if (is_array($value)) {
505
+ // Add array of properties to the end
506
+ array_push($this->cal[$key1][$key2]["{$keyword}_array"], $value);
507
+ } else {
508
+ if (!isset($this->cal[$key1][$key2][$keyword])) {
509
+ $this->cal[$key1][$key2][$keyword] = $value;
510
+ }
511
+
512
+ if ($keyword === 'EXDATE') {
513
+ if (trim($value) === $value) {
514
+ $array = array_filter(explode(',', $value));
515
+ $this->cal[$key1][$key2]["{$keyword}_array"][] = $array;
516
+ } else {
517
+ $value = explode(',', implode(',', $this->cal[$key1][$key2]["{$keyword}_array"][1]) . trim($value));
518
+ $this->cal[$key1][$key2]["{$keyword}_array"][1] = $value;
519
+ }
520
+ } else {
521
+ $this->cal[$key1][$key2]["{$keyword}_array"][] = $value;
522
+
523
+ if ($keyword === 'DURATION') {
524
+ $duration = new \DateInterval($value);
525
+ array_push($this->cal[$key1][$key2]["{$keyword}_array"], $duration);
526
+ }
527
+ }
528
+
529
+ if ($this->cal[$key1][$key2][$keyword] !== $value) {
530
+ $this->cal[$key1][$key2][$keyword] .= ',' . $value;
531
+ }
532
+ }
533
+ break;
534
+
535
+ case 'VFREEBUSY':
536
+ $key1 = $component;
537
+ $key2 = ($this->freeBusyIndex - 1);
538
+ $key3 = $keyword;
539
+
540
+ if ($keyword === 'FREEBUSY') {
541
+ if (is_array($value)) {
542
+ $this->cal[$key1][$key2][$key3][][] = $value;
543
+ } else {
544
+ $this->freeBusyCount++;
545
+
546
+ end($this->cal[$key1][$key2][$key3]);
547
+ $key = key($this->cal[$key1][$key2][$key3]);
548
+
549
+ $value = explode('/', $value);
550
+ $this->cal[$key1][$key2][$key3][$key][] = $value;
551
+ }
552
+ } else {
553
+ $this->cal[$key1][$key2][$key3][] = $value;
554
+ }
555
+ break;
556
+
557
+ case 'VTODO':
558
+ $this->cal[$component][$this->todoCount - 1][$keyword] = $value;
559
+ break;
560
+
561
+ default:
562
+ $this->cal[$component][$keyword] = $value;
563
+ break;
564
+ }
565
+
566
+ $this->lastKeyword = $keyword;
567
+ }
568
+
569
+ /**
570
+ * Gets the key value pair from an iCal string
571
+ *
572
+ * @param string $text
573
+ * @return array
574
+ */
575
+ protected function keyValueFromString($text)
576
+ {
577
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
578
+
579
+ $colon = strpos($text, ':');
580
+ $quote = strpos($text, '"');
581
+ if ($colon === false) {
582
+ $matches = array();
583
+ } elseif ($quote === false || $colon < $quote) {
584
+ list($before, $after) = explode(':', $text, 2);
585
+ $matches = array($text, $before, $after);
586
+ } else {
587
+ list($before, $text) = explode('"', $text, 2);
588
+ $text = '"' . $text;
589
+ $matches = str_getcsv($text, ':');
590
+ $combinedValue = '';
591
+
592
+ foreach ($matches as $key => $match) {
593
+ if ($key === 0) {
594
+ if (!empty($before)) {
595
+ $matches[$key] = $before . '"' . $matches[$key] . '"';
596
+ }
597
+ } else {
598
+ if ($key > 1) {
599
+ $combinedValue .= ':';
600
+ }
601
+
602
+ $combinedValue .= $matches[$key];
603
+ }
604
+ }
605
+
606
+ $matches = array_slice($matches, 0, 2);
607
+ $matches[1] = $combinedValue;
608
+ array_unshift($matches, $before . $text);
609
+ }
610
+
611
+ if (count($matches) === 0) {
612
+ return false;
613
+ }
614
+
615
+ if (preg_match('/^([A-Z-]+)([;][\w\W]*)?$/', $matches[1])) {
616
+ $matches = array_splice($matches, 1, 2); // Remove first match and re-align ordering
617
+
618
+ // Process properties
619
+ if (preg_match('/([A-Z-]+)[;]([\w\W]*)/', $matches[0], $properties)) {
620
+ // Remove first match
621
+ array_shift($properties);
622
+ // Fix to ignore everything in keyword after a ; (e.g. Language, TZID, etc.)
623
+ $matches[0] = $properties[0];
624
+ array_shift($properties); // Repeat removing first match
625
+
626
+ $formatted = array();
627
+ foreach ($properties as $property) {
628
+ // Match semicolon separator outside of quoted substrings
629
+ preg_match_all('~[^' . PHP_EOL . '";]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^' . PHP_EOL . '";]*)*~', $property, $attributes);
630
+ // Remove multi-dimensional array and use the first key
631
+ $attributes = (sizeof($attributes) === 0) ? array($property) : reset($attributes);
632
+
633
+ if (is_array($attributes)) {
634
+ foreach ($attributes as $attribute) {
635
+ // Match equals sign separator outside of quoted substrings
636
+ preg_match_all(
637
+ '~[^' . PHP_EOL . '"=]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^' . PHP_EOL . '"=]*)*~',
638
+ $attribute,
639
+ $values
640
+ );
641
+ // Remove multi-dimensional array and use the first key
642
+ $value = (sizeof($values) === 0) ? null : reset($values);
643
+
644
+ if (is_array($value) && isset($value[1])) {
645
+ // Remove double quotes from beginning and end only
646
+ $formatted[$value[0]] = trim($value[1], '"');
647
+ }
648
+ }
649
+ }
650
+ }
651
+
652
+ // Assign the keyword property information
653
+ $properties[0] = $formatted;
654
+
655
+ // Add match to beginning of array
656
+ array_unshift($properties, $matches[1]);
657
+ $matches[1] = $properties;
658
+ }
659
+
660
+ return $matches;
661
+ } else {
662
+ return false; // Ignore this match
663
+ }
664
+ }
665
+
666
+ /**
667
+ * Returns a `DateTime` object from an iCal date time format
668
+ *
669
+ * @param string $icalDate
670
+ * @param boolean $forceTimeZone
671
+ * @param boolean $forceUtc
672
+ * @return DateTime
673
+ * @throws \Exception
674
+ */
675
+ public function iCalDateToDateTime($icalDate, $forceTimeZone = false, $forceUtc = false)
676
+ {
677
+ /**
678
+ * iCal times may be in 3 formats, (https://www.kanzaki.com/docs/ical/dateTime.html)
679
+ *
680
+ * UTC: Has a trailing 'Z'
681
+ * Floating: No time zone reference specified, no trailing 'Z', use local time
682
+ * TZID: Set time zone as specified
683
+ *
684
+ * Use DateTime class objects to get around limitations with `mktime` and `gmmktime`.
685
+ * Must have a local time zone set to process floating times.
686
+ */
687
+ $pattern = '/\AT?Z?I?D?=?(.*):?'; // [1]: Time zone
688
+ $pattern .= '([0-9]{4})'; // [2]: YYYY
689
+ $pattern .= '([0-9]{2})'; // [3]: MM
690
+ $pattern .= '([0-9]{2})'; // [4]: DD
691
+ $pattern .= 'T?'; // Time delimiter
692
+ $pattern .= '([0-9]{0,2})'; // [5]: HH
693
+ $pattern .= '([0-9]{0,2})'; // [6]: MM
694
+ $pattern .= '([0-9]{0,2})'; // [7]: SS
695
+ $pattern .= '(Z?)/'; // [8]: UTC flag
696
+
697
+ preg_match($pattern, $icalDate, $date);
698
+
699
+ if (empty($date)) {
700
+ throw new \Exception('Invalid iCal date format.');
701
+ }
702
+
703
+ // A Unix timestamp cannot represent a date prior to 1 Jan 1970
704
+ $year = $date[2];
705
+ $isUtc = false;
706
+
707
+ if ($year <= self::UNIX_MIN_YEAR) {
708
+ $eventTimeZone = ltrim(strstr($icalDate, ':', true), 'TZID=');
709
+
710
+ if (empty($eventTimeZone)) {
711
+ $dateTime = new \DateTime($icalDate, new \DateTimeZone($this->defaultTimeZone));
712
+ } else {
713
+ $icalDate = ltrim(strstr($icalDate, ':'), ':');
714
+ $dateTime = new \DateTime($icalDate, new \DateTimeZone($eventTimeZone));
715
+ }
716
+ } else {
717
+ if ($forceTimeZone) {
718
+ // TZID={Time Zone}:
719
+ if (isset($date[1])) {
720
+ $eventTimeZone = rtrim($date[1], ':');
721
+ }
722
+
723
+ if ($date[8] === 'Z') {
724
+ $isUtc = true;
725
+ $dateTime = new \DateTime('now', new \DateTimeZone(self::TIME_ZONE_UTC));
726
+ } elseif (isset($eventTimeZone) && $this->isValidIanaTimeZoneId($eventTimeZone)) {
727
+ $dateTime = new \DateTime('now', new \DateTimeZone($eventTimeZone));
728
+ } elseif (isset($eventTimeZone) && $this->isValidCldrTimeZoneId($eventTimeZone)) {
729
+ $dateTime = new \DateTime('now', new \DateTimeZone($this->isValidCldrTimeZoneId($eventTimeZone, true)));
730
+ } else {
731
+ $dateTime = new \DateTime('now', new \DateTimeZone($this->defaultTimeZone));
732
+ }
733
+ } else {
734
+ if ($forceUtc) {
735
+ $dateTime = new \DateTime('now', new \DateTimeZone(self::TIME_ZONE_UTC));
736
+ } else {
737
+ $dateTime = new \DateTime('now');
738
+ }
739
+ }
740
+
741
+ $dateTime->setDate((int) $date[2], (int) $date[3], (int) $date[4]);
742
+ $dateTime->setTime((int) $date[5], (int) $date[6], (int) $date[7]);
743
+ }
744
+
745
+ if ($forceTimeZone && $isUtc) {
746
+ $dateTime->setTimezone(new \DateTimeZone($this->defaultTimeZone));
747
+ } elseif ($forceUtc) {
748
+ $dateTime->setTimezone(new \DateTimeZone(self::TIME_ZONE_UTC));
749
+ }
750
+
751
+ return $dateTime;
752
+ }
753
+
754
+ /**
755
+ * Returns a Unix timestamp from an iCal date time format
756
+ *
757
+ * @param string $icalDate
758
+ * @param boolean $forceTimeZone
759
+ * @param boolean $forceUtc
760
+ * @return integer
761
+ */
762
+ public function iCalDateToUnixTimestamp($icalDate, $forceTimeZone = false, $forceUtc = false)
763
+ {
764
+ $dateTime = $this->iCalDateToDateTime($icalDate, $forceTimeZone, $forceUtc);
765
+ $offset = 0;
766
+
767
+ if ($forceTimeZone) {
768
+ $offset = $dateTime->getOffset();
769
+ }
770
+
771
+ return $dateTime->getTimestamp() + $offset;
772
+ }
773
+
774
+ /**
775
+ * Returns a date adapted to the calendar time zone depending on the event `TZID`
776
+ *
777
+ * @param array $event
778
+ * @param string $key
779
+ * @param string $format
780
+ * @return string|boolean
781
+ */
782
+ public function iCalDateWithTimeZone(array $event, $key, $format = self::DATE_TIME_FORMAT)
783
+ {
784
+ if (!isset($event[$key . '_array']) || !isset($event[$key])) {
785
+ return false;
786
+ }
787
+
788
+ $dateArray = $event[$key . '_array'];
789
+ $date = $event[$key];
790
+
791
+ if ($key === 'DURATION') {
792
+ $duration = end($dateArray);
793
+ $dateTime = $this->parseDuration($event['DTSTART'], $duration, null);
794
+ } else {
795
+ $dateTime = new \DateTime($dateArray[1], new \DateTimeZone(self::TIME_ZONE_UTC));
796
+ $dateTime->setTimezone(new \DateTimeZone($this->calendarTimeZone()));
797
+ }
798
+
799
+ // Force time zone
800
+ if (isset($dateArray[0]['TZID'])) {
801
+ if ($this->isValidIanaTimeZoneId($dateArray[0]['TZID'])) {
802
+ $dateTime->setTimezone(new \DateTimeZone($dateArray[0]['TZID']));
803
+ } elseif ($this->isValidCldrTimeZoneId($dateArray[0]['TZID'])) {
804
+ $dateTime->setTimezone(new \DateTimeZone($this->isValidCldrTimeZoneId($dateArray[0]['TZID'], true)));
805
+ } else {
806
+ $dateTime->setTimezone(new \DateTimeZone($this->defaultTimeZone));
807
+ }
808
+ }
809
+
810
+ if (is_null($format)) {
811
+ $output = $dateTime;
812
+ } else {
813
+ if ($format === self::UNIX_FORMAT) {
814
+ $output = $dateTime->getTimestamp();
815
+ } else {
816
+ $output = $dateTime->format($format);
817
+ }
818
+ }
819
+
820
+ return $output;
821
+ }
822
+
823
+ /**
824
+ * Performs admin tasks on all events as read from the iCal file.
825
+ * Adds a Unix timestamp to all `{DTSTART|DTEND|RECURRENCE-ID}_array` arrays
826
+ * Tracks modified recurrence instances
827
+ *
828
+ * @return boolean|void
829
+ */
830
+ protected function processEvents()
831
+ {
832
+ $events = (isset($this->cal['VEVENT'])) ? $this->cal['VEVENT'] : array();
833
+
834
+ if (empty($events)) {
835
+ return false;
836
+ }
837
+
838
+ foreach ($events as $key => $anEvent) {
839
+ foreach (array('DTSTART', 'DTEND', 'RECURRENCE-ID') as $type) {
840
+ if (isset($anEvent[$type])) {
841
+ $date = $anEvent[$type . '_array'][1];
842
+
843
+ if (isset($anEvent[$type . '_array'][0]['TZID'])) {
844
+ $date = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent[$type . '_array'][0]['TZID']) . $date;
845
+ }
846
+
847
+ $anEvent[$type . '_array'][2] = $this->iCalDateToUnixTimestamp($date, true, true);
848
+ $anEvent[$type . '_array'][3] = $date;
849
+ }
850
+ }
851
+
852
+ if (isset($anEvent['RECURRENCE-ID'])) {
853
+ $uid = $anEvent['UID'];
854
+
855
+ if (!isset($this->alteredRecurrenceInstances[$uid])) {
856
+ $this->alteredRecurrenceInstances[$uid] = array();
857
+ }
858
+
859
+ $recurrenceDateUtc = $this->iCalDateToUnixTimestamp($anEvent['RECURRENCE-ID_array'][3], true, true);
860
+ $this->alteredRecurrenceInstances[$uid][$key] = $recurrenceDateUtc;
861
+ }
862
+
863
+ $events[$key] = $anEvent;
864
+ }
865
+
866
+ $eventKeysToRemove = array();
867
+
868
+ foreach ($events as $key => $event) {
869
+ $checks[] = !isset($event['RECURRENCE-ID']);
870
+ $checks[] = isset($event['UID']);
871
+ $checks[] = isset($event['UID']) && isset($this->alteredRecurrenceInstances[$event['UID']]);
872
+
873
+ if ((bool) array_product($checks)) {
874
+ $eventDtstartUnix = $this->iCalDateToUnixTimestamp($event['DTSTART_array'][3], true, true);
875
+
876
+ if (false !== $alteredEventKey = array_search($eventDtstartUnix, $this->alteredRecurrenceInstances[$event['UID']])) {
877
+ $eventKeysToRemove[] = $alteredEventKey;
878
+
879
+ $alteredEvent = array_replace_recursive($events[$key], $events[$alteredEventKey]);
880
+ $this->alteredRecurrenceInstances[$event['UID']]['altered-event'] = array($key => $alteredEvent);
881
+ }
882
+ }
883
+
884
+ unset($checks);
885
+ }
886
+
887
+ if (!empty($eventKeysToRemove)) {
888
+ foreach ($eventKeysToRemove as $eventKeyToRemove) {
889
+ $events[$eventKeyToRemove] = null;
890
+ }
891
+ }
892
+
893
+ $this->cal['VEVENT'] = $events;
894
+ }
895
+
896
+ /**
897
+ * Processes recurrence rules
898
+ *
899
+ * @return boolean|void
900
+ */
901
+ protected function processRecurrences()
902
+ {
903
+ $events = (isset($this->cal['VEVENT'])) ? $this->cal['VEVENT'] : array();
904
+
905
+ $recurrenceEvents = array();
906
+ $allRecurrenceEvents = array();
907
+
908
+ if (empty($events)) {
909
+ return false;
910
+ }
911
+
912
+ foreach ($events as $anEvent) {
913
+ if (isset($anEvent['RRULE']) && $anEvent['RRULE'] !== '') {
914
+ // Tag as generated by a recurrence rule
915
+ $anEvent['RRULE_array'][2] = self::RECURRENCE_EVENT;
916
+
917
+ $isAllDayEvent = (strlen($anEvent['DTSTART_array'][1]) === 8) ? true : false;
918
+
919
+ $initialStart = new \DateTime($anEvent['DTSTART_array'][1]);
920
+ $initialStartOffset = $initialStart->getOffset();
921
+ $initialStartTimeZoneName = $initialStart->getTimezone()->getName();
922
+
923
+ if (isset($anEvent['DTEND'])) {
924
+ $initialEnd = new \DateTime($anEvent['DTEND_array'][1]);
925
+ $initialEndOffset = $initialEnd->getOffset();
926
+ $initialEndTimeZoneName = $initialEnd->getTimezone()->getName();
927
+ } else {
928
+ $initialEndTimeZoneName = $initialStartTimeZoneName;
929
+ }
930
+
931
+ // Recurring event, parse RRULE and add appropriate duplicate events
932
+ $rrules = array();
933
+ $rruleStrings = explode(';', $anEvent['RRULE']);
934
+
935
+ foreach ($rruleStrings as $s) {
936
+ list($k, $v) = explode('=', $s);
937
+ $rrules[$k] = $v;
938
+ }
939
+
940
+ // Get frequency
941
+ $frequency = $rrules['FREQ'];
942
+ // Get Start timestamp
943
+ $startTimestamp = $initialStart->getTimestamp();
944
+
945
+ if (isset($anEvent['DTEND'])) {
946
+ $endTimestamp = $initialEnd->getTimestamp();
947
+ } elseif (isset($anEvent['DURATION'])) {
948
+ $duration = end($anEvent['DURATION_array']);
949
+ $endTimestamp = $this->parseDuration($anEvent['DTSTART'], $duration);
950
+ } else {
951
+ $endTimestamp = $anEvent['DTSTART_array'][2];
952
+ }
953
+
954
+ $eventTimestampOffset = $endTimestamp - $startTimestamp;
955
+ // Get Interval
956
+ $interval = (isset($rrules['INTERVAL']) && $rrules['INTERVAL'] !== '') ? $rrules['INTERVAL'] : 1;
957
+
958
+ $dayNumber = null;
959
+ $weekday = null;
960
+
961
+ if (in_array($frequency, array('MONTHLY', 'YEARLY')) && isset($rrules['BYDAY']) && $rrules['BYDAY'] !== '') {
962
+ // Deal with BYDAY
963
+ $byDay = $rrules['BYDAY'];
964
+ $dayNumber = intval($byDay);
965
+
966
+ if (empty($dayNumber)) { // Returns 0 when no number defined in BYDAY
967
+ if (!isset($rrules['BYSETPOS'])) {
968
+ $dayNumber = 1; // Set first as default
969
+ } elseif (is_numeric($rrules['BYSETPOS'])) {
970
+ $dayNumber = $rrules['BYSETPOS'];
971
+ }
972
+ }
973
+
974
+ $weekday = substr($byDay, -2);
975
+ }
976
+
977
+ $untilDefault = date_create('now');
978
+ $untilDefault->modify($this->defaultSpan . ' year');
979
+ $untilDefault->setTime(23, 59, 59); // End of the day
980
+
981
+ // Compute EXDATEs
982
+ $exdates = $this->parseExdates($anEvent);
983
+
984
+ if (isset($rrules['UNTIL'])) {
985
+ // Get Until
986
+ $until = strtotime($rrules['UNTIL']);
987
+ } elseif (isset($rrules['COUNT'])) {
988
+ $countOrig = (is_numeric($rrules['COUNT']) && $rrules['COUNT'] > 1) ? $rrules['COUNT'] : 0;
989
+
990
+ // Increment count by the number of excluded dates
991
+ $countOrig += sizeof($exdates);
992
+
993
+ // Remove one to exclude the occurrence that initialises the rule
994
+ $count = ($countOrig - 1);
995
+
996
+ if ($interval >= 2) {
997
+ $count += ($count > 0) ? ($count * $interval) : 0;
998
+ }
999
+
1000
+ $countNb = 1;
1001
+ $offset = "+{$count} " . $this->frequencyConversion[$frequency];
1002
+ $until = strtotime($offset, $startTimestamp);
1003
+
1004
+ if (in_array($frequency, array('MONTHLY', 'YEARLY'))
1005
+ && isset($rrules['BYDAY']) && $rrules['BYDAY'] !== ''
1006
+ ) {
1007
+ $dtstart = date_create($anEvent['DTSTART']);
1008
+
1009
+ if (!$dtstart) {
1010
+ continue;
1011
+ }
1012
+
1013
+ for ($i = 1; $i <= $count; $i++) {
1014
+ $dtstartClone = clone $dtstart;
1015
+ $dtstartClone->modify('next ' . $this->frequencyConversion[$frequency]);
1016
+ $offset = "{$this->convertDayOrdinalToPositive($dayNumber, $weekday, $dtstartClone)} {$this->weekdays[$weekday]} of " . $dtstartClone->format('F Y H:i:01');
1017
+ $dtstart->modify($offset);
1018
+ }
1019
+
1020
+ // Jumping X months forwards doesn't mean
1021
+ // the end date will fall on the same day defined in BYDAY
1022
+ // Use the largest of these to ensure we are going far enough
1023
+ // in the future to capture our final end day
1024
+ $until = max($until, $dtstart->format(self::UNIX_FORMAT));
1025
+ }
1026
+
1027
+ unset($offset);
1028
+ } else {
1029
+ $until = $untilDefault->getTimestamp();
1030
+ }
1031
+
1032
+ $until = intval($until);
1033
+
1034
+ // Decide how often to add events and do so
1035
+ switch ($frequency) {
1036
+ case 'DAILY':
1037
+ // Simply add a new event each interval of days until UNTIL is reached
1038
+ $offset = "+{$interval} day";
1039
+ $recurringTimestamp = strtotime($offset, $startTimestamp);
1040
+
1041
+ while ($recurringTimestamp <= $until) {
1042
+ $dayRecurringTimestamp = $recurringTimestamp;
1043
+
1044
+ // Adjust time zone from initial event
1045
+ $dayRecurringOffset = 0;
1046
+ if ($this->useTimeZoneWithRRules) {
1047
+ $recurringTimeZone = \DateTime::createFromFormat(self::UNIX_FORMAT, $dayRecurringTimestamp);
1048
+ $recurringTimeZone->setTimezone($initialStart->getTimezone());
1049
+ $dayRecurringOffset = $recurringTimeZone->getOffset();
1050
+ $dayRecurringTimestamp += $dayRecurringOffset;
1051
+ }
1052
+
1053
+ // Add event
1054
+ $anEvent['DTSTART'] = date(self::DATE_TIME_FORMAT, $dayRecurringTimestamp) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1055
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1056
+ $anEvent['DTSTART_array'][2] = $dayRecurringTimestamp;
1057
+ $anEvent['DTEND_array'] = $anEvent['DTSTART_array'];
1058
+ $anEvent['DTEND_array'][2] += $eventTimestampOffset;
1059
+ $anEvent['DTEND'] = date(
1060
+ self::DATE_TIME_FORMAT,
1061
+ $anEvent['DTEND_array'][2]
1062
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1063
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1064
+
1065
+ // Exclusions
1066
+ $isExcluded = array_filter($exdates, function ($exdate) use ($anEvent, $dayRecurringOffset) {
1067
+ return self::isExdateMatch($exdate, $anEvent, $dayRecurringOffset);
1068
+ });
1069
+
1070
+ if (isset($anEvent['UID'])) {
1071
+ $searchDate = $anEvent['DTSTART'];
1072
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
1073
+ $searchDate = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent['DTSTART_array'][0]['TZID']) . $searchDate;
1074
+ }
1075
+
1076
+ if (isset($this->alteredRecurrenceInstances[$anEvent['UID']])) {
1077
+ $searchDateUtc = $this->iCalDateToUnixTimestamp($searchDate, true, true);
1078
+ if (in_array($searchDateUtc, $this->alteredRecurrenceInstances[$anEvent['UID']])) {
1079
+ $isExcluded = true;
1080
+ }
1081
+ }
1082
+ }
1083
+
1084
+ if (!$isExcluded) {
1085
+ $anEvent = $this->processEventIcalDateTime($anEvent);
1086
+ $recurrenceEvents[] = $anEvent;
1087
+ $this->eventCount++;
1088
+
1089
+ // If RRULE[COUNT] is reached then break
1090
+ if (isset($rrules['COUNT'])) {
1091
+ $countNb++;
1092
+
1093
+ if ($countNb >= $countOrig) {
1094
+ break;
1095
+ }
1096
+ }
1097
+ }
1098
+
1099
+ // Move forwards
1100
+ $recurringTimestamp = strtotime($offset, $recurringTimestamp);
1101
+ }
1102
+
1103
+ $recurrenceEvents = $this->trimToRecurrenceCount($rrules, $recurrenceEvents);
1104
+ $allRecurrenceEvents = array_merge($allRecurrenceEvents, $recurrenceEvents);
1105
+ $recurrenceEvents = array(); // Reset
1106
+ break;
1107
+
1108
+ case 'WEEKLY':
1109
+ // Create offset
1110
+ $offset = "+{$interval} week";
1111
+
1112
+ $wkst = (isset($rrules['WKST']) && in_array($rrules['WKST'], array('SA', 'SU', 'MO'))) ? $rrules['WKST'] : $this->defaultWeekStart;
1113
+ $aWeek = $this->weeks[$wkst];
1114
+ $days = array('SA' => 'Saturday', 'SU' => 'Sunday', 'MO' => 'Monday');
1115
+
1116
+ // Build list of days of week to add events
1117
+ $weekdays = $aWeek;
1118
+
1119
+ if (isset($rrules['BYDAY']) && $rrules['BYDAY'] !== '') {
1120
+ $byDays = explode(',', $rrules['BYDAY']);
1121
+ } else {
1122
+ // A textual representation of a day, two letters (e.g. SU)
1123
+ $byDays = array(mb_substr(strtoupper($initialStart->format('D')), 0, 2));
1124
+ }
1125
+
1126
+ // Get timestamp of first day of start week
1127
+ $weekRecurringTimestamp = (strcasecmp($initialStart->format('l'), $this->weekdays[$wkst]) === 0)
1128
+ ? $startTimestamp
1129
+ : strtotime("last {$days[$wkst]} " . $initialStart->format('H:i:s'), $startTimestamp);
1130
+
1131
+ // Step through weeks
1132
+ while ($weekRecurringTimestamp <= $until) {
1133
+ $dayRecurringTimestamp = $weekRecurringTimestamp;
1134
+
1135
+ // Adjust time zone from initial event
1136
+ $dayRecurringOffset = 0;
1137
+ if ($this->useTimeZoneWithRRules) {
1138
+ $dayRecurringTimeZone = \DateTime::createFromFormat(self::UNIX_FORMAT, $dayRecurringTimestamp);
1139
+ $dayRecurringTimeZone->setTimezone($initialStart->getTimezone());
1140
+ $dayRecurringOffset = $dayRecurringTimeZone->getOffset();
1141
+ $dayRecurringTimestamp += $dayRecurringOffset;
1142
+ }
1143
+
1144
+ foreach ($weekdays as $day) {
1145
+ // Check if day should be added
1146
+ if (in_array($day, $byDays) && $dayRecurringTimestamp > $startTimestamp
1147
+ && $dayRecurringTimestamp <= $until
1148
+ ) {
1149
+ // Add event
1150
+ $anEvent['DTSTART'] = date(self::DATE_TIME_FORMAT, $dayRecurringTimestamp) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1151
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1152
+ $anEvent['DTSTART_array'][2] = $dayRecurringTimestamp;
1153
+ $anEvent['DTEND_array'] = $anEvent['DTSTART_array'];
1154
+ $anEvent['DTEND_array'][2] += $eventTimestampOffset;
1155
+ $anEvent['DTEND'] = date(
1156
+ self::DATE_TIME_FORMAT,
1157
+ $anEvent['DTEND_array'][2]
1158
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1159
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1160
+
1161
+ // Exclusions
1162
+ $isExcluded = array_filter($exdates, function ($exdate) use ($anEvent, $dayRecurringOffset) {
1163
+ return self::isExdateMatch($exdate, $anEvent, $dayRecurringOffset);
1164
+ });
1165
+
1166
+ if (isset($anEvent['UID'])) {
1167
+ $searchDate = $anEvent['DTSTART'];
1168
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
1169
+ $searchDate = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent['DTSTART_array'][0]['TZID']) . $searchDate;
1170
+ }
1171
+
1172
+ if (isset($this->alteredRecurrenceInstances[$anEvent['UID']])) {
1173
+ $searchDateUtc = $this->iCalDateToUnixTimestamp($searchDate, true, true);
1174
+ if (in_array($searchDateUtc, $this->alteredRecurrenceInstances[$anEvent['UID']])) {
1175
+ $isExcluded = true;
1176
+ }
1177
+ }
1178
+ }
1179
+
1180
+ if (!$isExcluded) {
1181
+ $anEvent = $this->processEventIcalDateTime($anEvent);
1182
+ $recurrenceEvents[] = $anEvent;
1183
+ $this->eventCount++;
1184
+
1185
+ // If RRULE[COUNT] is reached then break
1186
+ if (isset($rrules['COUNT'])) {
1187
+ $countNb++;
1188
+
1189
+ if ($countNb >= $countOrig) {
1190
+ break 2;
1191
+ }
1192
+ }
1193
+ }
1194
+ }
1195
+
1196
+ // Move forwards a day
1197
+ $dayRecurringTimestamp = strtotime('+1 day', $dayRecurringTimestamp);
1198
+ }
1199
+
1200
+ // Move forwards $interval weeks
1201
+ $weekRecurringTimestamp = strtotime($offset, $weekRecurringTimestamp);
1202
+ }
1203
+
1204
+ $recurrenceEvents = $this->trimToRecurrenceCount($rrules, $recurrenceEvents);
1205
+ $allRecurrenceEvents = array_merge($allRecurrenceEvents, $recurrenceEvents);
1206
+ $recurrenceEvents = array(); // Reset
1207
+ break;
1208
+
1209
+ case 'MONTHLY':
1210
+ // Create offset
1211
+ $recurringTimestamp = $startTimestamp;
1212
+ $offset = "+{$interval} month";
1213
+
1214
+ if (isset($rrules['BYMONTHDAY']) && $rrules['BYMONTHDAY'] !== '') {
1215
+ // Deal with BYMONTHDAY
1216
+ $monthdays = explode(',', $rrules['BYMONTHDAY']);
1217
+
1218
+ while ($recurringTimestamp <= $until) {
1219
+ foreach ($monthdays as $key => $monthday) {
1220
+ if ($key === 0) {
1221
+ // Ensure original event conforms to monthday rule
1222
+ $anEvent['DTSTART'] = gmdate(
1223
+ 'Ym' . sprintf('%02d', $monthday) . '\T' . self::TIME_FORMAT,
1224
+ strtotime($anEvent['DTSTART'])
1225
+ ) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1226
+
1227
+ $anEvent['DTEND'] = gmdate(
1228
+ 'Ym' . sprintf('%02d', $monthday) . '\T' . self::TIME_FORMAT,
1229
+ isset($anEvent['DURATION'])
1230
+ ? $this->parseDuration($anEvent['DTSTART'], end($anEvent['DURATION_array']))
1231
+ : strtotime($anEvent['DTEND'])
1232
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1233
+
1234
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1235
+ $anEvent['DTSTART_array'][2] = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
1236
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1237
+ $anEvent['DTEND_array'][2] = $this->iCalDateToUnixTimestamp($anEvent['DTEND']);
1238
+
1239
+ // Ensure recurring timestamp confirms to BYMONTHDAY rule
1240
+ $monthRecurringTimestamp = $this->iCalDateToUnixTimestamp(
1241
+ gmdate(
1242
+ 'Ym' . sprintf('%02d', $monthday) . '\T' . self::TIME_FORMAT,
1243
+ $recurringTimestamp
1244
+ ) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '')
1245
+ );
1246
+ }
1247
+
1248
+ // Adjust time zone from initial event
1249
+ $monthRecurringOffset = 0;
1250
+ if ($this->useTimeZoneWithRRules) {
1251
+ $recurringTimeZone = \DateTime::createFromFormat(self::UNIX_FORMAT, $monthRecurringTimestamp);
1252
+ $recurringTimeZone->setTimezone($initialStart->getTimezone());
1253
+ $monthRecurringOffset = $recurringTimeZone->getOffset();
1254
+ $monthRecurringTimestamp += $monthRecurringOffset;
1255
+ }
1256
+
1257
+ // Add event
1258
+ $anEvent['DTSTART'] = date(
1259
+ 'Ym' . sprintf('%02d', $monthday) . '\T' . self::TIME_FORMAT,
1260
+ $monthRecurringTimestamp
1261
+ ) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1262
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1263
+ $anEvent['DTSTART_array'][2] = $monthRecurringTimestamp;
1264
+ $anEvent['DTEND_array'] = $anEvent['DTSTART_array'];
1265
+ $anEvent['DTEND_array'][2] += $eventTimestampOffset;
1266
+ $anEvent['DTEND'] = date(
1267
+ self::DATE_TIME_FORMAT,
1268
+ $anEvent['DTEND_array'][2]
1269
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1270
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1271
+
1272
+ // Exclusions
1273
+ $isExcluded = array_filter($exdates, function ($exdate) use ($anEvent, $monthRecurringOffset) {
1274
+ return self::isExdateMatch($exdate, $anEvent, $monthRecurringOffset);
1275
+ });
1276
+
1277
+ if (isset($anEvent['UID'])) {
1278
+ $searchDate = $anEvent['DTSTART'];
1279
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
1280
+ $searchDate = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent['DTSTART_array'][0]['TZID']) . $searchDate;
1281
+ }
1282
+
1283
+ if (isset($this->alteredRecurrenceInstances[$anEvent['UID']])) {
1284
+ $searchDateUtc = $this->iCalDateToUnixTimestamp($searchDate, true, true);
1285
+ if (in_array($searchDateUtc, $this->alteredRecurrenceInstances[$anEvent['UID']])) {
1286
+ $isExcluded = true;
1287
+ }
1288
+ }
1289
+ }
1290
+
1291
+ if (!$isExcluded) {
1292
+ $anEvent = $this->processEventIcalDateTime($anEvent);
1293
+ $recurrenceEvents[] = $anEvent;
1294
+ $this->eventCount++;
1295
+
1296
+ // If RRULE[COUNT] is reached then break
1297
+ if (isset($rrules['COUNT'])) {
1298
+ $countNb++;
1299
+
1300
+ if ($countNb >= $countOrig) {
1301
+ break 2;
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+
1307
+ // Move forwards
1308
+ $recurringTimestamp = strtotime($offset, $recurringTimestamp);
1309
+ }
1310
+ } elseif (isset($rrules['BYDAY']) && $rrules['BYDAY'] !== '') {
1311
+ while ($recurringTimestamp <= $until) {
1312
+ $monthRecurringTimestamp = $recurringTimestamp;
1313
+
1314
+ // Adjust time zone from initial event
1315
+ $monthRecurringOffset = 0;
1316
+
1317
+ if ($this->useTimeZoneWithRRules) {
1318
+ $recurringTimeZone = \DateTime::createFromFormat(self::UNIX_FORMAT, $monthRecurringTimestamp);
1319
+ $recurringTimeZone->setTimezone($initialStart->getTimezone());
1320
+ $monthRecurringOffset = $recurringTimeZone->getOffset();
1321
+ $monthRecurringTimestamp += $monthRecurringOffset;
1322
+ }
1323
+
1324
+ $eventStartDesc = "{$this->convertDayOrdinalToPositive($dayNumber, $weekday, $monthRecurringTimestamp)} {$this->weekdays[$weekday]} of "
1325
+ . date(self::DATE_TIME_FORMAT_PRETTY, $monthRecurringTimestamp);
1326
+ $eventStartTimestamp = strtotime($eventStartDesc);
1327
+
1328
+ if (intval($rrules['BYDAY']) === 0) {
1329
+ $lastDayDesc = "last {$this->weekdays[$weekday]} of "
1330
+ . date(self::DATE_TIME_FORMAT_PRETTY, $monthRecurringTimestamp);
1331
+ } else {
1332
+ $lastDayDesc = "{$this->convertDayOrdinalToPositive($dayNumber, $weekday, $monthRecurringTimestamp)} {$this->weekdays[$weekday]} of "
1333
+ . date(self::DATE_TIME_FORMAT_PRETTY, $monthRecurringTimestamp);
1334
+ }
1335
+
1336
+ $lastDayTimestamp = strtotime($lastDayDesc);
1337
+
1338
+ do {
1339
+ // Prevent 5th day of a month from showing up on the next month
1340
+ // If BYDAY and the event falls outside the current month, skip the event
1341
+
1342
+ $compareCurrentMonth = date('F', $monthRecurringTimestamp);
1343
+ $compareEventMonth = date('F', $eventStartTimestamp);
1344
+
1345
+ if ($compareCurrentMonth !== $compareEventMonth) {
1346
+ $monthRecurringTimestamp = strtotime($offset, $monthRecurringTimestamp);
1347
+ continue;
1348
+ }
1349
+
1350
+ if ($eventStartTimestamp > $startTimestamp && $eventStartTimestamp < $until) {
1351
+ $anEvent['DTSTART'] = date(self::DATE_TIME_FORMAT, $eventStartTimestamp) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1352
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1353
+ $anEvent['DTSTART_array'][2] = $eventStartTimestamp;
1354
+ $anEvent['DTEND_array'] = $anEvent['DTSTART_array'];
1355
+ $anEvent['DTEND_array'][2] += $eventTimestampOffset;
1356
+ $anEvent['DTEND'] = date(
1357
+ self::DATE_TIME_FORMAT,
1358
+ $anEvent['DTEND_array'][2]
1359
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1360
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1361
+
1362
+ // Exclusions
1363
+ $isExcluded = array_filter($exdates, function ($exdate) use ($anEvent, $monthRecurringOffset) {
1364
+ return self::isExdateMatch($exdate, $anEvent, $monthRecurringOffset);
1365
+ });
1366
+
1367
+ if (isset($anEvent['UID'])) {
1368
+ $searchDate = $anEvent['DTSTART'];
1369
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
1370
+ $searchDate = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent['DTSTART_array'][0]['TZID']) . $searchDate;
1371
+ }
1372
+
1373
+ if (isset($this->alteredRecurrenceInstances[$anEvent['UID']])) {
1374
+ $searchDateUtc = $this->iCalDateToUnixTimestamp($searchDate, true, true);
1375
+ if (in_array($searchDateUtc, $this->alteredRecurrenceInstances[$anEvent['UID']])) {
1376
+ $isExcluded = true;
1377
+ }
1378
+ }
1379
+ }
1380
+
1381
+ if (!$isExcluded) {
1382
+ $anEvent = $this->processEventIcalDateTime($anEvent);
1383
+ $recurrenceEvents[] = $anEvent;
1384
+ $this->eventCount++;
1385
+
1386
+ // If RRULE[COUNT] is reached then break
1387
+ if (isset($rrules['COUNT'])) {
1388
+ $countNb++;
1389
+
1390
+ if ($countNb >= $countOrig) {
1391
+ break 2;
1392
+ }
1393
+ }
1394
+ }
1395
+ }
1396
+
1397
+ if (isset($rrules['BYSETPOS'])) {
1398
+ // BYSETPOS is defined so skip
1399
+ // looping through each week
1400
+ $lastDayTimestamp = $eventStartTimestamp;
1401
+ }
1402
+
1403
+ $eventStartTimestamp += self::SECONDS_IN_A_WEEK;
1404
+ } while ($eventStartTimestamp <= $lastDayTimestamp);
1405
+
1406
+ // Move forwards
1407
+ $recurringTimestamp = strtotime($offset, $recurringTimestamp);
1408
+ }
1409
+ }
1410
+
1411
+ $recurrenceEvents = $this->trimToRecurrenceCount($rrules, $recurrenceEvents);
1412
+ $allRecurrenceEvents = array_merge($allRecurrenceEvents, $recurrenceEvents);
1413
+ $recurrenceEvents = array(); // Reset
1414
+ break;
1415
+
1416
+ case 'YEARLY':
1417
+ // Create offset
1418
+ $recurringTimestamp = $startTimestamp;
1419
+ $offset = "+{$interval} year";
1420
+
1421
+ // Deal with BYMONTH
1422
+ if (isset($rrules['BYMONTH']) && $rrules['BYMONTH'] !== '') {
1423
+ $bymonths = explode(',', $rrules['BYMONTH']);
1424
+ }
1425
+
1426
+ // Check if BYDAY rule exists
1427
+ if (isset($rrules['BYDAY']) && $rrules['BYDAY'] !== '') {
1428
+ while ($recurringTimestamp <= $until) {
1429
+ $yearRecurringTimestamp = $recurringTimestamp;
1430
+
1431
+ // Adjust time zone from initial event
1432
+ $yearRecurringOffset = 0;
1433
+
1434
+ if ($this->useTimeZoneWithRRules) {
1435
+ $recurringTimeZone = \DateTime::createFromFormat(self::UNIX_FORMAT, $yearRecurringTimestamp);
1436
+ $recurringTimeZone->setTimezone($initialStart->getTimezone());
1437
+ $yearRecurringOffset = $recurringTimeZone->getOffset();
1438
+ $yearRecurringTimestamp += $yearRecurringOffset;
1439
+ }
1440
+
1441
+ foreach ($bymonths as $bymonth) {
1442
+ $eventStartDesc = "{$this->convertDayOrdinalToPositive($dayNumber, $weekday, $yearRecurringTimestamp)} {$this->weekdays[$weekday]}"
1443
+ . " of {$this->monthNames[$bymonth]} "
1444
+ . gmdate('Y H:i:s', $yearRecurringTimestamp);
1445
+ $eventStartTimestamp = strtotime($eventStartDesc);
1446
+
1447
+ if (intval($rrules['BYDAY']) === 0) {
1448
+ $lastDayDesc = "last {$this->weekdays[$weekday]}"
1449
+ . " of {$this->monthNames[$bymonth]} "
1450
+ . gmdate('Y H:i:s', $yearRecurringTimestamp);
1451
+ } else {
1452
+ $lastDayDesc = "{$this->convertDayOrdinalToPositive($dayNumber, $weekday, $yearRecurringTimestamp)} {$this->weekdays[$weekday]}"
1453
+ . " of {$this->monthNames[$bymonth]} "
1454
+ . gmdate('Y H:i:s', $yearRecurringTimestamp);
1455
+ }
1456
+
1457
+ $lastDayTimestamp = strtotime($lastDayDesc);
1458
+
1459
+ do {
1460
+ if ($eventStartTimestamp > $startTimestamp && $eventStartTimestamp < $until) {
1461
+ $anEvent['DTSTART'] = date(self::DATE_TIME_FORMAT, $eventStartTimestamp) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1462
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1463
+ $anEvent['DTSTART_array'][2] = $eventStartTimestamp;
1464
+ $anEvent['DTEND_array'] = $anEvent['DTSTART_array'];
1465
+ $anEvent['DTEND_array'][2] += $eventTimestampOffset;
1466
+ $anEvent['DTEND'] = date(
1467
+ self::DATE_TIME_FORMAT,
1468
+ $anEvent['DTEND_array'][2]
1469
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1470
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1471
+
1472
+ // Exclusions
1473
+ $isExcluded = array_filter($exdates, function ($exdate) use ($anEvent, $yearRecurringOffset) {
1474
+ return self::isExdateMatch($exdate, $anEvent, $yearRecurringOffset);
1475
+ });
1476
+
1477
+ if (isset($anEvent['UID'])) {
1478
+ $searchDate = $anEvent['DTSTART'];
1479
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
1480
+ $searchDate = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent['DTSTART_array'][0]['TZID']) . $searchDate;
1481
+ }
1482
+
1483
+ if (isset($this->alteredRecurrenceInstances[$anEvent['UID']])) {
1484
+ $searchDateUtc = $this->iCalDateToUnixTimestamp($searchDate, true, true);
1485
+ if (in_array($searchDateUtc, $this->alteredRecurrenceInstances[$anEvent['UID']])) {
1486
+ $isExcluded = true;
1487
+ }
1488
+ }
1489
+ }
1490
+
1491
+ if (!$isExcluded) {
1492
+ $anEvent = $this->processEventIcalDateTime($anEvent);
1493
+ $recurrenceEvents[] = $anEvent;
1494
+ $this->eventCount++;
1495
+
1496
+ // If RRULE[COUNT] is reached then break
1497
+ if (isset($rrules['COUNT'])) {
1498
+ $countNb++;
1499
+
1500
+ if ($countNb >= $countOrig) {
1501
+ break 3;
1502
+ }
1503
+ }
1504
+ }
1505
+ }
1506
+
1507
+ $eventStartTimestamp += self::SECONDS_IN_A_WEEK;
1508
+ } while ($eventStartTimestamp <= $lastDayTimestamp);
1509
+ }
1510
+
1511
+ // Move forwards
1512
+ $recurringTimestamp = strtotime($offset, $recurringTimestamp);
1513
+ }
1514
+ } else {
1515
+ $day = $initialStart->format('d');
1516
+
1517
+ // Step through years
1518
+ while ($recurringTimestamp <= $until) {
1519
+ $yearRecurringTimestamp = $recurringTimestamp;
1520
+
1521
+ // Adjust time zone from initial event
1522
+ $yearRecurringOffset = 0;
1523
+ if ($this->useTimeZoneWithRRules) {
1524
+ $recurringTimeZone = \DateTime::createFromFormat(self::UNIX_FORMAT, $yearRecurringTimestamp);
1525
+ $recurringTimeZone->setTimezone($initialStart->getTimezone());
1526
+ $yearRecurringOffset = $recurringTimeZone->getOffset();
1527
+ $yearRecurringTimestamp += $yearRecurringOffset;
1528
+ }
1529
+
1530
+ $eventStartDescs = array();
1531
+ if (isset($rrules['BYMONTH']) && $rrules['BYMONTH'] !== '') {
1532
+ foreach ($bymonths as $bymonth) {
1533
+ array_push($eventStartDescs, "$day {$this->monthNames[$bymonth]} " . gmdate('Y H:i:s', $yearRecurringTimestamp));
1534
+ }
1535
+ } else {
1536
+ array_push($eventStartDescs, $day . gmdate(self::DATE_TIME_FORMAT_PRETTY, $yearRecurringTimestamp));
1537
+ }
1538
+
1539
+ foreach ($eventStartDescs as $eventStartDesc) {
1540
+ $eventStartTimestamp = strtotime($eventStartDesc);
1541
+
1542
+ if ($eventStartTimestamp > $startTimestamp && $eventStartTimestamp < $until) {
1543
+ $anEvent['DTSTART'] = date(self::DATE_TIME_FORMAT, $eventStartTimestamp) . ($isAllDayEvent || ($initialStartTimeZoneName === 'Z') ? 'Z' : '');
1544
+ $anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
1545
+ $anEvent['DTSTART_array'][2] = $eventStartTimestamp;
1546
+ $anEvent['DTEND_array'] = $anEvent['DTSTART_array'];
1547
+ $anEvent['DTEND_array'][2] += $eventTimestampOffset;
1548
+ $anEvent['DTEND'] = date(
1549
+ self::DATE_TIME_FORMAT,
1550
+ $anEvent['DTEND_array'][2]
1551
+ ) . ($isAllDayEvent || ($initialEndTimeZoneName === 'Z') ? 'Z' : '');
1552
+ $anEvent['DTEND_array'][1] = $anEvent['DTEND'];
1553
+
1554
+ // Exclusions
1555
+ $isExcluded = array_filter($exdates, function ($exdate) use ($anEvent, $yearRecurringOffset) {
1556
+ return self::isExdateMatch($exdate, $anEvent, $yearRecurringOffset);
1557
+ });
1558
+
1559
+ if (isset($anEvent['UID'])) {
1560
+ $searchDate = $anEvent['DTSTART'];
1561
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
1562
+ $searchDate = sprintf(self::ICAL_DATE_TIME_TEMPLATE, $anEvent['DTSTART_array'][0]['TZID']) . $searchDate;
1563
+ }
1564
+
1565
+ if (isset($this->alteredRecurrenceInstances[$anEvent['UID']])) {
1566
+ $searchDateUtc = $this->iCalDateToUnixTimestamp($searchDate, true, true);
1567
+ if (in_array($searchDateUtc, $this->alteredRecurrenceInstances[$anEvent['UID']])) {
1568
+ $isExcluded = true;
1569
+ }
1570
+ }
1571
+ }
1572
+
1573
+ if (!$isExcluded) {
1574
+ $anEvent = $this->processEventIcalDateTime($anEvent);
1575
+ $recurrenceEvents[] = $anEvent;
1576
+ $this->eventCount++;
1577
+
1578
+ // If RRULE[COUNT] is reached then break
1579
+ if (isset($rrules['COUNT'])) {
1580
+ $countNb++;
1581
+
1582
+ if ($countNb >= $countOrig) {
1583
+ break 2;
1584
+ }
1585
+ }
1586
+ }
1587
+ }
1588
+ }
1589
+
1590
+ // Move forwards
1591
+ $recurringTimestamp = strtotime($offset, $recurringTimestamp);
1592
+ }
1593
+ }
1594
+
1595
+ $recurrenceEvents = $this->trimToRecurrenceCount($rrules, $recurrenceEvents);
1596
+ $allRecurrenceEvents = array_merge($allRecurrenceEvents, $recurrenceEvents);
1597
+ $recurrenceEvents = array(); // Reset
1598
+ break;
1599
+ }
1600
+ }
1601
+ }
1602
+
1603
+ $events = array_merge($events, $allRecurrenceEvents);
1604
+
1605
+ $this->cal['VEVENT'] = $events;
1606
+ }
1607
+
1608
+ /**
1609
+ * Processes date conversions using the time zone
1610
+ *
1611
+ * Add keys `DTSTART_tz` and `DTEND_tz` to each Event
1612
+ * These keys contain dates adapted to the calendar
1613
+ * time zone depending on the event `TZID`.
1614
+ *
1615
+ * @return boolean|void
1616
+ */
1617
+ protected function processDateConversions()
1618
+ {
1619
+ $events = (isset($this->cal['VEVENT'])) ? $this->cal['VEVENT'] : array();
1620
+
1621
+ if (empty($events)) {
1622
+ return false;
1623
+ }
1624
+
1625
+ foreach ($events as $key => $anEvent) {
1626
+ if (!$this->isValidDate($anEvent['DTSTART'])) {
1627
+ unset($events[$key]);
1628
+ $this->eventCount--;
1629
+
1630
+ continue;
1631
+ }
1632
+
1633
+ if ($this->useTimeZoneWithRRules && isset($anEvent['RRULE_array'][2]) && $anEvent['RRULE_array'][2] === self::RECURRENCE_EVENT) {
1634
+ $events[$key]['DTSTART_tz'] = $anEvent['DTSTART'];
1635
+ $events[$key]['DTEND_tz'] = $anEvent['DTEND'];
1636
+ } else {
1637
+ $events[$key]['DTSTART_tz'] = $this->iCalDateWithTimeZone($anEvent, 'DTSTART');
1638
+
1639
+ if ($this->iCalDateWithTimeZone($anEvent, 'DTEND')) {
1640
+ $events[$key]['DTEND_tz'] = $this->iCalDateWithTimeZone($anEvent, 'DTEND');
1641
+ } elseif ($this->iCalDateWithTimeZone($anEvent, 'DURATION')) {
1642
+ $events[$key]['DTEND_tz'] = $this->iCalDateWithTimeZone($anEvent, 'DURATION');
1643
+ }
1644
+ }
1645
+ }
1646
+
1647
+ $this->cal['VEVENT'] = $events;
1648
+ }
1649
+
1650
+ /**
1651
+ * Extends the `{DTSTART|DTEND|RECURRENCE-ID}_array`
1652
+ * array to include an iCal date time for each event
1653
+ * (`TZID=Timezone:YYYYMMDD[T]HHMMSS`)
1654
+ *
1655
+ * @param array $event
1656
+ * @param integer $index
1657
+ * @return array
1658
+ */
1659
+ protected function processEventIcalDateTime(array $event, $index = 3)
1660
+ {
1661
+ $calendarTimeZone = $this->calendarTimeZone(true);
1662
+
1663
+ foreach (array('DTSTART', 'DTEND', 'RECURRENCE-ID') as $type) {
1664
+ if (isset($event["{$type}_array"])) {
1665
+ $timeZone = (isset($event["{$type}_array"][0]['TZID'])) ? $event["{$type}_array"][0]['TZID'] : $calendarTimeZone;
1666
+ $event["{$type}_array"][$index] = ((is_null($timeZone)) ? '' : sprintf(self::ICAL_DATE_TIME_TEMPLATE, $timeZone)) . $event["{$type}_array"][1];
1667
+ }
1668
+ }
1669
+
1670
+ return $event;
1671
+ }
1672
+
1673
+ /**
1674
+ * Returns an array of Events.
1675
+ * Every event is a class with the event
1676
+ * details being properties within it.
1677
+ *
1678
+ * @return array
1679
+ */
1680
+ public function events()
1681
+ {
1682
+ $array = $this->cal;
1683
+ $array = isset($array['VEVENT']) ? $array['VEVENT'] : array();
1684
+ $events = array();
1685
+
1686
+ if (!empty($array)) {
1687
+ foreach ($array as $event) {
1688
+ $events[] = new Event($event);
1689
+ }
1690
+ }
1691
+
1692
+ return $events;
1693
+ }
1694
+
1695
+ /**
1696
+ * Returns the calendar name
1697
+ *
1698
+ * @return string
1699
+ */
1700
+ public function calendarName()
1701
+ {
1702
+ return isset($this->cal['VCALENDAR']['X-WR-CALNAME']) ? $this->cal['VCALENDAR']['X-WR-CALNAME'] : '';
1703
+ }
1704
+
1705
+ /**
1706
+ * Returns the calendar description
1707
+ *
1708
+ * @return string
1709
+ */
1710
+ public function calendarDescription()
1711
+ {
1712
+ return isset($this->cal['VCALENDAR']['X-WR-CALDESC']) ? $this->cal['VCALENDAR']['X-WR-CALDESC'] : '';
1713
+ }
1714
+
1715
+ /**
1716
+ * Returns the calendar time zone
1717
+ *
1718
+ * @param boolean $ignoreUtc
1719
+ * @return string
1720
+ */
1721
+ public function calendarTimeZone($ignoreUtc = false)
1722
+ {
1723
+ if (isset($this->cal['VCALENDAR']['X-WR-TIMEZONE'])) {
1724
+ $timeZone = $this->cal['VCALENDAR']['X-WR-TIMEZONE'];
1725
+ } elseif (isset($this->cal['VTIMEZONE']['TZID'])) {
1726
+ $timeZone = $this->cal['VTIMEZONE']['TZID'];
1727
+ } else {
1728
+ $timeZone = $this->defaultTimeZone;
1729
+ }
1730
+
1731
+ // Use default time zone if the calendar's is invalid
1732
+ if ($this->isValidIanaTimeZoneId($timeZone) === false) {
1733
+ // phpcs:ignore CustomPHPCS.ControlStructures.AssignmentInCondition.Warning
1734
+ if (($timeZone = $this->isValidCldrTimeZoneId($timeZone, true)) === false) {
1735
+ $timeZone = $this->defaultTimeZone;
1736
+ }
1737
+ }
1738
+
1739
+ if ($ignoreUtc && strtoupper($timeZone) === self::TIME_ZONE_UTC) {
1740
+ return null;
1741
+ }
1742
+
1743
+ return $timeZone;
1744
+ }
1745
+
1746
+ /**
1747
+ * Returns an array of arrays with all free/busy events.
1748
+ * Every event is an associative array and each property
1749
+ * is an element it.
1750
+ *
1751
+ * @return array
1752
+ */
1753
+ public function freeBusyEvents()
1754
+ {
1755
+ $array = $this->cal;
1756
+
1757
+ return isset($array['VFREEBUSY']) ? $array['VFREEBUSY'] : '';
1758
+ }
1759
+
1760
+ /**
1761
+ * Returns a boolean value whether the
1762
+ * current calendar has events or not
1763
+ *
1764
+ * @return boolean
1765
+ */
1766
+ public function hasEvents()
1767
+ {
1768
+ return (count($this->events()) > 0) ?: false;
1769
+ }
1770
+
1771
+ /**
1772
+ * Returns a sorted array of the events in a given range,
1773
+ * or an empty array if no events exist in the range.
1774
+ *
1775
+ * Events will be returned if the start or end date is contained within the
1776
+ * range (inclusive), or if the event starts before and end after the range.
1777
+ *
1778
+ * If a start date is not specified or of a valid format, then the start
1779
+ * of the range will default to the current time and date of the server.
1780
+ *
1781
+ * If an end date is not specified or of a valid format, then the end of
1782
+ * the range will default to the current time and date of the server,
1783
+ * plus 20 years.
1784
+ *
1785
+ * Note that this function makes use of Unix timestamps. This might be a
1786
+ * problem for events on, during, or after 29 Jan 2038.
1787
+ * See https://en.wikipedia.org/wiki/Unix_time#Representing_the_number
1788
+ *
1789
+ * @param string $rangeStart
1790
+ * @param string $rangeEnd
1791
+ * @return array
1792
+ * @throws \Exception
1793
+ */
1794
+ public function eventsFromRange($rangeStart = false, $rangeEnd = false)
1795
+ {
1796
+ // Sort events before processing range
1797
+ $events = $this->sortEventsWithOrder($this->events(), SORT_ASC);
1798
+
1799
+ if (empty($events)) {
1800
+ return array();
1801
+ }
1802
+
1803
+ $extendedEvents = array();
1804
+
1805
+ if ($rangeStart) {
1806
+ try {
1807
+ $rangeStart = new \DateTime($rangeStart, new \DateTimeZone($this->defaultTimeZone));
1808
+ } catch (\Exception $e) {
1809
+ error_log("ICal::eventsFromRange: Invalid date passed ({$rangeStart})");
1810
+ $rangeStart = false;
1811
+ }
1812
+ } else {
1813
+ $rangeStart = new \DateTime('now', new \DateTimeZone($this->defaultTimeZone));
1814
+ }
1815
+
1816
+ if ($rangeEnd) {
1817
+ try {
1818
+ $rangeEnd = new \DateTime($rangeEnd, new \DateTimeZone($this->defaultTimeZone));
1819
+ } catch (\Exception $e) {
1820
+ error_log("ICal::eventsFromRange: Invalid date passed ({$rangeEnd})");
1821
+ $rangeEnd = false;
1822
+ }
1823
+ } else {
1824
+ $rangeEnd = new \DateTime('now', new \DateTimeZone($this->defaultTimeZone));
1825
+ $rangeEnd->modify('+20 years');
1826
+ }
1827
+
1828
+ // If start and end are identical and are dates with no times...
1829
+ if ($rangeEnd->format('His') == 0 && $rangeStart->getTimestamp() == $rangeEnd->getTimestamp()) {
1830
+ $rangeEnd->modify('+1 day');
1831
+ }
1832
+
1833
+ $rangeStart = $rangeStart->getTimestamp();
1834
+ $rangeEnd = $rangeEnd->getTimestamp();
1835
+
1836
+ foreach ($events as $anEvent) {
1837
+ $eventStart = $anEvent->dtstart_array[2];
1838
+ $eventEnd = (isset($anEvent->dtend_array[2])) ? $anEvent->dtend_array[2] : null;
1839
+
1840
+ if (($eventStart >= $rangeStart && $eventStart < $rangeEnd) // Event start date contained in the range
1841
+ || ($eventEnd !== null
1842
+ && (
1843
+ ($eventEnd > $rangeStart && $eventEnd <= $rangeEnd) // Event end date contained in the range
1844
+ || ($eventStart < $rangeStart && $eventEnd > $rangeEnd) // Event starts before and finishes after range
1845
+ )
1846
+ )
1847
+ ) {
1848
+ $extendedEvents[] = $anEvent;
1849
+ }
1850
+ }
1851
+
1852
+ if (empty($extendedEvents)) {
1853
+ return array();
1854
+ }
1855
+
1856
+ return $extendedEvents;
1857
+ }
1858
+
1859
+ /**
1860
+ * Returns a sorted array of the events following a given string,
1861
+ * or `false` if no events exist in the range.
1862
+ *
1863
+ * @param string $interval
1864
+ * @return array
1865
+ */
1866
+ public function eventsFromInterval($interval)
1867
+ {
1868
+ $rangeStart = new \DateTime('now', new \DateTimeZone($this->defaultTimeZone));
1869
+ $rangeEnd = new \DateTime('now', new \DateTimeZone($this->defaultTimeZone));
1870
+
1871
+ $dateInterval = \DateInterval::createFromDateString($interval);
1872
+ $rangeEnd->add($dateInterval);
1873
+
1874
+ return $this->eventsFromRange($rangeStart->format('Y-m-d'), $rangeEnd->format('Y-m-d'));
1875
+ }
1876
+
1877
+ /**
1878
+ * Sorts events based on a given sort order
1879
+ *
1880
+ * @param array $events
1881
+ * @param integer $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
1882
+ * @return array
1883
+ */
1884
+ public function sortEventsWithOrder(array $events, $sortOrder = SORT_ASC)
1885
+ {
1886
+ $extendedEvents = array();
1887
+ $timestamp = array();
1888
+
1889
+ foreach ($events as $key => $anEvent) {
1890
+ $extendedEvents[] = $anEvent;
1891
+ $timestamp[$key] = $anEvent->dtstart_array[2];
1892
+ }
1893
+
1894
+ array_multisort($timestamp, $sortOrder, $extendedEvents);
1895
+
1896
+ return $extendedEvents;
1897
+ }
1898
+
1899
+ /**
1900
+ * Checks if a time zone is valid (IANA or CLDR)
1901
+ *
1902
+ * @param string $timeZone
1903
+ * @return boolean
1904
+ */
1905
+ protected function isValidTimeZoneId($timeZone)
1906
+ {
1907
+ return ($this->isValidIanaTimeZoneId($timeZone) !== false || $this->isValidCldrTimeZoneId($timeZone) !== false);
1908
+ }
1909
+
1910
+ /**
1911
+ * Checks if a time zone is a valid IANA time zone
1912
+ *
1913
+ * @param string $timeZone
1914
+ * @return boolean
1915
+ */
1916
+ protected function isValidIanaTimeZoneId($timeZone)
1917
+ {
1918
+ if (in_array($timeZone, $this->validTimeZones)) {
1919
+ return true;
1920
+ }
1921
+
1922
+ $valid = array();
1923
+ $tza = timezone_abbreviations_list();
1924
+
1925
+ foreach ($tza as $zone) {
1926
+ foreach ($zone as $item) {
1927
+ $valid[$item['timezone_id']] = true;
1928
+ }
1929
+ }
1930
+
1931
+ unset($valid['']);
1932
+
1933
+ if (isset($valid[$timeZone]) || in_array($timeZone, timezone_identifiers_list(\DateTimeZone::ALL_WITH_BC))) {
1934
+ $this->validTimeZones[] = $timeZone;
1935
+
1936
+ return true;
1937
+ }
1938
+
1939
+ return false;
1940
+ }
1941
+
1942
+ /**
1943
+ * Checks if a time zone is a valid CLDR time zone
1944
+ *
1945
+ * @param string $timeZone
1946
+ * @param boolean $doConversion
1947
+ * @return boolean|string
1948
+ */
1949
+ public function isValidCldrTimeZoneId($timeZone, $doConversion = false)
1950
+ {
1951
+ $timeZone = html_entity_decode($timeZone);
1952
+
1953
+ $cldrTimeZones = array(
1954
+ '(UTC-12:00) International Date Line West' => 'Etc/GMT+12',
1955
+ '(UTC-11:00) Coordinated Universal Time-11' => 'Etc/GMT+11',
1956
+ '(UTC-10:00) Hawaii' => 'Pacific/Honolulu',
1957
+ '(UTC-09:00) Alaska' => 'America/Anchorage',
1958
+ '(UTC-08:00) Pacific Time (US & Canada)' => 'America/Los_Angeles',
1959
+ '(UTC-07:00) Arizona' => 'America/Phoenix',
1960
+ '(UTC-07:00) Chihuahua, La Paz, Mazatlan' => 'America/Chihuahua',
1961
+ '(UTC-07:00) Mountain Time (US & Canada)' => 'America/Denver',
1962
+ '(UTC-06:00) Central America' => 'America/Guatemala',
1963
+ '(UTC-06:00) Central Time (US & Canada)' => 'America/Chicago',
1964
+ '(UTC-06:00) Guadalajara, Mexico City, Monterrey' => 'America/Mexico_City',
1965
+ '(UTC-06:00) Saskatchewan' => 'America/Regina',
1966
+ '(UTC-05:00) Bogota, Lima, Quito, Rio Branco' => 'America/Bogota',
1967
+ '(UTC-05:00) Chetumal' => 'America/Cancun',
1968
+ '(UTC-05:00) Eastern Time (US & Canada)' => 'America/New_York',
1969
+ '(UTC-05:00) Indiana (East)' => 'America/Indianapolis',
1970
+ '(UTC-04:00) Asuncion' => 'America/Asuncion',
1971
+ '(UTC-04:00) Atlantic Time (Canada)' => 'America/Halifax',
1972
+ '(UTC-04:00) Caracas' => 'America/Caracas',
1973
+ '(UTC-04:00) Cuiaba' => 'America/Cuiaba',
1974
+ '(UTC-04:00) Georgetown, La Paz, Manaus, San Juan' => 'America/La_Paz',
1975
+ '(UTC-04:00) Santiago' => 'America/Santiago',
1976
+ '(UTC-03:30) Newfoundland' => 'America/St_Johns',
1977
+ '(UTC-03:00) Brasilia' => 'America/Sao_Paulo',
1978
+ '(UTC-03:00) Cayenne, Fortaleza' => 'America/Cayenne',
1979
+ '(UTC-03:00) City of Buenos Aires' => 'America/Buenos_Aires',
1980
+ '(UTC-03:00) Greenland' => 'America/Godthab',
1981
+ '(UTC-03:00) Montevideo' => 'America/Montevideo',
1982
+ '(UTC-03:00) Salvador' => 'America/Bahia',
1983
+ '(UTC-02:00) Coordinated Universal Time-02' => 'Etc/GMT+2',
1984
+ '(UTC-01:00) Azores' => 'Atlantic/Azores',
1985
+ '(UTC-01:00) Cabo Verde Is.' => 'Atlantic/Cape_Verde',
1986
+ '(UTC) Coordinated Universal Time' => 'Etc/GMT',
1987
+ '(UTC+00:00) Casablanca' => 'Africa/Casablanca',
1988
+ '(UTC+00:00) Dublin, Edinburgh, Lisbon, London' => 'Europe/London',
1989
+ '(UTC+00:00) Monrovia, Reykjavik' => 'Atlantic/Reykjavik',
1990
+ '(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
1991
+ '(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague' => 'Europe/Budapest',
1992
+ '(UTC+01:00) Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
1993
+ '(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb' => 'Europe/Warsaw',
1994
+ '(UTC+01:00) West Central Africa' => 'Africa/Lagos',
1995
+ '(UTC+02:00) Amman' => 'Asia/Amman',
1996
+ '(UTC+02:00) Athens, Bucharest' => 'Europe/Bucharest',
1997
+ '(UTC+02:00) Beirut' => 'Asia/Beirut',
1998
+ '(UTC+02:00) Cairo' => 'Africa/Cairo',
1999
+ '(UTC+02:00) Chisinau' => 'Europe/Chisinau',
2000
+ '(UTC+02:00) Damascus' => 'Asia/Damascus',
2001
+ '(UTC+02:00) Harare, Pretoria' => 'Africa/Johannesburg',
2002
+ '(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius' => 'Europe/Kiev',
2003
+ '(UTC+02:00) Jerusalem' => 'Asia/Jerusalem',
2004
+ '(UTC+02:00) Kaliningrad' => 'Europe/Kaliningrad',
2005
+ '(UTC+02:00) Tripoli' => 'Africa/Tripoli',
2006
+ '(UTC+02:00) Windhoek' => 'Africa/Windhoek',
2007
+ '(UTC+03:00) Baghdad' => 'Asia/Baghdad',
2008
+ '(UTC+03:00) Istanbul' => 'Europe/Istanbul',
2009
+ '(UTC+03:00) Kuwait, Riyadh' => 'Asia/Riyadh',
2010
+ '(UTC+03:00) Minsk' => 'Europe/Minsk',
2011
+ '(UTC+03:00) Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
2012
+ '(UTC+03:00) Nairobi' => 'Africa/Nairobi',
2013
+ '(UTC+03:30) Tehran' => 'Asia/Tehran',
2014
+ '(UTC+04:00) Abu Dhabi, Muscat' => 'Asia/Dubai',
2015
+ '(UTC+04:00) Baku' => 'Asia/Baku',
2016
+ '(UTC+04:00) Izhevsk, Samara' => 'Europe/Samara',
2017
+ '(UTC+04:00) Port Louis' => 'Indian/Mauritius',
2018
+ '(UTC+04:00) Tbilisi' => 'Asia/Tbilisi',
2019
+ '(UTC+04:00) Yerevan' => 'Asia/Yerevan',
2020
+ '(UTC+04:30) Kabul' => 'Asia/Kabul',
2021
+ '(UTC+05:00) Ashgabat, Tashkent' => 'Asia/Tashkent',
2022
+ '(UTC+05:00) Ekaterinburg' => 'Asia/Yekaterinburg',
2023
+ '(UTC+05:00) Islamabad, Karachi' => 'Asia/Karachi',
2024
+ '(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi' => 'Asia/Calcutta',
2025
+ '(UTC+05:30) Sri Jayawardenepura' => 'Asia/Colombo',
2026
+ '(UTC+05:45) Kathmandu' => 'Asia/Katmandu',
2027
+ '(UTC+06:00) Astana' => 'Asia/Almaty',
2028
+ '(UTC+06:00) Dhaka' => 'Asia/Dhaka',
2029
+ '(UTC+06:30) Yangon (Rangoon)' => 'Asia/Rangoon',
2030
+ '(UTC+07:00) Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
2031
+ '(UTC+07:00) Krasnoyarsk' => 'Asia/Krasnoyarsk',
2032
+ '(UTC+07:00) Novosibirsk' => 'Asia/Novosibirsk',
2033
+ '(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi' => 'Asia/Shanghai',
2034
+ '(UTC+08:00) Irkutsk' => 'Asia/Irkutsk',
2035
+ '(UTC+08:00) Kuala Lumpur, Singapore' => 'Asia/Singapore',
2036
+ '(UTC+08:00) Perth' => 'Australia/Perth',
2037
+ '(UTC+08:00) Taipei' => 'Asia/Taipei',
2038
+ '(UTC+08:00) Ulaanbaatar' => 'Asia/Ulaanbaatar',
2039
+ '(UTC+09:00) Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
2040
+ '(UTC+09:00) Pyongyang' => 'Asia/Pyongyang',
2041
+ '(UTC+09:00) Seoul' => 'Asia/Seoul',
2042
+ '(UTC+09:00) Yakutsk' => 'Asia/Yakutsk',
2043
+ '(UTC+09:30) Adelaide' => 'Australia/Adelaide',
2044
+ '(UTC+09:30) Darwin' => 'Australia/Darwin',
2045
+ '(UTC+10:00) Brisbane' => 'Australia/Brisbane',
2046
+ '(UTC+10:00) Canberra, Melbourne, Sydney' => 'Australia/Sydney',
2047
+ '(UTC+10:00) Guam, Port Moresby' => 'Pacific/Port_Moresby',
2048
+ '(UTC+10:00) Hobart' => 'Australia/Hobart',
2049
+ '(UTC+10:00) Vladivostok' => 'Asia/Vladivostok',
2050
+ '(UTC+11:00) Chokurdakh' => 'Asia/Srednekolymsk',
2051
+ '(UTC+11:00) Magadan' => 'Asia/Magadan',
2052
+ '(UTC+11:00) Solomon Is., New Caledonia' => 'Pacific/Guadalcanal',
2053
+ '(UTC+12:00) Anadyr, Petropavlovsk-Kamchatsky' => 'Asia/Kamchatka',
2054
+ '(UTC+12:00) Auckland, Wellington' => 'Pacific/Auckland',
2055
+ '(UTC+12:00) Coordinated Universal Time+12' => 'Etc/GMT-12',
2056
+ '(UTC+12:00) Fiji' => 'Pacific/Fiji',
2057
+ "(UTC+13:00) Nuku'alofa" => 'Pacific/Tongatapu',
2058
+ '(UTC+13:00) Samoa' => 'Pacific/Apia',
2059
+ '(UTC+14:00) Kiritimati Island' => 'Pacific/Kiritimati',
2060
+ );
2061
+
2062
+ if (array_key_exists($timeZone, $cldrTimeZones)) {
2063
+ if ($doConversion) {
2064
+ return $cldrTimeZones[$timeZone];
2065
+ } else {
2066
+ return true;
2067
+ }
2068
+ }
2069
+
2070
+ return false;
2071
+ }
2072
+
2073
+ /**
2074
+ * Parses a duration and applies it to a date
2075
+ *
2076
+ * @param string $date
2077
+ * @param string $duration
2078
+ * @param string $format
2079
+ * @return integer|DateTime
2080
+ */
2081
+ protected function parseDuration($date, $duration, $format = self::UNIX_FORMAT)
2082
+ {
2083
+ $dateTime = date_create($date);
2084
+ $dateTime->modify($duration->y . ' year');
2085
+ $dateTime->modify($duration->m . ' month');
2086
+ $dateTime->modify($duration->d . ' day');
2087
+ $dateTime->modify($duration->h . ' hour');
2088
+ $dateTime->modify($duration->i . ' minute');
2089
+ $dateTime->modify($duration->s . ' second');
2090
+
2091
+ if (is_null($format)) {
2092
+ $output = $dateTime;
2093
+ } else {
2094
+ if ($format === self::UNIX_FORMAT) {
2095
+ $output = $dateTime->getTimestamp();
2096
+ } else {
2097
+ $output = $dateTime->format($format);
2098
+ }
2099
+ }
2100
+
2101
+ return $output;
2102
+ }
2103
+
2104
+ /**
2105
+ * Gets the number of days between a start and end date
2106
+ *
2107
+ * @param integer $days
2108
+ * @param integer $start
2109
+ * @param integer $end
2110
+ * @return integer
2111
+ */
2112
+ protected function numberOfDays($days, $start, $end)
2113
+ {
2114
+ $w = array(date('w', $start), date('w', $end));
2115
+ $oneWeek = self::SECONDS_IN_A_WEEK;
2116
+ $x = floor(($end - $start) / $oneWeek);
2117
+ $sum = 0;
2118
+
2119
+ for ($day = 0; $day < 7; ++$day) {
2120
+ if ($days & pow(2, $day)) {
2121
+ $sum += $x + (($w[0] > $w[1]) ? $w[0] <= $day || $day <= $w[1] : $w[0] <= $day && $day <= $w[1]);
2122
+ }
2123
+ }
2124
+
2125
+ return $sum;
2126
+ }
2127
+
2128
+ /**
2129
+ * Converts a negative day ordinal to
2130
+ * its equivalent positive form
2131
+ *
2132
+ * @param integer $dayNumber
2133
+ * @param integer $weekday
2134
+ * @param integer $timestamp
2135
+ * @return string
2136
+ */
2137
+ protected function convertDayOrdinalToPositive($dayNumber, $weekday, $timestamp)
2138
+ {
2139
+ $dayNumber = empty($dayNumber) ? 1 : $dayNumber; // Returns 0 when no number defined in BYDAY
2140
+
2141
+ $dayOrdinals = $this->dayOrdinals;
2142
+
2143
+ // We only care about negative BYDAY values
2144
+ if ($dayNumber >= 1) {
2145
+ return $dayOrdinals[$dayNumber];
2146
+ }
2147
+
2148
+ $timestamp = (is_object($timestamp)) ? $timestamp : \DateTime::createFromFormat(self::UNIX_FORMAT, $timestamp);
2149
+ $start = strtotime('first day of ' . $timestamp->format(self::DATE_TIME_FORMAT_PRETTY));
2150
+ $end = strtotime('last day of ' . $timestamp->format(self::DATE_TIME_FORMAT_PRETTY));
2151
+
2152
+ // Used with pow(2, X) so pow(2, 4) is THURSDAY
2153
+ $weekdays = array_flip(array_keys($this->weekdays));
2154
+
2155
+ $numberOfDays = $this->numberOfDays(pow(2, $weekdays[$weekday]), $start, $end);
2156
+
2157
+ // Create subset
2158
+ $dayOrdinals = array_slice($dayOrdinals, 0, $numberOfDays, true);
2159
+
2160
+ // Reverse only the values
2161
+ $dayOrdinals = array_combine(array_keys($dayOrdinals), array_reverse(array_values($dayOrdinals)));
2162
+
2163
+ return $dayOrdinals[$dayNumber * -1];
2164
+ }
2165
+
2166
+ /**
2167
+ * Removes unprintable ASCII and UTF-8 characters
2168
+ *
2169
+ * @param string $data
2170
+ * @return string
2171
+ */
2172
+ protected function removeUnprintableChars($data)
2173
+ {
2174
+ return preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $data);
2175
+ }
2176
+
2177
+ /**
2178
+ * Provides a polyfill for PHP 7.2's `mb_chr()`, which is a multibyte safe version of `chr()`.
2179
+ * Multibyte safe.
2180
+ *
2181
+ * @param integer $code
2182
+ * @return string
2183
+ */
2184
+ protected function mb_chr($code)
2185
+ {
2186
+ if (function_exists('mb_chr')) {
2187
+ return mb_chr($code);
2188
+ } else {
2189
+ if (0x80 > $code %= 0x200000) {
2190
+ $s = chr($code);
2191
+ } elseif (0x800 > $code) {
2192
+ $s = chr(0xc0 | $code >> 6) . chr(0x80 | $code & 0x3f);
2193
+ } elseif (0x10000 > $code) {
2194
+ $s = chr(0xe0 | $code >> 12) . chr(0x80 | $code >> 6 & 0x3f) . chr(0x80 | $code & 0x3f);
2195
+ } else {
2196
+ $s = chr(0xf0 | $code >> 18) . chr(0x80 | $code >> 12 & 0x3f) . chr(0x80 | $code >> 6 & 0x3f) . chr(0x80 | $code & 0x3f);
2197
+ }
2198
+
2199
+ return $s;
2200
+ }
2201
+ }
2202
+
2203
+ /**
2204
+ * Replaces all occurrences of a search string with a given replacement string.
2205
+ * Multibyte safe.
2206
+ *
2207
+ * @param string|array $search
2208
+ * @param string|array $replace
2209
+ * @param string|array $subject
2210
+ * @param integer $count
2211
+ * @return array|string
2212
+ */
2213
+ protected function mb_str_replace($search, $replace, $subject, &$count = 0)
2214
+ {
2215
+ if (!is_array($subject)) {
2216
+ // Normalize `$search` and `$replace` so they are both arrays of the same length
2217
+ $searches = is_array($search) ? array_values($search) : array($search);
2218
+ $replacements = is_array($replace) ? array_values($replace) : array($replace);
2219
+ $replacements = array_pad($replacements, count($searches), '');
2220
+
2221
+ foreach ($searches as $key => $search) {
2222
+ $parts = mb_split(preg_quote($search), $subject);
2223
+ $count += count($parts) - 1;
2224
+ $subject = implode($replacements[$key], $parts);
2225
+ }
2226
+ } else {
2227
+ // Call `mb_str_replace` for each subject in array, recursively
2228
+ foreach ($subject as $key => $value) {
2229
+ $subject[$key] = $this->mb_str_replace($search, $replace, $value, $count);
2230
+ }
2231
+ }
2232
+
2233
+ return $subject;
2234
+ }
2235
+
2236
+ /**
2237
+ * Replaces curly quotes and other special characters
2238
+ * with their standard equivalents
2239
+ *
2240
+ * @param string $data
2241
+ * @return string
2242
+ */
2243
+ protected function cleanData($data)
2244
+ {
2245
+ $replacementChars = array(
2246
+ "\xe2\x80\x98" => "'", // ‘
2247
+ "\xe2\x80\x99" => "'", // ’
2248
+ "\xe2\x80\x9a" => "'", // ‚
2249
+ "\xe2\x80\x9b" => "'", // ‛
2250
+ "\xe2\x80\x9c" => '"', // “
2251
+ "\xe2\x80\x9d" => '"', // ”
2252
+ "\xe2\x80\x9e" => '"', // „
2253
+ "\xe2\x80\x9f" => '"', // ‟
2254
+ "\xe2\x80\x93" => '-', // –
2255
+ "\xe2\x80\x94" => '--', // —
2256
+ "\xe2\x80\xa6" => '...', // …
2257
+ "\xc2\xa0" => ' ',
2258
+ );
2259
+ // Replace UTF-8 characters
2260
+ $cleanedData = strtr($data, $replacementChars);
2261
+
2262
+ // Replace Windows-1252 equivalents
2263
+ $charsToReplace = array_map(function ($code) {
2264
+ return $this->mb_chr($code);
2265
+ }, array(133, 145, 146, 147, 148, 150, 151, 194));
2266
+ $cleanedData = $this->mb_str_replace($charsToReplace, $replacementChars, $cleanedData);
2267
+
2268
+ return $cleanedData;
2269
+ }
2270
+
2271
+ /**
2272
+ * Parses a list of excluded dates
2273
+ * to be applied to an Event
2274
+ *
2275
+ * @param array $event
2276
+ * @return array
2277
+ */
2278
+ public function parseExdates(array $event)
2279
+ {
2280
+ if (empty($event['EXDATE_array'])) {
2281
+ return array();
2282
+ } else {
2283
+ $exdates = $event['EXDATE_array'];
2284
+ }
2285
+
2286
+ $output = array();
2287
+ $currentTimeZone = $this->defaultTimeZone;
2288
+
2289
+ foreach ($exdates as $subArray) {
2290
+ end($subArray);
2291
+ $finalKey = key($subArray);
2292
+
2293
+ foreach ($subArray as $key => $value) {
2294
+ if ($key === 'TZID') {
2295
+ $checkTimeZone = $subArray[$key];
2296
+
2297
+ if ($this->isValidIanaTimeZoneId($checkTimeZone)) {
2298
+ $currentTimeZone = $checkTimeZone;
2299
+ } elseif ($this->isValidCldrTimeZoneId($checkTimeZone)) {
2300
+ $currentTimeZone = $this->isValidCldrTimeZoneId($checkTimeZone, true);
2301
+ } else {
2302
+ $currentTimeZone = $this->defaultTimeZone;
2303
+ }
2304
+ } elseif (is_numeric($key)) {
2305
+ $icalDate = $subArray[$key];
2306
+
2307
+ if (substr($icalDate, -1) === 'Z') {
2308
+ $currentTimeZone = self::TIME_ZONE_UTC;
2309
+ }
2310
+
2311
+ $output[] = new Carbon($icalDate, $currentTimeZone);
2312
+
2313
+ if ($key === $finalKey) {
2314
+ // Reset to default
2315
+ $currentTimeZone = $this->defaultTimeZone;
2316
+ }
2317
+ }
2318
+ }
2319
+ }
2320
+
2321
+ return $output;
2322
+ }
2323
+
2324
+ /**
2325
+ * Checks if a date string is a valid date
2326
+ *
2327
+ * @param string $value
2328
+ * @return boolean
2329
+ * @throws \Exception
2330
+ */
2331
+ public function isValidDate($value)
2332
+ {
2333
+ if (!$value) {
2334
+ return false;
2335
+ }
2336
+
2337
+ try {
2338
+ new \DateTime($value);
2339
+
2340
+ return true;
2341
+ } catch (\Exception $e) {
2342
+ return false;
2343
+ }
2344
+ }
2345
+
2346
+ /**
2347
+ * Checks if a filename exists as a file or URL
2348
+ *
2349
+ * @param string $filename
2350
+ * @return boolean
2351
+ */
2352
+ protected function isFileOrUrl($filename)
2353
+ {
2354
+ return (file_exists($filename) || filter_var($filename, FILTER_VALIDATE_URL)) ?: false;
2355
+ }
2356
+
2357
+ /**
2358
+ * Reads an entire file or URL into an array
2359
+ *
2360
+ * @param string $filename
2361
+ * @return array
2362
+ * @throws \Exception
2363
+ */
2364
+ protected function fileOrUrl($filename)
2365
+ {
2366
+ if (!$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)) {
2367
+ throw new \Exception("The file path or URL '{$filename}' does not exist.");
2368
+ }
2369
+
2370
+ return $lines;
2371
+ }
2372
+
2373
+ /**
2374
+ * Ensures the recurrence count is enforced against generated recurrence events.
2375
+ *
2376
+ * @param array $rrules
2377
+ * @param array $recurrenceEvents
2378
+ * @return array
2379
+ */
2380
+ protected function trimToRecurrenceCount(array $rrules, array $recurrenceEvents)
2381
+ {
2382
+ if (isset($rrules['COUNT'])) {
2383
+ $recurrenceCount = (intval($rrules['COUNT']) - 1);
2384
+ $surplusCount = (sizeof($recurrenceEvents) - $recurrenceCount);
2385
+
2386
+ if ($surplusCount > 0) {
2387
+ $recurrenceEvents = array_slice($recurrenceEvents, 0, $recurrenceCount);
2388
+ $this->eventCount -= $surplusCount;
2389
+ }
2390
+ }
2391
+
2392
+ return $recurrenceEvents;
2393
+ }
2394
+
2395
+ /**
2396
+ * Checks if an excluded date matches a given date by reconciling time zones.
2397
+ *
2398
+ * @param integer $exdate
2399
+ * @param array $anEvent
2400
+ * @param integer $recurringOffset
2401
+ * @return boolean
2402
+ */
2403
+ protected function isExdateMatch($exdate, array $anEvent, $recurringOffset)
2404
+ {
2405
+ $searchDate = $anEvent['DTSTART'];
2406
+
2407
+ if (substr($searchDate, -1) === 'Z') {
2408
+ $timeZone = self::TIME_ZONE_UTC;
2409
+ } else {
2410
+ if (isset($anEvent['DTSTART_array'][0]['TZID'])) {
2411
+ $checkTimeZone = $anEvent['DTSTART_array'][0]['TZID'];
2412
+
2413
+ if ($this->isValidIanaTimeZoneId($checkTimeZone)) {
2414
+ $timeZone = $checkTimeZone;
2415
+ } elseif ($this->isValidCldrTimeZoneId($checkTimeZone)) {
2416
+ $timeZone = $this->isValidCldrTimeZoneId($checkTimeZone, true);
2417
+ } else {
2418
+ $timeZone = $this->defaultTimeZone;
2419
+ }
2420
+ } else {
2421
+ $timeZone = $this->defaultTimeZone;
2422
+ }
2423
+ }
2424
+
2425
+ $a = new Carbon($searchDate, $timeZone);
2426
+ $b = $exdate->addSeconds($recurringOffset);
2427
+
2428
+ return $a->eq($b);
2429
+ }
2430
+ }
app/vendor/nesbot/carbon/.php_cs.dist ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use PhpCsFixer\Config;
4
+ use PhpCsFixer\Finder;
5
+
6
+ $rules = array(
7
+ '@PSR2' => true,
8
+ 'array_syntax' => array(
9
+ 'syntax' => 'long',
10
+ ),
11
+ 'binary_operator_spaces' => array(
12
+ 'align_double_arrow' => false,
13
+ 'align_equals' => false,
14
+ ),
15
+ 'blank_line_before_return' => true,
16
+ 'cast_spaces' => true,
17
+ 'concat_space' => array(
18
+ 'spacing' => 'none',
19
+ ),
20
+ 'ereg_to_preg' => true,
21
+ 'method_separation' => true,
22
+ 'no_blank_lines_after_phpdoc' => true,
23
+ 'no_extra_consecutive_blank_lines' => true,
24
+ 'no_short_bool_cast' => true,
25
+ 'no_unneeded_control_parentheses' => true,
26
+ 'no_unused_imports' => true,
27
+ 'no_whitespace_in_blank_line' => true,
28
+ 'ordered_imports' => true,
29
+ 'phpdoc_align' => true,
30
+ 'phpdoc_indent' => true,
31
+ 'phpdoc_inline_tag' => true,
32
+ 'phpdoc_no_access' => true,
33
+ 'phpdoc_no_alias_tag' => array(
34
+ 'type' => 'var',
35
+ ),
36
+ 'phpdoc_no_package' => true,
37
+ 'phpdoc_order' => true,
38
+ 'phpdoc_scalar' => true,
39
+ 'phpdoc_separation' => true,
40
+ 'phpdoc_to_comment' => true,
41
+ 'phpdoc_trim' => true,
42
+ 'phpdoc_types' => true,
43
+ 'phpdoc_var_without_name' => true,
44
+ 'self_accessor' => true,
45
+ 'single_quote' => true,
46
+ 'space_after_semicolon' => true,
47
+ 'standardize_not_equals' => true,
48
+ 'ternary_operator_spaces' => true,
49
+ 'trailing_comma_in_multiline_array' => true,
50
+ 'trim_array_spaces' => true,
51
+ 'unary_operator_spaces' => true,
52
+ 'line_ending' => true,
53
+ 'blank_line_after_namespace' => true,
54
+ 'no_unused_imports' => true,
55
+ );
56
+
57
+ return Config::create()->setRules($rules)
58
+ ->setFinder(Finder::create()->in(__DIR__))
59
+ ->setUsingCache(true)
60
+ ->setRiskyAllowed(true);
app/vendor/nesbot/carbon/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (C) Brian Nesbitt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
app/vendor/nesbot/carbon/build.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ chdir(__DIR__);
4
+ $currentBranch = 'master';
5
+ if (preg_match('/On branch ([^\n]+)\n/', shell_exec('git status'), $match)) {
6
+ $currentBranch = $match[1];
7
+ }
8
+ shell_exec('git fetch --all --tags --prune');
9
+ $remotes = explode("\n", trim(shell_exec('git remote')));
10
+ $tagsCommand = count($remotes)
11
+ ? 'git ls-remote --tags '.(in_array('upstream', $remotes) ? 'upstream' : (in_array('origin', $remotes) ? 'origin' : $remotes[0]))
12
+ : 'git tag';
13
+ $tags = array_map(function ($ref) {
14
+ $ref = explode('refs/tags/', $ref);
15
+
16
+ return isset($ref[1]) ? $ref[1] : $ref[0];
17
+ }, array_filter(explode("\n", trim(shell_exec($tagsCommand))), function ($ref) {
18
+ return substr($ref, -3) !== '^{}';
19
+ }));
20
+ usort($tags, 'version_compare');
21
+
22
+ $tag = isset($argv[1]) && !in_array($argv[1], array('last', 'latest')) ? $argv[1] : end($tags);
23
+
24
+ if (strtolower($tag) !== 'all') {
25
+ if (!in_array($tag, $tags)) {
26
+ echo "Tag must be one of remote tags available:\n";
27
+ foreach ($tags as $_tag) {
28
+ echo " - $_tag\n";
29
+ }
30
+ echo "\"$tag\" does not match.\n";
31
+
32
+ exit(1);
33
+ }
34
+
35
+ $tags = array($tag);
36
+ }
37
+
38
+ foreach ($tags as $tag) {
39
+ $archive = "Carbon-$tag.zip";
40
+ if (isset($argv[2]) && $argv[2] === 'missing' && file_exists($archive)) {
41
+ continue;
42
+ }
43
+
44
+ $branch = "build-$tag";
45
+ shell_exec('git stash');
46
+ shell_exec("git branch -d $branch");
47
+ shell_exec("git checkout tags/$tag -b $branch");
48
+ shell_exec('composer config platform.php 5.3.9');
49
+ shell_exec('composer update --no-interaction --no-dev --optimize-autoloader');
50
+ $zip = new ZipArchive();
51
+
52
+ $zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
53
+
54
+ foreach (array('src', 'vendor', 'Carbon') as $directory) {
55
+ if (is_dir($directory)) {
56
+ $directory = realpath($directory);
57
+ $base = dirname($directory);
58
+
59
+ $files = new RecursiveIteratorIterator(
60
+ new RecursiveDirectoryIterator($directory),
61
+ RecursiveIteratorIterator::LEAVES_ONLY
62
+ );
63
+
64
+ foreach ($files as $name => $file) {
65
+ if (!$file->isDir()) {
66
+ $filePath = $file->getRealPath();
67
+
68
+ $zip->addFile($filePath, substr($filePath, strlen($base) + 1));
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ $autoload = 'autoload.php';
75
+ file_put_contents($autoload, "<?php\n\n/**\n * @version $tag\n */\n\nrequire __DIR__.'/vendor/autoload.php';\n");
76
+ $zip->addFile($autoload, $autoload);
77
+ $zip->close();
78
+ unlink($autoload);
79
+
80
+ shell_exec('git checkout .');
81
+ shell_exec("git checkout $currentBranch");
82
+ shell_exec("git branch -d $branch");
83
+ shell_exec('git stash pop');
84
+ shell_exec('composer update --no-interaction');
85
+ }
86
+
87
+ exit(0);
app/vendor/nesbot/carbon/composer.json ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "nesbot/carbon",
3
+ "type": "library",
4
+ "description": "A simple API extension for DateTime.",
5
+ "keywords": [
6
+ "date",
7
+ "time",
8
+ "DateTime"
9
+ ],
10
+ "homepage": "http://carbon.nesbot.com",
11
+ "support": {
12
+ "issues": "https://github.com/briannesbitt/Carbon/issues",
13
+ "source": "https://github.com/briannesbitt/Carbon"
14
+ },
15
+ "license": "MIT",
16
+ "authors": [
17
+ {
18
+ "name": "Brian Nesbitt",
19
+ "email": "brian@nesbot.com",
20
+ "homepage": "http://nesbot.com"
21
+ }
22
+ ],
23
+ "require": {
24
+ "php": ">=5.3.9",
25
+ "symfony/translation": "~2.6 || ~3.0 || ~4.0"
26
+ },
27
+ "require-dev": {
28
+ "friendsofphp/php-cs-fixer": "~2",
29
+ "phpunit/phpunit": "^4.8.35 || ^5.7"
30
+ },
31
+ "autoload": {
32
+ "psr-4": {
33
+ "": "src/"
34
+ }
35
+ },
36
+ "autoload-dev": {
37
+ "psr-4": {
38
+ "Tests\\": "tests/"
39
+ }
40
+ },
41
+ "config": {
42
+ "sort-packages": true
43
+ },
44
+ "scripts": {
45
+ "test": [
46
+ "@phpunit",
47
+ "@phpcs"
48
+ ],
49
+ "phpunit": "phpunit --verbose --coverage-clover=coverage.xml",
50
+ "phpcs": "php-cs-fixer fix -v --diff --dry-run",
51
+ "phpstan": "phpstan analyse --configuration phpstan.neon --level 3 src tests"
52
+ }
53
+ }
app/vendor/nesbot/carbon/readme.md ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Carbon
2
+
3
+ [![Latest Stable Version](https://poser.pugx.org/nesbot/carbon/v/stable.png)](https://packagist.org/packages/nesbot/carbon)
4
+ [![Total Downloads](https://poser.pugx.org/nesbot/carbon/downloads.png)](https://packagist.org/packages/nesbot/carbon)
5
+ [![Build Status](https://travis-ci.org/briannesbitt/Carbon.svg?branch=master)](https://travis-ci.org/briannesbitt/Carbon)
6
+ [![StyleCI](https://styleci.io/repos/5724990/shield?style=flat)](https://styleci.io/repos/5724990)
7
+ [![codecov.io](https://codecov.io/github/briannesbitt/Carbon/coverage.svg?branch=master)](https://codecov.io/github/briannesbitt/Carbon?branch=master)
8
+ [![PHP-Eye](https://php-eye.com/badge/nesbot/carbon/tested.svg?style=flat)](https://php-eye.com/package/nesbot/carbon)
9
+ [![PHPStan](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat)](https://github.com/phpstan/phpstan)
10
+
11
+ A simple PHP API extension for DateTime. [http://carbon.nesbot.com](http://carbon.nesbot.com)
12
+
13
+ ```php
14
+ use Carbon\Carbon;
15
+
16
+ printf("Right now is %s", Carbon::now()->toDateTimeString());
17
+ printf("Right now in Vancouver is %s", Carbon::now('America/Vancouver')); //implicit __toString()
18
+ $tomorrow = Carbon::now()->addDay();
19
+ $lastWeek = Carbon::now()->subWeek();
20
+ $nextSummerOlympics = Carbon::createFromDate(2016)->addYears(4);
21
+
22
+ $officialDate = Carbon::now()->toRfc2822String();
23
+
24
+ $howOldAmI = Carbon::createFromDate(1975, 5, 21)->age;
25
+
26
+ $noonTodayLondonTime = Carbon::createFromTime(12, 0, 0, 'Europe/London');
27
+
28
+ $internetWillBlowUpOn = Carbon::create(2038, 01, 19, 3, 14, 7, 'GMT');
29
+
30
+ // Don't really want this to happen so mock now
31
+ Carbon::setTestNow(Carbon::createFromDate(2000, 1, 1));
32
+
33
+ // comparisons are always done in UTC
34
+ if (Carbon::now()->gte($internetWillBlowUpOn)) {
35
+ die();
36
+ }
37
+
38
+ // Phew! Return to normal behaviour
39
+ Carbon::setTestNow();
40
+
41
+ if (Carbon::now()->isWeekend()) {
42
+ echo 'Party!';
43
+ }
44
+ echo Carbon::now()->subMinutes(2)->diffForHumans(); // '2 minutes ago'
45
+
46
+ // ... but also does 'from now', 'after' and 'before'
47
+ // rolling up to seconds, minutes, hours, days, months, years
48
+
49
+ $daysSinceEpoch = Carbon::createFromTimestamp(0)->diffInDays();
50
+ ```
51
+
52
+ ## Installation
53
+
54
+ ### With Composer
55
+
56
+ ```
57
+ $ composer require nesbot/carbon
58
+ ```
59
+
60
+ ```json
61
+ {
62
+ "require": {
63
+ "nesbot/carbon": "~1.21"
64
+ }
65
+ }
66
+ ```
67
+
68
+ ```php
69
+ <?php
70
+ require 'vendor/autoload.php';
71
+
72
+ use Carbon\Carbon;
73
+
74
+ printf("Now: %s", Carbon::now());
75
+ ```
76
+
77
+ <a name="install-nocomposer"/>
78
+
79
+ ### Without Composer
80
+
81
+ Why are you not using [composer](http://getcomposer.org/)? Download [Carbon.php](https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php) from the repo and save the file into your project path somewhere.
82
+
83
+ ```php
84
+ <?php
85
+ require 'path/to/Carbon.php';
86
+
87
+ use Carbon\Carbon;
88
+
89
+ printf("Now: %s", Carbon::now());
90
+ ```
91
+
92
+ ## Docs
93
+
94
+ [http://carbon.nesbot.com/docs](http://carbon.nesbot.com/docs)
app/vendor/nesbot/carbon/src/Carbon/Carbon.php ADDED
@@ -0,0 +1,4665 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Carbon;
13
+
14
+ use Carbon\Exceptions\InvalidDateException;
15
+ use Closure;
16
+ use DatePeriod;
17
+ use DateTime;
18
+ use DateTimeInterface;
19
+ use DateTimeZone;
20
+ use InvalidArgumentException;
21
+ use JsonSerializable;
22
+ use Symfony\Component\Translation\TranslatorInterface;
23
+
24
+ /**
25
+ * A simple API extension for DateTime
26
+ *
27
+ * @property int $year
28
+ * @property int $yearIso
29
+ * @property int $month
30
+ * @property int $day
31
+ * @property int $hour
32
+ * @property int $minute
33
+ * @property int $second
34
+ * @property int $timestamp seconds since the Unix Epoch
35
+ * @property \DateTimeZone $timezone the current timezone
36
+ * @property \DateTimeZone $tz alias of timezone
37
+ * @property-read int $micro
38
+ * @property-read int $dayOfWeek 0 (for Sunday) through 6 (for Saturday)
39
+ * @property-read int $dayOfWeekIso 1 (for Monday) through 7 (for Sunday)
40
+ * @property-read int $dayOfYear 0 through 365
41
+ * @property-read int $weekOfMonth 1 through 5
42
+ * @property-read int $weekNumberInMonth 1 through 5
43
+ * @property-read int $weekOfYear ISO-8601 week number of year, weeks starting on Monday
44
+ * @property-read int $daysInMonth number of days in the given month
45
+ * @property-read int $age does a diffInYears() with default parameters
46
+ * @property-read int $quarter the quarter of this instance, 1 - 4
47
+ * @property-read int $offset the timezone offset in seconds from UTC
48
+ * @property-read int $offsetHours the timezone offset in hours from UTC
49
+ * @property-read bool $dst daylight savings time indicator, true if DST, false otherwise
50
+ * @property-read bool $local checks if the timezone is local, true if local, false otherwise
51
+ * @property-read bool $utc checks if the timezone is UTC, true if UTC, false otherwise
52
+ * @property-read string $timezoneName
53
+ * @property-read string $tzName
54
+ * @property-read string $englishDayOfWeek the day of week in English
55
+ * @property-read string $shortEnglishDayOfWeek the abbreviated day of week in English
56
+ * @property-read string $englishMonth the day of week in English
57
+ * @property-read string $shortEnglishMonth the abbreviated day of week in English
58
+ * @property-read string $localeDayOfWeek the day of week in current locale LC_TIME
59
+ * @property-read string $shortLocaleDayOfWeek the abbreviated day of week in current locale LC_TIME
60
+ * @property-read string $localeMonth the month in current locale LC_TIME
61
+ * @property-read string $shortLocaleMonth the abbreviated month in current locale LC_TIME
62
+ */
63
+ class Carbon extends DateTime implements JsonSerializable
64
+ {
65
+ const NO_ZERO_DIFF = 01;
66
+ const JUST_NOW = 02;
67
+ const ONE_DAY_WORDS = 04;
68
+ const TWO_DAY_WORDS = 010;
69
+
70
+ /**
71
+ * The day constants.
72
+ */
73
+ const SUNDAY = 0;
74
+ const MONDAY = 1;
75
+ const TUESDAY = 2;
76
+ const WEDNESDAY = 3;
77
+ const THURSDAY = 4;
78
+ const FRIDAY = 5;
79
+ const SATURDAY = 6;
80
+
81
+ /**
82
+ * Names of days of the week.
83
+ *
84
+ * @var array
85
+ */
86
+ protected static $days = array(
87
+ self::SUNDAY => 'Sunday',
88
+ self::MONDAY => 'Monday',
89
+ self::TUESDAY => 'Tuesday',
90
+ self::WEDNESDAY => 'Wednesday',
91
+ self::THURSDAY => 'Thursday',
92
+ self::FRIDAY => 'Friday',
93
+ self::SATURDAY => 'Saturday',
94
+ );
95
+
96
+ /**
97
+ * Number of X in Y.
98
+ */
99
+ const YEARS_PER_CENTURY = 100;
100
+ const YEARS_PER_DECADE = 10;
101
+ const MONTHS_PER_YEAR = 12;
102
+ const MONTHS_PER_QUARTER = 3;
103
+ const WEEKS_PER_YEAR = 52;
104
+ const WEEKS_PER_MONTH = 4;
105
+ const DAYS_PER_WEEK = 7;
106
+ const HOURS_PER_DAY = 24;
107
+ const MINUTES_PER_HOUR = 60;
108
+ const SECONDS_PER_MINUTE = 60;
109
+
110
+ /**
111
+ * RFC7231 DateTime format.
112
+ *
113
+ * @var string
114
+ */
115
+ const RFC7231_FORMAT = 'D, d M Y H:i:s \G\M\T';
116
+
117
+ /**
118
+ * Default format to use for __toString method when type juggling occurs.
119
+ *
120
+ * @var string
121
+ */
122
+ const DEFAULT_TO_STRING_FORMAT = 'Y-m-d H:i:s';
123
+
124
+ /**
125
+ * Format for converting mocked time, includes microseconds.
126
+ *
127
+ * @var string
128
+ */
129
+ const MOCK_DATETIME_FORMAT = 'Y-m-d H:i:s.u';
130
+
131
+ /**
132
+ * Customizable PHP_INT_SIZE override.
133
+ *
134
+ * @var int
135
+ */
136
+ public static $PHPIntSize = PHP_INT_SIZE;
137
+
138
+ /**
139
+ * Format to use for __toString method when type juggling occurs.
140
+ *
141
+ * @var string
142
+ */
143
+ protected static $toStringFormat = self::DEFAULT_TO_STRING_FORMAT;
144
+
145
+ /**
146
+ * First day of week.
147
+ *
148
+ * @var int
149
+ */
150
+ protected static $weekStartsAt = self::MONDAY;
151
+
152
+ /**
153
+ * Last day of week.
154
+ *
155
+ * @var int
156
+ */
157
+ protected static $weekEndsAt = self::SUNDAY;
158
+
159
+ /**
160
+ * Days of weekend.
161
+ *
162
+ * @var array
163
+ */
164
+ protected static $weekendDays = array(
165
+ self::SATURDAY,
166
+ self::SUNDAY,
167
+ );
168
+
169
+ /**
170
+ * Midday/noon hour.
171
+ *
172
+ * @var int
173
+ */
174
+ protected static $midDayAt = 12;
175
+
176
+ /**
177
+ * Format regex patterns.
178
+ *
179
+ * @var array
180
+ */
181
+ protected static $regexFormats = array(
182
+ 'd' => '(3[01]|[12][0-9]|0[1-9])',
183
+ 'D' => '([a-zA-Z]{3})',
184
+ 'j' => '([123][0-9]|[1-9])',
185
+ 'l' => '([a-zA-Z]{2,})',
186
+ 'N' => '([1-7])',
187
+ 'S' => '([a-zA-Z]{2})',
188
+ 'w' => '([0-6])',
189
+ 'z' => '(36[0-5]|3[0-5][0-9]|[12][0-9]{2}|[1-9]?[0-9])',
190
+ 'W' => '(5[012]|[1-4][0-9]|[1-9])',
191
+ 'F' => '([a-zA-Z]{2,})',
192
+ 'm' => '(1[012]|0[1-9])',
193
+ 'M' => '([a-zA-Z]{3})',
194
+ 'n' => '(1[012]|[1-9])',
195
+ 't' => '(2[89]|3[01])',
196
+ 'L' => '(0|1)',
197
+ 'o' => '([1-9][0-9]{0,4})',
198
+ 'Y' => '([1-9][0-9]{0,4})',
199
+ 'y' => '([0-9]{2})',
200
+ 'a' => '(am|pm)',
201
+ 'A' => '(AM|PM)',
202
+ 'B' => '([0-9]{3})',
203
+ 'g' => '(1[012]|[1-9])',
204
+ 'G' => '(2[0-3]|1?[0-9])',
205
+ 'h' => '(1[012]|0[1-9])',
206
+ 'H' => '(2[0-3]|[01][0-9])',
207
+ 'i' => '([0-5][0-9])',
208
+ 's' => '([0-5][0-9])',
209
+ 'u' => '([0-9]{1,6})',
210
+ 'v' => '([0-9]{1,3})',
211
+ 'e' => '([a-zA-Z]{1,5})|([a-zA-Z]*\/[a-zA-Z]*)',
212
+ 'I' => '(0|1)',
213
+ 'O' => '([\+\-](1[012]|0[0-9])[0134][05])',
214
+ 'P' => '([\+\-](1[012]|0[0-9]):[0134][05])',
215
+ 'T' => '([a-zA-Z]{1,5})',
216
+ 'Z' => '(-?[1-5]?[0-9]{1,4})',
217
+ 'U' => '([0-9]*)',
218
+
219
+ // The formats below are combinations of the above formats.
220
+ 'c' => '(([1-9][0-9]{0,4})\-(1[012]|0[1-9])\-(3[01]|[12][0-9]|0[1-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])[\+\-](1[012]|0[0-9]):([0134][05]))', // Y-m-dTH:i:sP
221
+ 'r' => '(([a-zA-Z]{3}), ([123][0-9]|[1-9]) ([a-zA-Z]{3}) ([1-9][0-9]{0,4}) (2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]) [\+\-](1[012]|0[0-9])([0134][05]))', // D, j M Y H:i:s O
222
+ );
223
+
224
+ /**
225
+ * A test Carbon instance to be returned when now instances are created.
226
+ *
227
+ * @var \Carbon\Carbon
228
+ */
229
+ protected static $testNow;
230
+
231
+ /**
232
+ * A translator to ... er ... translate stuff.
233
+ *
234
+ * @var \Symfony\Component\Translation\TranslatorInterface
235
+ */
236
+ protected static $translator;
237
+
238
+ /**
239
+ * The errors that can occur.
240
+ *
241
+ * @var array
242
+ */
243
+ protected static $lastErrors;
244
+
245
+ /**
246
+ * The custom Carbon JSON serializer.
247
+ *
248
+ * @var callable|null
249
+ */
250
+ protected static $serializer;
251
+
252
+ /**
253
+ * The registered string macros.
254
+ *
255
+ * @var array
256
+ */
257
+ protected static $localMacros = array();
258
+
259
+ /**
260
+ * Will UTF8 encoding be used to print localized date/time ?
261
+ *
262
+ * @var bool
263
+ */
264
+ protected static $utf8 = false;
265
+
266
+ /**
267
+ * Add microseconds to now on PHP < 7.1 and 7.1.3. true by default.
268
+ *
269
+ * @var bool
270
+ */
271
+ protected static $microsecondsFallback = true;
272
+
273
+ /**
274
+ * Indicates if months should be calculated with overflow.
275
+ *
276
+ * @var bool
277
+ */
278
+ protected static $monthsOverflow = true;
279
+
280
+ /**
281
+ * Indicates if years should be calculated with overflow.
282
+ *
283
+ * @var bool
284
+ */
285
+ protected static $yearsOverflow = true;
286
+
287
+ /**
288
+ * Indicates if years are compared with month by default so isSameMonth and isSameQuarter have $ofSameYear set
289
+ * to true by default.
290
+ *
291
+ * @var bool
292
+ */
293
+ protected static $compareYearWithMonth = false;
294
+
295
+ /**
296
+ * Options for diffForHumans().
297
+ *
298
+ * @var int
299
+ */
300
+ protected static $humanDiffOptions = self::NO_ZERO_DIFF;
301
+
302
+ /**
303
+ * @param int $humanDiffOptions
304
+ */
305
+ public static function setHumanDiffOptions($humanDiffOptions)
306
+ {
307
+ static::$humanDiffOptions = $humanDiffOptions;
308
+ }
309
+
310
+ /**
311
+ * @param int $humanDiffOption
312
+ */
313
+ public static function enableHumanDiffOption($humanDiffOption)
314
+ {
315
+ static::$humanDiffOptions = static::getHumanDiffOptions() | $humanDiffOption;
316
+ }
317
+
318
+ /**
319
+ * @param int $humanDiffOption
320
+ */
321
+ public static function disableHumanDiffOption($humanDiffOption)
322
+ {
323
+ static::$humanDiffOptions = static::getHumanDiffOptions() & ~$humanDiffOption;
324
+ }
325
+
326
+ /**
327
+ * @return int
328
+ */
329
+ public static function getHumanDiffOptions()
330
+ {
331
+ return static::$humanDiffOptions;
332
+ }
333
+
334
+ /**
335
+ * Add microseconds to now on PHP < 7.1 and 7.1.3 if set to true,
336
+ * let microseconds to 0 on those PHP versions if false.
337
+ *
338
+ * @param bool $microsecondsFallback
339
+ */
340
+ public static function useMicrosecondsFallback($microsecondsFallback = true)
341
+ {
342
+ static::$microsecondsFallback = $microsecondsFallback;
343
+ }
344
+
345
+ /**
346
+ * Return true if microseconds fallback on PHP < 7.1 and 7.1.3 is
347
+ * enabled. false if disabled.
348
+ *
349
+ * @return bool
350
+ */
351
+ public static function isMicrosecondsFallbackEnabled()
352
+ {
353
+ return static::$microsecondsFallback;
354
+ }
355
+
356
+ /**
357
+ * Indicates if months should be calculated with overflow.
358
+ *
359
+ * @param bool $monthsOverflow
360
+ *
361
+ * @return void
362
+ */
363
+ public static function useMonthsOverflow($monthsOverflow = true)
364
+ {
365
+ static::$monthsOverflow = $monthsOverflow;
366
+ }
367
+
368
+ /**
369
+ * Reset the month overflow behavior.
370
+ *
371
+ * @return void
372
+ */
373
+ public static function resetMonthsOverflow()
374
+ {
375
+ static::$monthsOverflow = true;
376
+ }
377
+
378
+ /**
379
+ * Get the month overflow behavior.
380
+ *
381
+ * @return bool
382
+ */
383
+ public static function shouldOverflowMonths()
384
+ {
385
+ return static::$monthsOverflow;
386
+ }
387
+
388
+ /**
389
+ * Indicates if years should be calculated with overflow.
390
+ *
391
+ * @param bool $yearsOverflow
392
+ *
393
+ * @return void
394
+ */
395
+ public static function useYearsOverflow($yearsOverflow = true)
396
+ {
397
+ static::$yearsOverflow = $yearsOverflow;
398
+ }
399
+
400
+ /**
401
+ * Reset the month overflow behavior.
402
+ *
403
+ * @return void
404
+ */
405
+ public static function resetYearsOverflow()
406
+ {
407
+ static::$yearsOverflow = true;
408
+ }
409
+
410
+ /**
411
+ * Get the month overflow behavior.
412
+ *
413
+ * @return bool
414
+ */
415
+ public static function shouldOverflowYears()
416
+ {
417
+ return static::$yearsOverflow;
418
+ }
419
+
420
+ /**
421
+ * Get the month comparison default behavior.
422
+ *
423
+ * @return bool
424
+ */
425
+ public static function compareYearWithMonth($compareYearWithMonth = true)
426
+ {
427
+ static::$compareYearWithMonth = $compareYearWithMonth;
428
+ }
429
+
430
+ /**
431
+ * Get the month comparison default behavior.
432
+ *
433
+ * @return bool
434
+ */
435
+ public static function shouldCompareYearWithMonth()
436
+ {
437
+ return static::$compareYearWithMonth;
438
+ }
439
+
440
+ /**
441
+ * Creates a DateTimeZone from a string, DateTimeZone or integer offset.
442
+ *
443
+ * @param \DateTimeZone|string|int|null $object
444
+ *
445
+ * @throws \InvalidArgumentException
446
+ *
447
+ * @return \DateTimeZone
448
+ */
449
+ protected static function safeCreateDateTimeZone($object)
450
+ {
451
+ if ($object === null) {
452
+ // Don't return null... avoid Bug #52063 in PHP <5.3.6
453
+ return new DateTimeZone(date_default_timezone_get());
454
+ }
455
+
456
+ if ($object instanceof DateTimeZone) {
457
+ return $object;
458
+ }
459
+
460
+ if (is_numeric($object)) {
461
+ $tzName = timezone_name_from_abbr(null, $object * 3600, true);
462
+
463
+ if ($tzName === false) {
464
+ throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
465
+ }
466
+
467
+ $object = $tzName;
468
+ }
469
+
470
+ $tz = @timezone_open($object = (string) $object);
471
+
472
+ if ($tz !== false) {
473
+ return $tz;
474
+ }
475
+
476
+ // Work-around for a bug fixed in PHP 5.5.10 https://bugs.php.net/bug.php?id=45528
477
+ // See: https://stackoverflow.com/q/14068594/2646927
478
+ // @codeCoverageIgnoreStart
479
+ if (strpos($object, ':') !== false) {
480
+ try {
481
+ return static::createFromFormat('O', $object)->getTimezone();
482
+ } catch (InvalidArgumentException $e) {
483
+ //
484
+ }
485
+ }
486
+ // @codeCoverageIgnoreEnd
487
+
488
+ throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
489
+ }
490
+
491
+ ///////////////////////////////////////////////////////////////////
492
+ //////////////////////////// CONSTRUCTORS /////////////////////////
493
+ ///////////////////////////////////////////////////////////////////
494
+
495
+ /**
496
+ * Create a new Carbon instance.
497
+ *
498
+ * Please see the testing aids section (specifically static::setTestNow())
499
+ * for more on the possibility of this constructor returning a test instance.
500
+ *
501
+ * @param string|null $time
502
+ * @param \DateTimeZone|string|null $tz
503
+ */
504
+ public function __construct($time = null, $tz = null)
505
+ {
506
+ // If the class has a test now set and we are trying to create a now()
507
+ // instance then override as required
508
+ $isNow = empty($time) || $time === 'now';
509
+ if (static::hasTestNow() && ($isNow || static::hasRelativeKeywords($time))) {
510
+ $testInstance = clone static::getTestNow();
511
+
512
+ //shift the time according to the given time zone
513
+ if ($tz !== null && $tz !== static::getTestNow()->getTimezone()) {
514
+ $testInstance->setTimezone($tz);
515
+ } else {
516
+ $tz = $testInstance->getTimezone();
517
+ }
518
+
519
+ if (static::hasRelativeKeywords($time)) {
520
+ $testInstance->modify($time);
521
+ }
522
+
523
+ $time = $testInstance->format(static::MOCK_DATETIME_FORMAT);
524
+ }
525
+
526
+ $timezone = static::safeCreateDateTimeZone($tz);
527
+ // @codeCoverageIgnoreStart
528
+ if ($isNow && !isset($testInstance) && static::isMicrosecondsFallbackEnabled() && (
529
+ version_compare(PHP_VERSION, '7.1.0-dev', '<')
530
+ ||
531
+ version_compare(PHP_VERSION, '7.1.3-dev', '>=') && version_compare(PHP_VERSION, '7.1.4-dev', '<')
532
+ )
533
+ ) {
534
+ // Get microseconds from microtime() if "now" asked and PHP < 7.1 and PHP 7.1.3 if fallback enabled.
535
+ list($microTime, $timeStamp) = explode(' ', microtime());
536
+ $dateTime = new DateTime('now', $timezone);
537
+ $dateTime->setTimestamp($timeStamp); // Use the timestamp returned by microtime as now can happen in the next second
538
+ $time = $dateTime->format(static::DEFAULT_TO_STRING_FORMAT).substr($microTime, 1, 7);
539
+ }
540
+ // @codeCoverageIgnoreEnd
541
+
542
+ // Work-around for PHP bug https://bugs.php.net/bug.php?id=67127
543
+ if (strpos((string) .1, '.') === false) {
544
+ $locale = setlocale(LC_NUMERIC, '0');
545
+ setlocale(LC_NUMERIC, 'C');
546
+ }
547
+ parent::__construct($time, $timezone);
548
+ if (isset($locale)) {
549
+ setlocale(LC_NUMERIC, $locale);
550
+ }
551
+ static::setLastErrors(parent::getLastErrors());
552
+ }
553
+
554
+ /**
555
+ * Create a Carbon instance from a DateTime one.
556
+ *
557
+ * @param \DateTime|\DateTimeInterface $date
558
+ *
559
+ * @return static
560
+ */
561
+ public static function instance($date)
562
+ {
563
+ if ($date instanceof static) {
564
+ return clone $date;
565
+ }
566
+
567
+ static::expectDateTime($date);
568
+
569
+ return new static($date->format('Y-m-d H:i:s.u'), $date->getTimezone());
570
+ }
571
+
572
+ /**
573
+ * Create a carbon instance from a string.
574
+ *
575
+ * This is an alias for the constructor that allows better fluent syntax
576
+ * as it allows you to do Carbon::parse('Monday next week')->fn() rather
577
+ * than (new Carbon('Monday next week'))->fn().
578
+ *
579
+ * @param string|null $time
580
+ * @param \DateTimeZone|string|null $tz
581
+ *
582
+ * @return static
583
+ */
584
+ public static function parse($time = null, $tz = null)
585
+ {
586
+ return new static($time, $tz);
587
+ }
588
+
589
+ /**
590
+ * Get a Carbon instance for the current date and time.
591
+ *
592
+ * @param \DateTimeZone|string|null $tz
593
+ *
594
+ * @return static
595
+ */
596
+ public static function now($tz = null)
597
+ {
598
+ return new static(null, $tz);
599
+ }
600
+
601
+ /**
602
+ * Create a Carbon instance for today.
603
+ *
604
+ * @param \DateTimeZone|string|null $tz
605
+ *
606
+ * @return static
607
+ */
608
+ public static function today($tz = null)
609
+ {
610
+ return static::parse('today', $tz);
611
+ }
612
+
613
+ /**
614
+ * Create a Carbon instance for tomorrow.
615
+ *
616
+ * @param \DateTimeZone|string|null $tz
617
+ *
618
+ * @return static
619
+ */
620
+ public static function tomorrow($tz = null)
621
+ {
622
+ return static::parse('tomorrow', $tz);
623
+ }
624
+
625
+ /**
626
+ * Create a Carbon instance for yesterday.
627
+ *
628
+ * @param \DateTimeZone|string|null $tz
629
+ *
630
+ * @return static
631
+ */
632
+ public static function yesterday($tz = null)
633
+ {
634
+ return static::parse('yesterday', $tz);
635
+ }
636
+
637
+ /**
638
+ * Create a Carbon instance for the greatest supported date.
639
+ *
640
+ * @return static
641
+ */
642
+ public static function maxValue()
643
+ {
644
+ if (self::$PHPIntSize === 4) {
645
+ // 32 bit
646
+ return static::createFromTimestamp(PHP_INT_MAX); // @codeCoverageIgnore
647
+ }
648
+
649
+ // 64 bit
650
+ return static::create(9999, 12, 31, 23, 59, 59);
651
+ }
652
+
653
+ /**
654
+ * Create a Carbon instance for the lowest supported date.
655
+ *
656
+ * @return static
657
+ */
658
+ public static function minValue()
659
+ {
660
+ if (self::$PHPIntSize === 4) {
661
+ // 32 bit
662
+ return static::createFromTimestamp(~PHP_INT_MAX); // @codeCoverageIgnore
663
+ }
664
+
665
+ // 64 bit
666
+ return static::create(1, 1, 1, 0, 0, 0);
667
+ }
668
+
669
+ /**
670
+ * Create a new Carbon instance from a specific date and time.
671
+ *
672
+ * If any of $year, $month or $day are set to null their now() values will
673
+ * be used.
674
+ *
675
+ * If $hour is null it will be set to its now() value and the default
676
+ * values for $minute and $second will be their now() values.
677
+ *
678
+ * If $hour is not null then the default values for $minute and $second
679
+ * will be 0.
680
+ *
681
+ * @param int|null $year
682
+ * @param int|null $month
683
+ * @param int|null $day
684
+ * @param int|null $hour
685
+ * @param int|null $minute
686
+ * @param int|null $second
687
+ * @param \DateTimeZone|string|null $tz
688
+ *
689
+ * @throws \InvalidArgumentException
690
+ *
691
+ * @return static
692
+ */
693
+ public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
694
+ {
695
+ $now = static::hasTestNow() ? static::getTestNow() : static::now($tz);
696
+
697
+ $defaults = array_combine(array(
698
+ 'year',
699
+ 'month',
700
+ 'day',
701
+ 'hour',
702
+ 'minute',
703
+ 'second',
704
+ ), explode('-', $now->format('Y-n-j-G-i-s')));
705
+
706
+ $year = $year === null ? $defaults['year'] : $year;
707
+ $month = $month === null ? $defaults['month'] : $month;
708
+ $day = $day === null ? $defaults['day'] : $day;
709
+
710
+ if ($hour === null) {
711
+ $hour = $defaults['hour'];
712
+ $minute = $minute === null ? $defaults['minute'] : $minute;
713
+ $second = $second === null ? $defaults['second'] : $second;
714
+ } else {
715
+ $minute = $minute === null ? 0 : $minute;
716
+ $second = $second === null ? 0 : $second;
717
+ }
718
+
719
+ $fixYear = null;
720
+
721
+ if ($year < 0) {
722
+ $fixYear = $year;
723
+ $year = 0;
724
+ } elseif ($year > 9999) {
725
+ $fixYear = $year - 9999;
726
+ $year = 9999;
727
+ }
728
+
729
+ $instance = static::createFromFormat('!Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $tz);
730
+
731
+ if ($fixYear !== null) {
732
+ $instance->addYears($fixYear);
733
+ }
734
+
735
+ return $instance;
736
+ }
737
+
738
+ /**
739
+ * Create a new safe Carbon instance from a specific date and time.
740
+ *
741
+ * If any of $year, $month or $day are set to null their now() values will
742
+ * be used.
743
+ *
744
+ * If $hour is null it will be set to its now() value and the default
745
+ * values for $minute and $second will be their now() values.
746
+ *
747
+ * If $hour is not null then the default values for $minute and $second
748
+ * will be 0.
749
+ *
750
+ * If one of the set values is not valid, an \InvalidArgumentException
751
+ * will be thrown.
752
+ *
753
+ * @param int|null $year
754
+ * @param int|null $month
755
+ * @param int|null $day
756
+ * @param int|null $hour
757
+ * @param int|null $minute
758
+ * @param int|null $second
759
+ * @param \DateTimeZone|string|null $tz
760
+ *
761
+ * @throws \Carbon\Exceptions\InvalidDateException|\InvalidArgumentException
762
+ *
763
+ * @return static
764
+ */
765
+ public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
766
+ {
767
+ $fields = array(
768
+ 'year' => array(0, 9999),
769
+ 'month' => array(0, 12),
770
+ 'day' => array(0, 31),
771
+ 'hour' => array(0, 24),
772
+ 'minute' => array(0, 59),
773
+ 'second' => array(0, 59),
774
+ );
775
+
776
+ foreach ($fields as $field => $range) {
777
+ if ($$field !== null && (!is_int($$field) || $$field < $range[0] || $$field > $range[1])) {
778
+ throw new InvalidDateException($field, $$field);
779
+ }
780
+ }
781
+
782
+ $instance = static::create($year, $month, $day, $hour, $minute, $second, $tz);
783
+
784
+ foreach (array_reverse($fields) as $field => $range) {
785
+ if ($$field !== null && (!is_int($$field) || $$field !== $instance->$field)) {
786
+ throw new InvalidDateException($field, $$field);
787
+ }
788
+ }
789
+
790
+ return $instance;
791
+ }
792
+
793
+ /**
794
+ * Create a Carbon instance from just a date. The time portion is set to now.
795
+ *
796
+ * @param int|null $year
797
+ * @param int|null $month
798
+ * @param int|null $day
799
+ * @param \DateTimeZone|string|null $tz
800
+ *
801
+ * @throws \InvalidArgumentException
802
+ *
803
+ * @return static
804
+ */
805
+ public static function createFromDate($year = null, $month = null, $day = null, $tz = null)
806
+ {
807
+ return static::create($year, $month, $day, null, null, null, $tz);
808
+ }
809
+
810
+ /**
811
+ * Create a Carbon instance from just a date. The time portion is set to midnight.
812
+ *
813
+ * @param int|null $year
814
+ * @param int|null $month
815
+ * @param int|null $day
816
+ * @param \DateTimeZone|string|null $tz
817
+ *
818
+ * @return static
819
+ */
820
+ public static function createMidnightDate($year = null, $month = null, $day = null, $tz = null)
821
+ {
822
+ return static::create($year, $month, $day, 0, 0, 0, $tz);
823
+ }
824
+
825
+ /**
826
+ * Create a Carbon instance from just a time. The date portion is set to today.
827
+ *
828
+ * @param int|null $hour
829
+ * @param int|null $minute
830
+ * @param int|null $second
831
+ * @param \DateTimeZone|string|null $tz
832
+ *
833
+ * @throws \InvalidArgumentException
834
+ *
835
+ * @return static
836
+ */
837
+ public static function createFromTime($hour = null, $minute = null, $second = null, $tz = null)
838
+ {
839
+ return static::create(null, null, null, $hour, $minute, $second, $tz);
840
+ }
841
+
842
+ /**
843
+ * Create a Carbon instance from a time string. The date portion is set to today.
844
+ *
845
+ * @param string $time
846
+ * @param \DateTimeZone|string|null $tz
847
+ *
848
+ * @throws \InvalidArgumentException
849
+ *
850
+ * @return static
851
+ */
852
+ public static function createFromTimeString($time, $tz = null)
853
+ {
854
+ return static::today($tz)->setTimeFromTimeString($time);
855
+ }
856
+
857
+ private static function createFromFormatAndTimezone($format, $time, $tz)
858
+ {
859
+ return $tz !== null
860
+ ? parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz))
861
+ : parent::createFromFormat($format, $time);
862
+ }
863
+
864
+ /**
865
+ * Create a Carbon instance from a specific format.
866
+ *
867
+ * @param string $format Datetime format
868
+ * @param string $time
869
+ * @param \DateTimeZone|string|null $tz
870
+ *
871
+ * @throws InvalidArgumentException
872
+ *
873
+ * @return static
874
+ */
875
+ public static function createFromFormat($format, $time, $tz = null)
876
+ {
877
+ // First attempt to create an instance, so that error messages are based on the unmodified format.
878
+ $date = self::createFromFormatAndTimezone($format, $time, $tz);
879
+ $lastErrors = parent::getLastErrors();
880
+
881
+ if (($mock = static::getTestNow()) && ($date instanceof DateTime || $date instanceof DateTimeInterface)) {
882
+ // Set timezone from mock if custom timezone was neither given directly nor as a part of format.
883
+ // First let's skip the part that will be ignored by the parser.
884
+ $nonEscaped = '(?<!\\\\)(\\\\{2})*';
885
+
886
+ $nonIgnored = preg_replace("/^.*{$nonEscaped}!/s", '', $format);
887
+
888
+ if ($tz === null && !preg_match("/{$nonEscaped}[eOPT]/", $nonIgnored)) {
889
+ $tz = $mock->getTimezone();
890
+ }
891
+
892
+ // Prepend mock datetime only if the format does not contain non escaped unix epoch reset flag.
893
+ if (!preg_match("/{$nonEscaped}[!|]/", $format)) {
894
+ $format = static::MOCK_DATETIME_FORMAT.' '.$format;
895
+ $time = $mock->format(static::MOCK_DATETIME_FORMAT).' '.$time;
896
+ }
897
+
898
+ // Regenerate date from the modified format to base result on the mocked instance instead of now.
899
+ $date = self::createFromFormatAndTimezone($format, $time, $tz);
900
+ }
901
+
902
+ if ($date instanceof DateTime || $date instanceof DateTimeInterface) {
903
+ $instance = static::instance($date);
904
+ $instance::setLastErrors($lastErrors);
905
+
906
+ return $instance;
907
+ }
908
+
909
+ throw new InvalidArgumentException(implode(PHP_EOL, $lastErrors['errors']));
910
+ }
911
+
912
+ /**
913
+ * Set last errors.
914
+ *
915
+ * @param array $lastErrors
916
+ *
917
+ * @return void
918
+ */
919
+ private static function setLastErrors(array $lastErrors)
920
+ {
921
+ static::$lastErrors = $lastErrors;
922
+ }
923
+
924
+ /**
925
+ * {@inheritdoc}
926
+ */
927
+ public static function getLastErrors()
928
+ {
929
+ return static::$lastErrors;
930
+ }
931
+
932
+ /**
933
+ * Create a Carbon instance from a timestamp.
934
+ *
935
+ * @param int $timestamp
936
+ * @param \DateTimeZone|string|null $tz
937
+ *
938
+ * @return static
939
+ */
940
+ public static function createFromTimestamp($timestamp, $tz = null)
941
+ {
942
+ return static::today($tz)->setTimestamp($timestamp);
943
+ }
944
+
945
+ /**
946
+ * Create a Carbon instance from a timestamp in milliseconds.
947
+ *
948
+ * @param int $timestamp
949
+ * @param \DateTimeZone|string|null $tz
950
+ *
951
+ * @return static
952
+ */
953
+ public static function createFromTimestampMs($timestamp, $tz = null)
954
+ {
955
+ return static::createFromFormat('U.u', sprintf('%F', $timestamp / 1000))
956
+ ->setTimezone($tz);
957
+ }
958
+
959
+ /**
960
+ * Create a Carbon instance from an UTC timestamp.
961
+ *
962
+ * @param int $timestamp
963
+ *
964
+ * @return static
965
+ */
966
+ public static function createFromTimestampUTC($timestamp)
967
+ {
968
+ return new static('@'.$timestamp);
969
+ }
970
+
971
+ /**
972
+ * Make a Carbon instance from given variable if possible.
973
+ *
974
+ * Always return a new instance. Parse only strings and only these likely to be dates (skip intervals
975
+ * and recurrences). Throw an exception for invalid format, but otherwise return null.
976
+ *
977
+ * @param mixed $var
978
+ *
979
+ * @return static|null
980
+ */
981
+ public static function make($var)
982
+ {
983
+ if ($var instanceof DateTime || $var instanceof DateTimeInterface) {
984
+ return static::instance($var);
985
+ }
986
+
987
+ if (is_string($var)) {
988
+ $var = trim($var);
989
+ $first = substr($var, 0, 1);
990
+
991
+ if (is_string($var) && $first !== 'P' && $first !== 'R' && preg_match('/[a-z0-9]/i', $var)) {
992
+ return static::parse($var);
993
+ }
994
+ }
995
+ }
996
+
997
+ /**
998
+ * Get a copy of the instance.
999
+ *
1000
+ * @return static
1001
+ */
1002
+ public function copy()
1003
+ {
1004
+ return clone $this;
1005
+ }
1006
+
1007
+ /**
1008
+ * Returns a present instance in the same timezone.
1009
+ *
1010
+ * @return static
1011
+ */
1012
+ public function nowWithSameTz()
1013
+ {
1014
+ return static::now($this->getTimezone());
1015
+ }
1016
+
1017
+ /**
1018
+ * Throws an exception if the given object is not a DateTime and does not implement DateTimeInterface.
1019
+ *
1020
+ * @param mixed $date
1021
+ *
1022
+ * @throws \InvalidArgumentException
1023
+ */
1024
+ protected static function expectDateTime($date)
1025
+ {
1026
+ if (!$date instanceof DateTime && !$date instanceof DateTimeInterface) {
1027
+ throw new InvalidArgumentException(
1028
+ 'Expected null, string, DateTime or DateTimeInterface, '.
1029
+ (is_object($date) ? get_class($date) : gettype($date)).' given'
1030
+ );
1031
+ }
1032
+ }
1033
+
1034
+ /**
1035
+ * Return the Carbon instance passed through, a now instance in the same timezone
1036
+ * if null given or parse the input if string given.
1037
+ *
1038
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
1039
+ *
1040
+ * @return static
1041
+ */
1042
+ protected function resolveCarbon($date = null)
1043
+ {
1044
+ if (!$date) {
1045
+ return $this->nowWithSameTz();
1046
+ }
1047
+
1048
+ if (is_string($date)) {
1049
+ return static::parse($date, $this->getTimezone());
1050
+ }
1051
+
1052
+ static::expectDateTime($date);
1053
+
1054
+ return $date instanceof self ? $date : static::instance($date);
1055
+ }
1056
+
1057
+ ///////////////////////////////////////////////////////////////////
1058
+ ///////////////////////// GETTERS AND SETTERS /////////////////////
1059
+ ///////////////////////////////////////////////////////////////////
1060
+
1061
+ /**
1062
+ * Get a part of the Carbon object
1063
+ *
1064
+ * @param string $name
1065
+ *
1066
+ * @throws \InvalidArgumentException
1067
+ *
1068
+ * @return string|int|\DateTimeZone
1069
+ */
1070
+ public function __get($name)
1071
+ {
1072
+ static $formats = array(
1073
+ 'year' => 'Y',
1074
+ 'yearIso' => 'o',
1075
+ 'month' => 'n',
1076
+ 'day' => 'j',
1077
+ 'hour' => 'G',
1078
+ 'minute' => 'i',
1079
+ 'second' => 's',
1080
+ 'micro' => 'u',
1081
+ 'dayOfWeek' => 'w',
1082
+ 'dayOfWeekIso' => 'N',
1083
+ 'dayOfYear' => 'z',
1084
+ 'weekOfYear' => 'W',
1085
+ 'daysInMonth' => 't',
1086
+ 'timestamp' => 'U',
1087
+ 'englishDayOfWeek' => 'l',
1088
+ 'shortEnglishDayOfWeek' => 'D',
1089
+ 'englishMonth' => 'F',
1090
+ 'shortEnglishMonth' => 'M',
1091
+ 'localeDayOfWeek' => '%A',
1092
+ 'shortLocaleDayOfWeek' => '%a',
1093
+ 'localeMonth' => '%B',
1094
+ 'shortLocaleMonth' => '%b',
1095
+ );
1096
+
1097
+ switch (true) {
1098
+ case isset($formats[$name]):
1099
+ $format = $formats[$name];
1100
+ $method = substr($format, 0, 1) === '%' ? 'formatLocalized' : 'format';
1101
+ $value = $this->$method($format);
1102
+
1103
+ return is_numeric($value) ? (int) $value : $value;
1104
+
1105
+ case $name === 'weekOfMonth':
1106
+ return (int) ceil($this->day / static::DAYS_PER_WEEK);
1107
+
1108
+ case $name === 'weekNumberInMonth':
1109
+ return (int) ceil(($this->day + $this->copy()->startOfMonth()->dayOfWeek - 1) / static::DAYS_PER_WEEK);
1110
+
1111
+ case $name === 'age':
1112
+ return $this->diffInYears();
1113
+
1114
+ case $name === 'quarter':
1115
+ return (int) ceil($this->month / static::MONTHS_PER_QUARTER);
1116
+
1117
+ case $name === 'offset':
1118
+ return $this->getOffset();
1119
+
1120
+ case $name === 'offsetHours':
1121
+ return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR;
1122
+
1123
+ case $name === 'dst':
1124
+ return $this->format('I') === '1';
1125
+
1126
+ case $name === 'local':
1127
+ return $this->getOffset() === $this->copy()->setTimezone(date_default_timezone_get())->getOffset();
1128
+
1129
+ case $name === 'utc':
1130
+ return $this->getOffset() === 0;
1131
+
1132
+ case $name === 'timezone' || $name === 'tz':
1133
+ return $this->getTimezone();
1134
+
1135
+ case $name === 'timezoneName' || $name === 'tzName':
1136
+ return $this->getTimezone()->getName();
1137
+
1138
+ default:
1139
+ throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
1140
+ }
1141
+ }
1142
+
1143
+ /**
1144
+ * Check if an attribute exists on the object
1145
+ *
1146
+ * @param string $name
1147
+ *
1148
+ * @return bool
1149
+ */
1150
+ public function __isset($name)
1151
+ {
1152
+ try {
1153
+ $this->__get($name);
1154
+ } catch (InvalidArgumentException $e) {
1155
+ return false;
1156
+ }
1157
+
1158
+ return true;
1159
+ }
1160
+
1161
+ /**
1162
+ * Set a part of the Carbon object
1163
+ *
1164
+ * @param string $name
1165
+ * @param string|int|\DateTimeZone $value
1166
+ *
1167
+ * @throws \InvalidArgumentException
1168
+ *
1169
+ * @return void
1170
+ */
1171
+ public function __set($name, $value)
1172
+ {
1173
+ switch ($name) {
1174
+ case 'year':
1175
+ case 'month':
1176
+ case 'day':
1177
+ case 'hour':
1178
+ case 'minute':
1179
+ case 'second':
1180
+ list($year, $month, $day, $hour, $minute, $second) = explode('-', $this->format('Y-n-j-G-i-s'));
1181
+ $$name = $value;
1182
+ $this->setDateTime($year, $month, $day, $hour, $minute, $second);
1183
+ break;
1184
+
1185
+ case 'timestamp':
1186
+ parent::setTimestamp($value);
1187
+ break;
1188
+
1189
+ case 'timezone':
1190
+ case 'tz':
1191
+ $this->setTimezone($value);
1192
+ break;
1193
+
1194
+ default:
1195
+ throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
1196
+ }
1197
+ }
1198
+
1199
+ /**
1200
+ * Set the instance's year
1201
+ *
1202
+ * @param int $value
1203
+ *
1204
+ * @return static
1205
+ */
1206
+ public function year($value)
1207
+ {
1208
+ $this->year = $value;
1209
+
1210
+ return $this;
1211
+ }
1212
+
1213
+ /**
1214
+ * Set the instance's month
1215
+ *
1216
+ * @param int $value
1217
+ *
1218
+ * @return static
1219
+ */
1220
+ public function month($value)
1221
+ {
1222
+ $this->month = $value;
1223
+
1224
+ return $this;
1225
+ }
1226
+
1227
+ /**
1228
+ * Set the instance's day
1229
+ *
1230
+ * @param int $value
1231
+ *
1232
+ * @return static
1233
+ */
1234
+ public function day($value)
1235
+ {
1236
+ $this->day = $value;
1237
+
1238
+ return $this;
1239
+ }
1240
+
1241
+ /**
1242
+ * Set the instance's hour
1243
+ *
1244
+ * @param int $value
1245
+ *
1246
+ * @return static
1247
+ */
1248
+ public function hour($value)
1249
+ {
1250
+ $this->hour = $value;
1251
+
1252
+ return $this;
1253
+ }
1254
+
1255
+ /**
1256
+ * Set the instance's minute
1257
+ *
1258
+ * @param int $value
1259
+ *
1260
+ * @return static
1261
+ */
1262
+ public function minute($value)
1263
+ {
1264
+ $this->minute = $value;
1265
+
1266
+ return $this;
1267
+ }
1268
+
1269
+ /**
1270
+ * Set the instance's second
1271
+ *
1272
+ * @param int $value
1273
+ *
1274
+ * @return static
1275
+ */
1276
+ public function second($value)
1277
+ {
1278
+ $this->second = $value;
1279
+
1280
+ return $this;
1281
+ }
1282
+
1283
+ /**
1284
+ * Sets the current date of the DateTime object to a different date.
1285
+ * Calls modify as a workaround for a php bug
1286
+ *
1287
+ * @param int $year
1288
+ * @param int $month
1289
+ * @param int $day
1290
+ *
1291
+ * @return static
1292
+ *
1293
+ * @see https://github.com/briannesbitt/Carbon/issues/539
1294
+ * @see https://bugs.php.net/bug.php?id=63863
1295
+ */
1296
+ public function setDate($year, $month, $day)
1297
+ {
1298
+ $this->modify('+0 day');
1299
+
1300
+ return parent::setDate($year, $month, $day);
1301
+ }
1302
+
1303
+ /**
1304
+ * Set the date and time all together
1305
+ *
1306
+ * @param int $year
1307
+ * @param int $month
1308
+ * @param int $day
1309
+ * @param int $hour
1310
+ * @param int $minute
1311
+ * @param int $second
1312
+ *
1313
+ * @return static
1314
+ */
1315
+ public function setDateTime($year, $month, $day, $hour, $minute, $second = 0)
1316
+ {
1317
+ return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second);
1318
+ }
1319
+
1320
+ /**
1321
+ * Set the time by time string
1322
+ *
1323
+ * @param string $time
1324
+ *
1325
+ * @return static
1326
+ */
1327
+ public function setTimeFromTimeString($time)
1328
+ {
1329
+ if (strpos($time, ':') === false) {
1330
+ $time .= ':0';
1331
+ }
1332
+
1333
+ return $this->modify($time);
1334
+ }
1335
+
1336
+ /**
1337
+ * Set the instance's timestamp
1338
+ *
1339
+ * @param int $value
1340
+ *
1341
+ * @return static
1342
+ */
1343
+ public function timestamp($value)
1344
+ {
1345
+ return $this->setTimestamp($value);
1346
+ }
1347
+
1348
+ /**
1349
+ * Alias for setTimezone()
1350
+ *
1351
+ * @param \DateTimeZone|string $value
1352
+ *
1353
+ * @return static
1354
+ */
1355
+ public function timezone($value)
1356
+ {
1357
+ return $this->setTimezone($value);
1358
+ }
1359
+
1360
+ /**
1361
+ * Alias for setTimezone()
1362
+ *
1363
+ * @param \DateTimeZone|string $value
1364
+ *
1365
+ * @return static
1366
+ */
1367
+ public function tz($value)
1368
+ {
1369
+ return $this->setTimezone($value);
1370
+ }
1371
+
1372
+ /**
1373
+ * Set the instance's timezone from a string or object
1374
+ *
1375
+ * @param \DateTimeZone|string $value
1376
+ *
1377
+ * @return static
1378
+ */
1379
+ public function setTimezone($value)
1380
+ {
1381
+ parent::setTimezone(static::safeCreateDateTimeZone($value));
1382
+ // https://bugs.php.net/bug.php?id=72338
1383
+ // just workaround on this bug
1384
+ $this->getTimestamp();
1385
+
1386
+ return $this;
1387
+ }
1388
+
1389
+ /**
1390
+ * Set the year, month, and date for this instance to that of the passed instance.
1391
+ *
1392
+ * @param \Carbon\Carbon|\DateTimeInterface $date
1393
+ *
1394
+ * @return static
1395
+ */
1396
+ public function setDateFrom($date)
1397
+ {
1398
+ $date = static::instance($date);
1399
+
1400
+ $this->setDate($date->year, $date->month, $date->day);
1401
+
1402
+ return $this;
1403
+ }
1404
+
1405
+ /**
1406
+ * Set the hour, day, and time for this instance to that of the passed instance.
1407
+ *
1408
+ * @param \Carbon\Carbon|\DateTimeInterface $date
1409
+ *
1410
+ * @return static
1411
+ */
1412
+ public function setTimeFrom($date)
1413
+ {
1414
+ $date = static::instance($date);
1415
+
1416
+ $this->setTime($date->hour, $date->minute, $date->second);
1417
+
1418
+ return $this;
1419
+ }
1420
+
1421
+ /**
1422
+ * Get the days of the week
1423
+ *
1424
+ * @return array
1425
+ */
1426
+ public static function getDays()
1427
+ {
1428
+ return static::$days;
1429
+ }
1430
+
1431
+ ///////////////////////////////////////////////////////////////////
1432
+ /////////////////////// WEEK SPECIAL DAYS /////////////////////////
1433
+ ///////////////////////////////////////////////////////////////////
1434
+
1435
+ /**
1436
+ * Get the first day of week
1437
+ *
1438
+ * @return int
1439
+ */
1440
+ public static function getWeekStartsAt()
1441
+ {
1442
+ return static::$weekStartsAt;
1443
+ }
1444
+
1445
+ /**
1446
+ * Set the first day of week
1447
+ *
1448
+ * @param int $day week start day
1449
+ *
1450
+ * @return void
1451
+ */
1452
+ public static function setWeekStartsAt($day)
1453
+ {
1454
+ static::$weekStartsAt = $day;
1455
+ }
1456
+
1457
+ /**
1458
+ * Get the last day of week
1459
+ *
1460
+ * @return int
1461
+ */
1462
+ public static function getWeekEndsAt()
1463
+ {
1464
+ return static::$weekEndsAt;
1465
+ }
1466
+
1467
+ /**
1468
+ * Set the last day of week
1469
+ *
1470
+ * @param int $day
1471
+ *
1472
+ * @return void
1473
+ */
1474
+ public static function setWeekEndsAt($day)
1475
+ {
1476
+ static::$weekEndsAt = $day;
1477
+ }
1478
+
1479
+ /**
1480
+ * Get weekend days
1481
+ *
1482
+ * @return array
1483
+ */
1484
+ public static function getWeekendDays()
1485
+ {
1486
+ return static::$weekendDays;
1487
+ }
1488
+
1489
+ /**
1490
+ * Set weekend days
1491
+ *
1492
+ * @param array $days
1493
+ *
1494
+ * @return void
1495
+ */
1496
+ public static function setWeekendDays($days)
1497
+ {
1498
+ static::$weekendDays = $days;
1499
+ }
1500
+
1501
+ /**
1502
+ * get midday/noon hour
1503
+ *
1504
+ * @return int
1505
+ */
1506
+ public static function getMidDayAt()
1507
+ {
1508
+ return static::$midDayAt;
1509
+ }
1510
+
1511
+ /**
1512
+ * Set midday/noon hour
1513
+ *
1514
+ * @param int $hour midday hour
1515
+ *
1516
+ * @return void
1517
+ */
1518
+ public static function setMidDayAt($hour)
1519
+ {
1520
+ static::$midDayAt = $hour;
1521
+ }
1522
+
1523
+ ///////////////////////////////////////////////////////////////////
1524
+ ///////////////////////// TESTING AIDS ////////////////////////////
1525
+ ///////////////////////////////////////////////////////////////////
1526
+
1527
+ /**
1528
+ * Set a Carbon instance (real or mock) to be returned when a "now"
1529
+ * instance is created. The provided instance will be returned
1530
+ * specifically under the following conditions:
1531
+ * - A call to the static now() method, ex. Carbon::now()
1532
+ * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
1533
+ * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
1534
+ * - When a string containing the desired time is passed to Carbon::parse().
1535
+ *
1536
+ * Note the timezone parameter was left out of the examples above and
1537
+ * has no affect as the mock value will be returned regardless of its value.
1538
+ *
1539
+ * To clear the test instance call this method using the default
1540
+ * parameter of null.
1541
+ *
1542
+ * @param \Carbon\Carbon|null $testNow real or mock Carbon instance
1543
+ * @param \Carbon\Carbon|string|null $testNow
1544
+ */
1545
+ public static function setTestNow($testNow = null)
1546
+ {
1547
+ static::$testNow = is_string($testNow) ? static::parse($testNow) : $testNow;
1548
+ }
1549
+
1550
+ /**
1551
+ * Get the Carbon instance (real or mock) to be returned when a "now"
1552
+ * instance is created.
1553
+ *
1554
+ * @return static the current instance used for testing
1555
+ */
1556
+ public static function getTestNow()
1557
+ {
1558
+ return static::$testNow;
1559
+ }
1560
+
1561
+ /**
1562
+ * Determine if there is a valid test instance set. A valid test instance
1563
+ * is anything that is not null.
1564
+ *
1565
+ * @return bool true if there is a test instance, otherwise false
1566
+ */
1567
+ public static function hasTestNow()
1568
+ {
1569
+ return static::getTestNow() !== null;
1570
+ }
1571
+
1572
+ /**
1573
+ * Determine if a time string will produce a relative date.
1574
+ *
1575
+ * @param string $time
1576
+ *
1577
+ * @return bool true if time match a relative date, false if absolute or invalid time string
1578
+ */
1579
+ public static function hasRelativeKeywords($time)
1580
+ {
1581
+ if (strtotime($time) === false) {
1582
+ return false;
1583
+ }
1584
+
1585
+ $date1 = new DateTime('2000-01-01T00:00:00Z');
1586
+ $date1->modify($time);
1587
+ $date2 = new DateTime('2001-12-25T00:00:00Z');
1588
+ $date2->modify($time);
1589
+
1590
+ return $date1 != $date2;
1591
+ }
1592
+
1593
+ ///////////////////////////////////////////////////////////////////
1594
+ /////////////////////// LOCALIZATION //////////////////////////////
1595
+ ///////////////////////////////////////////////////////////////////
1596
+
1597
+ /**
1598
+ * Initialize the translator instance if necessary.
1599
+ *
1600
+ * @return \Symfony\Component\Translation\TranslatorInterface
1601
+ */
1602
+ protected static function translator()
1603
+ {
1604
+ if (static::$translator === null) {
1605
+ static::$translator = Translator::get();
1606
+ }
1607
+
1608
+ return static::$translator;
1609
+ }
1610
+
1611
+ /**
1612
+ * Get the translator instance in use
1613
+ *
1614
+ * @return \Symfony\Component\Translation\TranslatorInterface
1615
+ */
1616
+ public static function getTranslator()
1617
+ {
1618
+ return static::translator();
1619
+ }
1620
+
1621
+ /**
1622
+ * Set the translator instance to use
1623
+ *
1624
+ * @param \Symfony\Component\Translation\TranslatorInterface $translator
1625
+ *
1626
+ * @return void
1627
+ */
1628
+ public static function setTranslator(TranslatorInterface $translator)
1629
+ {
1630
+ static::$translator = $translator;
1631
+ }
1632
+
1633
+ /**
1634
+ * Get the current translator locale
1635
+ *
1636
+ * @return string
1637
+ */
1638
+ public static function getLocale()
1639
+ {
1640
+ return static::translator()->getLocale();
1641
+ }
1642
+
1643
+ /**
1644
+ * Set the current translator locale and indicate if the source locale file exists
1645
+ *
1646
+ * @param string $locale locale ex. en
1647
+ *
1648
+ * @return bool
1649
+ */
1650
+ public static function setLocale($locale)
1651
+ {
1652
+ return static::translator()->setLocale($locale) !== false;
1653
+ }
1654
+
1655
+ ///////////////////////////////////////////////////////////////////
1656
+ /////////////////////// STRING FORMATTING /////////////////////////
1657
+ ///////////////////////////////////////////////////////////////////
1658
+
1659
+ /**
1660
+ * Set if UTF8 will be used for localized date/time
1661
+ *
1662
+ * @param bool $utf8
1663
+ */
1664
+ public static function setUtf8($utf8)
1665
+ {
1666
+ static::$utf8 = $utf8;
1667
+ }
1668
+
1669
+ /**
1670
+ * Format the instance with the current locale. You can set the current
1671
+ * locale using setlocale() http://php.net/setlocale.
1672
+ *
1673
+ * @param string $format
1674
+ *
1675
+ * @return string
1676
+ */
1677
+ public function formatLocalized($format)
1678
+ {
1679
+ // Check for Windows to find and replace the %e modifier correctly.
1680
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
1681
+ $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format); // @codeCoverageIgnore
1682
+ }
1683
+
1684
+ $formatted = strftime($format, strtotime($this->toDateTimeString()));
1685
+
1686
+ return static::$utf8 ? utf8_encode($formatted) : $formatted;
1687
+ }
1688
+
1689
+ /**
1690
+ * Reset the format used to the default when type juggling a Carbon instance to a string
1691
+ *
1692
+ * @return void
1693
+ */
1694
+ public static function resetToStringFormat()
1695
+ {
1696
+ static::setToStringFormat(static::DEFAULT_TO_STRING_FORMAT);
1697
+ }
1698
+
1699
+ /**
1700
+ * Set the default format used when type juggling a Carbon instance to a string
1701
+ *
1702
+ * @param string $format
1703
+ *
1704
+ * @return void
1705
+ */
1706
+ public static function setToStringFormat($format)
1707
+ {
1708
+ static::$toStringFormat = $format;
1709
+ }
1710
+
1711
+ /**
1712
+ * Format the instance as a string using the set format
1713
+ *
1714
+ * @return string
1715
+ */
1716
+ public function __toString()
1717
+ {
1718
+ return $this->format(static::$toStringFormat);
1719
+ }
1720
+
1721
+ /**
1722
+ * Format the instance as date
1723
+ *
1724
+ * @return string
1725
+ */
1726
+ public function toDateString()
1727
+ {
1728
+ return $this->format('Y-m-d');
1729
+ }
1730
+
1731
+ /**
1732
+ * Format the instance as a readable date
1733
+ *
1734
+ * @return string
1735
+ */
1736
+ public function toFormattedDateString()
1737
+ {
1738
+ return $this->format('M j, Y');
1739
+ }
1740
+
1741
+ /**
1742
+ * Format the instance as time
1743
+ *
1744
+ * @return string
1745
+ */
1746
+ public function toTimeString()
1747
+ {
1748
+ return $this->format('H:i:s');
1749
+ }
1750
+
1751
+ /**
1752
+ * Format the instance as date and time
1753
+ *
1754
+ * @return string
1755
+ */
1756
+ public function toDateTimeString()
1757
+ {
1758
+ return $this->format('Y-m-d H:i:s');
1759
+ }
1760
+
1761
+ /**
1762
+ * Format the instance with day, date and time
1763
+ *
1764
+ * @return string
1765
+ */
1766
+ public function toDayDateTimeString()
1767
+ {
1768
+ return $this->format('D, M j, Y g:i A');
1769
+ }
1770
+
1771
+ /**
1772
+ * Format the instance as ATOM
1773
+ *
1774
+ * @return string
1775
+ */
1776
+ public function toAtomString()
1777
+ {
1778
+ return $this->format(static::ATOM);
1779
+ }
1780
+
1781
+ /**
1782
+ * Format the instance as COOKIE
1783
+ *
1784
+ * @return string
1785
+ */
1786
+ public function toCookieString()
1787
+ {
1788
+ return $this->format(static::COOKIE);
1789
+ }
1790
+
1791
+ /**
1792
+ * Format the instance as ISO8601
1793
+ *
1794
+ * @return string
1795
+ */
1796
+ public function toIso8601String()
1797
+ {
1798
+ return $this->toAtomString();
1799
+ }
1800
+
1801
+ /**
1802
+ * Format the instance as RFC822
1803
+ *
1804
+ * @return string
1805
+ */
1806
+ public function toRfc822String()
1807
+ {
1808
+ return $this->format(static::RFC822);
1809
+ }
1810
+
1811
+ /**
1812
+ * Convert the instance to UTC and return as Zulu ISO8601
1813
+ *
1814
+ * @return string
1815
+ */
1816
+ public function toIso8601ZuluString()
1817
+ {
1818
+ return $this->copy()->setTimezone('UTC')->format('Y-m-d\TH:i:s\Z');
1819
+ }
1820
+
1821
+ /**
1822
+ * Format the instance as RFC850
1823
+ *
1824
+ * @return string
1825
+ */
1826
+ public function toRfc850String()
1827
+ {
1828
+ return $this->format(static::RFC850);
1829
+ }
1830
+
1831
+ /**
1832
+ * Format the instance as RFC1036
1833
+ *
1834
+ * @return string
1835
+ */
1836
+ public function toRfc1036String()
1837
+ {
1838
+ return $this->format(static::RFC1036);
1839
+ }
1840
+
1841
+ /**
1842
+ * Format the instance as RFC1123
1843
+ *
1844
+ * @return string
1845
+ */
1846
+ public function toRfc1123String()
1847
+ {
1848
+ return $this->format(static::RFC1123);
1849
+ }
1850
+
1851
+ /**
1852
+ * Format the instance as RFC2822
1853
+ *
1854
+ * @return string
1855
+ */
1856
+ public function toRfc2822String()
1857
+ {
1858
+ return $this->format(static::RFC2822);
1859
+ }
1860
+
1861
+ /**
1862
+ * Format the instance as RFC3339
1863
+ *
1864
+ * @return string
1865
+ */
1866
+ public function toRfc3339String()
1867
+ {
1868
+ return $this->format(static::RFC3339);
1869
+ }
1870
+
1871
+ /**
1872
+ * Format the instance as RSS
1873
+ *
1874
+ * @return string
1875
+ */
1876
+ public function toRssString()
1877
+ {
1878
+ return $this->format(static::RSS);
1879
+ }
1880
+
1881
+ /**
1882
+ * Format the instance as W3C
1883
+ *
1884
+ * @return string
1885
+ */
1886
+ public function toW3cString()
1887
+ {
1888
+ return $this->format(static::W3C);
1889
+ }
1890
+
1891
+ /**
1892
+ * Format the instance as RFC7231
1893
+ *
1894
+ * @return string
1895
+ */
1896
+ public function toRfc7231String()
1897
+ {
1898
+ return $this->copy()
1899
+ ->setTimezone('GMT')
1900
+ ->format(static::RFC7231_FORMAT);
1901
+ }
1902
+
1903
+ /**
1904
+ * Get default array representation
1905
+ *
1906
+ * @return array
1907
+ */
1908
+ public function toArray()
1909
+ {
1910
+ return array(
1911
+ 'year' => $this->year,
1912
+ 'month' => $this->month,
1913
+ 'day' => $this->day,
1914
+ 'dayOfWeek' => $this->dayOfWeek,
1915
+ 'dayOfYear' => $this->dayOfYear,
1916
+ 'hour' => $this->hour,
1917
+ 'minute' => $this->minute,
1918
+ 'second' => $this->second,
1919
+ 'micro' => $this->micro,
1920
+ 'timestamp' => $this->timestamp,
1921
+ 'formatted' => $this->format(self::DEFAULT_TO_STRING_FORMAT),
1922
+ 'timezone' => $this->timezone,
1923
+ );
1924
+ }
1925
+
1926
+ ///////////////////////////////////////////////////////////////////
1927
+ ////////////////////////// COMPARISONS ////////////////////////////
1928
+ ///////////////////////////////////////////////////////////////////
1929
+
1930
+ /**
1931
+ * Determines if the instance is equal to another
1932
+ *
1933
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
1934
+ *
1935
+ * @return bool
1936
+ */
1937
+ public function eq($date)
1938
+ {
1939
+ return $this == $date;
1940
+ }
1941
+
1942
+ /**
1943
+ * Determines if the instance is equal to another
1944
+ *
1945
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
1946
+ *
1947
+ * @see eq()
1948
+ *
1949
+ * @return bool
1950
+ */
1951
+ public function equalTo($date)
1952
+ {
1953
+ return $this->eq($date);
1954
+ }
1955
+
1956
+ /**
1957
+ * Determines if the instance is not equal to another
1958
+ *
1959
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
1960
+ *
1961
+ * @return bool
1962
+ */
1963
+ public function ne($date)
1964
+ {
1965
+ return !$this->eq($date);
1966
+ }
1967
+
1968
+ /**
1969
+ * Determines if the instance is not equal to another
1970
+ *
1971
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
1972
+ *
1973
+ * @see ne()
1974
+ *
1975
+ * @return bool
1976
+ */
1977
+ public function notEqualTo($date)
1978
+ {
1979
+ return $this->ne($date);
1980
+ }
1981
+
1982
+ /**
1983
+ * Determines if the instance is greater (after) than another
1984
+ *
1985
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
1986
+ *
1987
+ * @return bool
1988
+ */
1989
+ public function gt($date)
1990
+ {
1991
+ return $this > $date;
1992
+ }
1993
+
1994
+ /**
1995
+ * Determines if the instance is greater (after) than another
1996
+ *
1997
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
1998
+ *
1999
+ * @see gt()
2000
+ *
2001
+ * @return bool
2002
+ */
2003
+ public function greaterThan($date)
2004
+ {
2005
+ return $this->gt($date);
2006
+ }
2007
+
2008
+ /**
2009
+ * Determines if the instance is greater (after) than or equal to another
2010
+ *
2011
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2012
+ *
2013
+ * @return bool
2014
+ */
2015
+ public function gte($date)
2016
+ {
2017
+ return $this >= $date;
2018
+ }
2019
+
2020
+ /**
2021
+ * Determines if the instance is greater (after) than or equal to another
2022
+ *
2023
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2024
+ *
2025
+ * @see gte()
2026
+ *
2027
+ * @return bool
2028
+ */
2029
+ public function greaterThanOrEqualTo($date)
2030
+ {
2031
+ return $this->gte($date);
2032
+ }
2033
+
2034
+ /**
2035
+ * Determines if the instance is less (before) than another
2036
+ *
2037
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2038
+ *
2039
+ * @return bool
2040
+ */
2041
+ public function lt($date)
2042
+ {
2043
+ return $this < $date;
2044
+ }
2045
+
2046
+ /**
2047
+ * Determines if the instance is less (before) than another
2048
+ *
2049
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2050
+ *
2051
+ * @see lt()
2052
+ *
2053
+ * @return bool
2054
+ */
2055
+ public function lessThan($date)
2056
+ {
2057
+ return $this->lt($date);
2058
+ }
2059
+
2060
+ /**
2061
+ * Determines if the instance is less (before) or equal to another
2062
+ *
2063
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2064
+ *
2065
+ * @return bool
2066
+ */
2067
+ public function lte($date)
2068
+ {
2069
+ return $this <= $date;
2070
+ }
2071
+
2072
+ /**
2073
+ * Determines if the instance is less (before) or equal to another
2074
+ *
2075
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2076
+ *
2077
+ * @see lte()
2078
+ *
2079
+ * @return bool
2080
+ */
2081
+ public function lessThanOrEqualTo($date)
2082
+ {
2083
+ return $this->lte($date);
2084
+ }
2085
+
2086
+ /**
2087
+ * Determines if the instance is between two others
2088
+ *
2089
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
2090
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
2091
+ * @param bool $equal Indicates if an equal to comparison should be done
2092
+ *
2093
+ * @return bool
2094
+ */
2095
+ public function between($date1, $date2, $equal = true)
2096
+ {
2097
+ if ($date1->gt($date2)) {
2098
+ $temp = $date1;
2099
+ $date1 = $date2;
2100
+ $date2 = $temp;
2101
+ }
2102
+
2103
+ if ($equal) {
2104
+ return $this->gte($date1) && $this->lte($date2);
2105
+ }
2106
+
2107
+ return $this->gt($date1) && $this->lt($date2);
2108
+ }
2109
+
2110
+ /**
2111
+ * Get the closest date from the instance.
2112
+ *
2113
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
2114
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
2115
+ *
2116
+ * @return static
2117
+ */
2118
+ public function closest($date1, $date2)
2119
+ {
2120
+ return $this->diffInSeconds($date1) < $this->diffInSeconds($date2) ? $date1 : $date2;
2121
+ }
2122
+
2123
+ /**
2124
+ * Get the farthest date from the instance.
2125
+ *
2126
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
2127
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
2128
+ *
2129
+ * @return static
2130
+ */
2131
+ public function farthest($date1, $date2)
2132
+ {
2133
+ return $this->diffInSeconds($date1) > $this->diffInSeconds($date2) ? $date1 : $date2;
2134
+ }
2135
+
2136
+ /**
2137
+ * Get the minimum instance between a given instance (default now) and the current instance.
2138
+ *
2139
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2140
+ *
2141
+ * @return static
2142
+ */
2143
+ public function min($date = null)
2144
+ {
2145
+ $date = $this->resolveCarbon($date);
2146
+
2147
+ return $this->lt($date) ? $this : $date;
2148
+ }
2149
+
2150
+ /**
2151
+ * Get the minimum instance between a given instance (default now) and the current instance.
2152
+ *
2153
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2154
+ *
2155
+ * @see min()
2156
+ *
2157
+ * @return static
2158
+ */
2159
+ public function minimum($date = null)
2160
+ {
2161
+ return $this->min($date);
2162
+ }
2163
+
2164
+ /**
2165
+ * Get the maximum instance between a given instance (default now) and the current instance.
2166
+ *
2167
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2168
+ *
2169
+ * @return static
2170
+ */
2171
+ public function max($date = null)
2172
+ {
2173
+ $date = $this->resolveCarbon($date);
2174
+
2175
+ return $this->gt($date) ? $this : $date;
2176
+ }
2177
+
2178
+ /**
2179
+ * Get the maximum instance between a given instance (default now) and the current instance.
2180
+ *
2181
+ * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
2182
+ *
2183
+ * @see max()
2184
+ *
2185
+ * @return static
2186
+ */
2187
+ public function maximum($date = null)
2188
+ {
2189
+ return $this->max($date);
2190
+ }
2191
+
2192
+ /**
2193
+ * Determines if the instance is a weekday.
2194
+ *
2195
+ * @return bool
2196
+ */
2197
+ public function isWeekday()
2198
+ {
2199
+ return !$this->isWeekend();
2200
+ }
2201
+
2202
+ /**
2203
+ * Determines if the instance is a weekend day.
2204
+ *
2205
+ * @return bool
2206
+ */
2207
+ public function isWeekend()
2208
+ {
2209
+ return in_array($this->dayOfWeek, static::$weekendDays);
2210
+ }
2211
+
2212
+ /**
2213
+ * Determines if the instance is yesterday.
2214
+ *
2215
+ * @return bool
2216
+ */
2217
+ public function isYesterday()
2218
+ {
2219
+ return $this->toDateString() === static::yesterday($this->getTimezone())->toDateString();
2220
+ }
2221
+
2222
+ /**
2223
+ * Determines if the instance is today.
2224
+ *
2225
+ * @return bool
2226
+ */
2227
+ public function isToday()
2228
+ {
2229
+ return $this->toDateString() === $this->nowWithSameTz()->toDateString();
2230
+ }
2231
+
2232
+ /**
2233
+ * Determines if the instance is tomorrow.
2234
+ *
2235
+ * @return bool
2236
+ */
2237
+ public function isTomorrow()
2238
+ {
2239
+ return $this->toDateString() === static::tomorrow($this->getTimezone())->toDateString();
2240
+ }
2241
+
2242
+ /**
2243
+ * Determines if the instance is within the next week.
2244
+ *
2245
+ * @return bool
2246
+ */
2247
+ public function isNextWeek()
2248
+ {
2249
+ return $this->weekOfYear === $this->nowWithSameTz()->addWeek()->weekOfYear;
2250
+ }
2251
+
2252
+ /**
2253
+ * Determines if the instance is within the last week.
2254
+ *
2255
+ * @return bool
2256
+ */
2257
+ public function isLastWeek()
2258
+ {
2259
+ return $this->weekOfYear === $this->nowWithSameTz()->subWeek()->weekOfYear;
2260
+ }
2261
+
2262
+ /**
2263
+ * Determines if the instance is within the next quarter.
2264
+ *
2265
+ * @return bool
2266
+ */
2267
+ public function isNextQuarter()
2268
+ {
2269
+ return $this->quarter === $this->nowWithSameTz()->addQuarter()->quarter;
2270
+ }
2271
+
2272
+ /**
2273
+ * Determines if the instance is within the last quarter.
2274
+ *
2275
+ * @return bool
2276
+ */
2277
+ public function isLastQuarter()
2278
+ {
2279
+ return $this->quarter === $this->nowWithSameTz()->subQuarter()->quarter;
2280
+ }
2281
+
2282
+ /**
2283
+ * Determines if the instance is within the next month.
2284
+ *
2285
+ * @return bool
2286
+ */
2287
+ public function isNextMonth()
2288
+ {
2289
+ return $this->month === $this->nowWithSameTz()->addMonthNoOverflow()->month;
2290
+ }
2291
+
2292
+ /**
2293
+ * Determines if the instance is within the last month.
2294
+ *
2295
+ * @return bool
2296
+ */
2297
+ public function isLastMonth()
2298
+ {
2299
+ return $this->month === $this->nowWithSameTz()->subMonthNoOverflow()->month;
2300
+ }
2301
+
2302
+ /**
2303
+ * Determines if the instance is within next year.
2304
+ *
2305
+ * @return bool
2306
+ */
2307
+ public function isNextYear()
2308
+ {
2309
+ return $this->year === $this->nowWithSameTz()->addYear()->year;
2310
+ }
2311
+
2312
+ /**
2313
+ * Determines if the instance is within the previous year.
2314
+ *
2315
+ * @return bool
2316
+ */
2317
+ public function isLastYear()
2318
+ {
2319
+ return $this->year === $this->nowWithSameTz()->subYear()->year;
2320
+ }
2321
+
2322
+ /**
2323
+ * Determines if the instance is in the future, ie. greater (after) than now.
2324
+ *
2325
+ * @return bool
2326
+ */
2327
+ public function isFuture()
2328
+ {
2329
+ return $this->gt($this->nowWithSameTz());
2330
+ }
2331
+
2332
+ /**
2333
+ * Determines if the instance is in the past, ie. less (before) than now.
2334
+ *
2335
+ * @return bool
2336
+ */
2337
+ public function isPast()
2338
+ {
2339
+ return $this->lt($this->nowWithSameTz());
2340
+ }
2341
+
2342
+ /**
2343
+ * Determines if the instance is a leap year.
2344
+ *
2345
+ * @return bool
2346
+ */
2347
+ public function isLeapYear()
2348
+ {
2349
+ return $this->format('L') === '1';
2350
+ }
2351
+
2352
+ /**
2353
+ * Determines if the instance is a long year
2354
+ *
2355
+ * @see https://en.wikipedia.org/wiki/ISO_8601#Week_dates
2356
+ *
2357
+ * @return bool
2358
+ */
2359
+ public function isLongYear()
2360
+ {
2361
+ return static::create($this->year, 12, 28, 0, 0, 0, $this->tz)->weekOfYear === 53;
2362
+ }
2363
+
2364
+ /**
2365
+ * Compares the formatted values of the two dates.
2366
+ *
2367
+ * @param string $format The date formats to compare.
2368
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use current day.
2369
+ *
2370
+ * @throws \InvalidArgumentException
2371
+ *
2372
+ * @return bool
2373
+ */
2374
+ public function isSameAs($format, $date = null)
2375
+ {
2376
+ $date = $date ?: static::now($this->tz);
2377
+
2378
+ static::expectDateTime($date);
2379
+
2380
+ return $this->format($format) === $date->format($format);
2381
+ }
2382
+
2383
+ /**
2384
+ * Determines if the instance is in the current year.
2385
+ *
2386
+ * @return bool
2387
+ */
2388
+ public function isCurrentYear()
2389
+ {
2390
+ return $this->isSameYear();
2391
+ }
2392
+
2393
+ /**
2394
+ * Checks if the passed in date is in the same year as the instance year.
2395
+ *
2396
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use current day.
2397
+ *
2398
+ * @return bool
2399
+ */
2400
+ public function isSameYear($date = null)
2401
+ {
2402
+ return $this->isSameAs('Y', $date);
2403
+ }
2404
+
2405
+ /**
2406
+ * Determines if the instance is in the current month.
2407
+ *
2408
+ * @return bool
2409
+ */
2410
+ public function isCurrentQuarter()
2411
+ {
2412
+ return $this->isSameQuarter();
2413
+ }
2414
+
2415
+ /**
2416
+ * Checks if the passed in date is in the same quarter as the instance quarter (and year if needed).
2417
+ *
2418
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use current day.
2419
+ * @param bool $ofSameYear Check if it is the same month in the same year.
2420
+ *
2421
+ * @return bool
2422
+ */
2423
+ public function isSameQuarter($date = null, $ofSameYear = null)
2424
+ {
2425
+ $date = $date ? static::instance($date) : static::now($this->tz);
2426
+
2427
+ static::expectDateTime($date);
2428
+
2429
+ $ofSameYear = is_null($ofSameYear) ? static::shouldCompareYearWithMonth() : $ofSameYear;
2430
+
2431
+ return $this->quarter === $date->quarter && (!$ofSameYear || $this->isSameYear($date));
2432
+ }
2433
+
2434
+ /**
2435
+ * Determines if the instance is in the current month.
2436
+ *
2437
+ * @param bool $ofSameYear Check if it is the same month in the same year.
2438
+ *
2439
+ * @return bool
2440
+ */
2441
+ public function isCurrentMonth($ofSameYear = null)
2442
+ {
2443
+ return $this->isSameMonth($ofSameYear);
2444
+ }
2445
+
2446
+ /**
2447
+ * Checks if the passed in date is in the same month as the instance´s month.
2448
+ *
2449
+ * Note that this defaults to only comparing the month while ignoring the year.
2450
+ * To test if it is the same exact month of the same year, pass in true as the second parameter.
2451
+ *
2452
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use the current date.
2453
+ * @param bool $ofSameYear Check if it is the same month in the same year.
2454
+ *
2455
+ * @return bool
2456
+ */
2457
+ public function isSameMonth($date = null, $ofSameYear = null)
2458
+ {
2459
+ $ofSameYear = is_null($ofSameYear) ? static::shouldCompareYearWithMonth() : $ofSameYear;
2460
+
2461
+ return $this->isSameAs($ofSameYear ? 'Y-m' : 'm', $date);
2462
+ }
2463
+
2464
+ /**
2465
+ * Determines if the instance is in the current day.
2466
+ *
2467
+ * @return bool
2468
+ */
2469
+ public function isCurrentDay()
2470
+ {
2471
+ return $this->isSameDay();
2472
+ }
2473
+
2474
+ /**
2475
+ * Checks if the passed in date is the same exact day as the instance´s day.
2476
+ *
2477
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use the current date.
2478
+ *
2479
+ * @return bool
2480
+ */
2481
+ public function isSameDay($date = null)
2482
+ {
2483
+ return $this->isSameAs('Y-m-d', $date);
2484
+ }
2485
+
2486
+ /**
2487
+ * Determines if the instance is in the current hour.
2488
+ *
2489
+ * @return bool
2490
+ */
2491
+ public function isCurrentHour()
2492
+ {
2493
+ return $this->isSameHour();
2494
+ }
2495
+
2496
+ /**
2497
+ * Checks if the passed in date is the same exact hour as the instance´s hour.
2498
+ *
2499
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use the current date.
2500
+ *
2501
+ * @return bool
2502
+ */
2503
+ public function isSameHour($date = null)
2504
+ {
2505
+ return $this->isSameAs('Y-m-d H', $date);
2506
+ }
2507
+
2508
+ /**
2509
+ * Determines if the instance is in the current minute.
2510
+ *
2511
+ * @return bool
2512
+ */
2513
+ public function isCurrentMinute()
2514
+ {
2515
+ return $this->isSameMinute();
2516
+ }
2517
+
2518
+ /**
2519
+ * Checks if the passed in date is the same exact minute as the instance´s minute.
2520
+ *
2521
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use the current date.
2522
+ *
2523
+ * @return bool
2524
+ */
2525
+ public function isSameMinute($date = null)
2526
+ {
2527
+ return $this->isSameAs('Y-m-d H:i', $date);
2528
+ }
2529
+
2530
+ /**
2531
+ * Determines if the instance is in the current second.
2532
+ *
2533
+ * @return bool
2534
+ */
2535
+ public function isCurrentSecond()
2536
+ {
2537
+ return $this->isSameSecond();
2538
+ }
2539
+
2540
+ /**
2541
+ * Checks if the passed in date is the same exact second as the instance´s second.
2542
+ *
2543
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use the current date.
2544
+ *
2545
+ * @return bool
2546
+ */
2547
+ public function isSameSecond($date = null)
2548
+ {
2549
+ return $this->isSameAs('Y-m-d H:i:s', $date);
2550
+ }
2551
+
2552
+ /**
2553
+ * Checks if this day is a specific day of the week.
2554
+ *
2555
+ * @param int $dayOfWeek
2556
+ *
2557
+ * @return bool
2558
+ */
2559
+ public function isDayOfWeek($dayOfWeek)
2560
+ {
2561
+ return $this->dayOfWeek === $dayOfWeek;
2562
+ }
2563
+
2564
+ /**
2565
+ * Checks if this day is a Sunday.
2566
+ *
2567
+ * @return bool
2568
+ */
2569
+ public function isSunday()
2570
+ {
2571
+ return $this->dayOfWeek === static::SUNDAY;
2572
+ }
2573
+
2574
+ /**
2575
+ * Checks if this day is a Monday.
2576
+ *
2577
+ * @return bool
2578
+ */
2579
+ public function isMonday()
2580
+ {
2581
+ return $this->dayOfWeek === static::MONDAY;
2582
+ }
2583
+
2584
+ /**
2585
+ * Checks if this day is a Tuesday.
2586
+ *
2587
+ * @return bool
2588
+ */
2589
+ public function isTuesday()
2590
+ {
2591
+ return $this->dayOfWeek === static::TUESDAY;
2592
+ }
2593
+
2594
+ /**
2595
+ * Checks if this day is a Wednesday.
2596
+ *
2597
+ * @return bool
2598
+ */
2599
+ public function isWednesday()
2600
+ {
2601
+ return $this->dayOfWeek === static::WEDNESDAY;
2602
+ }
2603
+
2604
+ /**
2605
+ * Checks if this day is a Thursday.
2606
+ *
2607
+ * @return bool
2608
+ */
2609
+ public function isThursday()
2610
+ {
2611
+ return $this->dayOfWeek === static::THURSDAY;
2612
+ }
2613
+
2614
+ /**
2615
+ * Checks if this day is a Friday.
2616
+ *
2617
+ * @return bool
2618
+ */
2619
+ public function isFriday()
2620
+ {
2621
+ return $this->dayOfWeek === static::FRIDAY;
2622
+ }
2623
+
2624
+ /**
2625
+ * Checks if this day is a Saturday.
2626
+ *
2627
+ * @return bool
2628
+ */
2629
+ public function isSaturday()
2630
+ {
2631
+ return $this->dayOfWeek === static::SATURDAY;
2632
+ }
2633
+
2634
+ /**
2635
+ * Check if its the birthday. Compares the date/month values of the two dates.
2636
+ *
2637
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use current day.
2638
+ *
2639
+ * @return bool
2640
+ */
2641
+ public function isBirthday($date = null)
2642
+ {
2643
+ return $this->isSameAs('md', $date);
2644
+ }
2645
+
2646
+ /**
2647
+ * Check if today is the last day of the Month
2648
+ *
2649
+ * @return bool
2650
+ */
2651
+ public function isLastOfMonth()
2652
+ {
2653
+ return $this->day === $this->daysInMonth;
2654
+ }
2655
+
2656
+ /**
2657
+ * Check if the instance is start of day / midnight.
2658
+ *
2659
+ * @param bool $checkMicroseconds check time at microseconds precision
2660
+ * /!\ Warning, this is not reliable with PHP < 7.1.4
2661
+ *
2662
+ * @return bool
2663
+ */
2664
+ public function isStartOfDay($checkMicroseconds = false)
2665
+ {
2666
+ return $checkMicroseconds
2667
+ ? $this->format('H:i:s.u') === '00:00:00.000000'
2668
+ : $this->format('H:i:s') === '00:00:00';
2669
+ }
2670
+
2671
+ /**
2672
+ * Check if the instance is end of day.
2673
+ *
2674
+ * @param bool $checkMicroseconds check time at microseconds precision
2675
+ * /!\ Warning, this is not reliable with PHP < 7.1.4
2676
+ *
2677
+ * @return bool
2678
+ */
2679
+ public function isEndOfDay($checkMicroseconds = false)
2680
+ {
2681
+ return $checkMicroseconds
2682
+ ? $this->format('H:i:s.u') === '23:59:59.999999'
2683
+ : $this->format('H:i:s') === '23:59:59';
2684
+ }
2685
+
2686
+ /**
2687
+ * Check if the instance is start of day / midnight.
2688
+ *
2689
+ * @return bool
2690
+ */
2691
+ public function isMidnight()
2692
+ {
2693
+ return $this->isStartOfDay();
2694
+ }
2695
+
2696
+ /**
2697
+ * Check if the instance is midday.
2698
+ *
2699
+ * @return bool
2700
+ */
2701
+ public function isMidday()
2702
+ {
2703
+ return $this->format('G:i:s') === static::$midDayAt.':00:00';
2704
+ }
2705
+
2706
+ /**
2707
+ * Checks if the (date)time string is in a given format.
2708
+ *
2709
+ * @param string $date
2710
+ * @param string $format
2711
+ *
2712
+ * @return bool
2713
+ */
2714
+ public static function hasFormat($date, $format)
2715
+ {
2716
+ try {
2717
+ // Try to create a DateTime object. Throws an InvalidArgumentException if the provided time string
2718
+ // doesn't match the format in any way.
2719
+ static::createFromFormat($format, $date);
2720
+
2721
+ // createFromFormat() is known to handle edge cases silently.
2722
+ // E.g. "1975-5-1" (Y-n-j) will still be parsed correctly when "Y-m-d" is supplied as the format.
2723
+ // To ensure we're really testing against our desired format, perform an additional regex validation.
2724
+ $regex = strtr(
2725
+ preg_quote($format, '/'),
2726
+ static::$regexFormats
2727
+ );
2728
+
2729
+ return (bool) preg_match('/^'.$regex.'$/', $date);
2730
+ } catch (InvalidArgumentException $e) {
2731
+ }
2732
+
2733
+ return false;
2734
+ }
2735
+
2736
+ ///////////////////////////////////////////////////////////////////
2737
+ /////////////////// ADDITIONS AND SUBTRACTIONS ////////////////////
2738
+ ///////////////////////////////////////////////////////////////////
2739
+
2740
+ /**
2741
+ * Add centuries to the instance. Positive $value travels forward while
2742
+ * negative $value travels into the past.
2743
+ *
2744
+ * @param int $value
2745
+ *
2746
+ * @return static
2747
+ */
2748
+ public function addCenturies($value)
2749
+ {
2750
+ return $this->addYears(static::YEARS_PER_CENTURY * $value);
2751
+ }
2752
+
2753
+ /**
2754
+ * Add a century to the instance
2755
+ *
2756
+ * @param int $value
2757
+ *
2758
+ * @return static
2759
+ */
2760
+ public function addCentury($value = 1)
2761
+ {
2762
+ return $this->addCenturies($value);
2763
+ }
2764
+
2765
+ /**
2766
+ * Remove centuries from the instance
2767
+ *
2768
+ * @param int $value
2769
+ *
2770
+ * @return static
2771
+ */
2772
+ public function subCenturies($value)
2773
+ {
2774
+ return $this->addCenturies(-1 * $value);
2775
+ }
2776
+
2777
+ /**
2778
+ * Remove a century from the instance
2779
+ *
2780
+ * @param int $value
2781
+ *
2782
+ * @return static
2783
+ */
2784
+ public function subCentury($value = 1)
2785
+ {
2786
+ return $this->subCenturies($value);
2787
+ }
2788
+
2789
+ /**
2790
+ * Add years to the instance. Positive $value travel forward while
2791
+ * negative $value travel into the past.
2792
+ *
2793
+ * @param int $value
2794
+ *
2795
+ * @return static
2796
+ */
2797
+ public function addYears($value)
2798
+ {
2799
+ if ($this->shouldOverflowYears()) {
2800
+ return $this->addYearsWithOverflow($value);
2801
+ }
2802
+
2803
+ return $this->addYearsNoOverflow($value);
2804
+ }
2805
+
2806
+ /**
2807
+ * Add a year to the instance
2808
+ *
2809
+ * @param int $value
2810
+ *
2811
+ * @return static
2812
+ */
2813
+ public function addYear($value = 1)
2814
+ {
2815
+ return $this->addYears($value);
2816
+ }
2817
+
2818
+ /**
2819
+ * Add years to the instance with no overflow of months
2820
+ * Positive $value travel forward while
2821
+ * negative $value travel into the past.
2822
+ *
2823
+ * @param int $value
2824
+ *
2825
+ * @return static
2826
+ */
2827
+ public function addYearsNoOverflow($value)
2828
+ {
2829
+ return $this->addMonthsNoOverflow($value * static::MONTHS_PER_YEAR);
2830
+ }
2831
+
2832
+ /**
2833
+ * Add year with overflow months set to false
2834
+ *
2835
+ * @param int $value
2836
+ *
2837
+ * @return static
2838
+ */
2839
+ public function addYearNoOverflow($value = 1)
2840
+ {
2841
+ return $this->addYearsNoOverflow($value);
2842
+ }
2843
+
2844
+ /**
2845
+ * Add years to the instance.
2846
+ * Positive $value travel forward while
2847
+ * negative $value travel into the past.
2848
+ *
2849
+ * @param int $value
2850
+ *
2851
+ * @return static
2852
+ */
2853
+ public function addYearsWithOverflow($value)
2854
+ {
2855
+ return $this->modify((int) $value.' year');
2856
+ }
2857
+
2858
+ /**
2859
+ * Add year with overflow.
2860
+ *
2861
+ * @param int $value
2862
+ *
2863
+ * @return static
2864
+ */
2865
+ public function addYearWithOverflow($value = 1)
2866
+ {
2867
+ return $this->addYearsWithOverflow($value);
2868
+ }
2869
+
2870
+ /**
2871
+ * Remove years from the instance.
2872
+ *
2873
+ * @param int $value
2874
+ *
2875
+ * @return static
2876
+ */
2877
+ public function subYears($value)
2878
+ {
2879
+ return $this->addYears(-1 * $value);
2880
+ }
2881
+
2882
+ /**
2883
+ * Remove a year from the instance
2884
+ *
2885
+ * @param int $value
2886
+ *
2887
+ * @return static
2888
+ */
2889
+ public function subYear($value = 1)
2890
+ {
2891
+ return $this->subYears($value);
2892
+ }
2893
+
2894
+ /**
2895
+ * Remove years from the instance with no month overflow.
2896
+ *
2897
+ * @param int $value
2898
+ *
2899
+ * @return static
2900
+ */
2901
+ public function subYearsNoOverflow($value)
2902
+ {
2903
+ return $this->subMonthsNoOverflow($value * static::MONTHS_PER_YEAR);
2904
+ }
2905
+
2906
+ /**
2907
+ * Remove year from the instance with no month overflow
2908
+ *
2909
+ * @param int $value
2910
+ *
2911
+ * @return static
2912
+ */
2913
+ public function subYearNoOverflow($value = 1)
2914
+ {
2915
+ return $this->subYearsNoOverflow($value);
2916
+ }
2917
+
2918
+ /**
2919
+ * Remove years from the instance.
2920
+ *
2921
+ * @param int $value
2922
+ *
2923
+ * @return static
2924
+ */
2925
+ public function subYearsWithOverflow($value)
2926
+ {
2927
+ return $this->subMonthsWithOverflow($value * static::MONTHS_PER_YEAR);
2928
+ }
2929
+
2930
+ /**
2931
+ * Remove year from the instance.
2932
+ *
2933
+ * @param int $value
2934
+ *
2935
+ * @return static
2936
+ */
2937
+ public function subYearWithOverflow($value = 1)
2938
+ {
2939
+ return $this->subYearsWithOverflow($value);
2940
+ }
2941
+
2942
+ /**
2943
+ * Add quarters to the instance. Positive $value travels forward while
2944
+ * negative $value travels into the past.
2945
+ *
2946
+ * @param int $value
2947
+ *
2948
+ * @return static
2949
+ */
2950
+ public function addQuarters($value)
2951
+ {
2952
+ return $this->addMonths(static::MONTHS_PER_QUARTER * $value);
2953
+ }
2954
+
2955
+ /**
2956
+ * Add a quarter to the instance
2957
+ *
2958
+ * @param int $value
2959
+ *
2960
+ * @return static
2961
+ */
2962
+ public function addQuarter($value = 1)
2963
+ {
2964
+ return $this->addQuarters($value);
2965
+ }
2966
+
2967
+ /**
2968
+ * Remove quarters from the instance
2969
+ *
2970
+ * @param int $value
2971
+ *
2972
+ * @return static
2973
+ */
2974
+ public function subQuarters($value)
2975
+ {
2976
+ return $this->addQuarters(-1 * $value);
2977
+ }
2978
+
2979
+ /**
2980
+ * Remove a quarter from the instance
2981
+ *
2982
+ * @param int $value
2983
+ *
2984
+ * @return static
2985
+ */
2986
+ public function subQuarter($value = 1)
2987
+ {
2988
+ return $this->subQuarters($value);
2989
+ }
2990
+
2991
+ /**
2992
+ * Add months to the instance. Positive $value travels forward while
2993
+ * negative $value travels into the past.
2994
+ *
2995
+ * @param int $value
2996
+ *
2997
+ * @return static
2998
+ */
2999
+ public function addMonths($value)
3000
+ {
3001
+ if (static::shouldOverflowMonths()) {
3002
+ return $this->addMonthsWithOverflow($value);
3003
+ }
3004
+
3005
+ return $this->addMonthsNoOverflow($value);
3006
+ }
3007
+
3008
+ /**
3009
+ * Add a month to the instance
3010
+ *
3011
+ * @param int $value
3012
+ *
3013
+ * @return static
3014
+ */
3015
+ public function addMonth($value = 1)
3016
+ {
3017
+ return $this->addMonths($value);
3018
+ }
3019
+
3020
+ /**
3021
+ * Remove months from the instance
3022
+ *
3023
+ * @param int $value
3024
+ *
3025
+ * @return static
3026
+ */
3027
+ public function subMonths($value)
3028
+ {
3029
+ return $this->addMonths(-1 * $value);
3030
+ }
3031
+
3032
+ /**
3033
+ * Remove a month from the instance
3034
+ *
3035
+ * @param int $value
3036
+ *
3037
+ * @return static
3038
+ */
3039
+ public function subMonth($value = 1)
3040
+ {
3041
+ return $this->subMonths($value);
3042
+ }
3043
+
3044
+ /**
3045
+ * Add months to the instance. Positive $value travels forward while
3046
+ * negative $value travels into the past.
3047
+ *
3048
+ * @param int $value
3049
+ *
3050
+ * @return static
3051
+ */
3052
+ public function addMonthsWithOverflow($value)
3053
+ {
3054
+ return $this->modify((int) $value.' month');
3055
+ }
3056
+
3057
+ /**
3058
+ * Add a month to the instance
3059
+ *
3060
+ * @param int $value
3061
+ *
3062
+ * @return static
3063
+ */
3064
+ public function addMonthWithOverflow($value = 1)
3065
+ {
3066
+ return $this->addMonthsWithOverflow($value);
3067
+ }
3068
+
3069
+ /**
3070
+ * Remove months from the instance
3071
+ *
3072
+ * @param int $value
3073
+ *
3074
+ * @return static
3075
+ */
3076
+ public function subMonthsWithOverflow($value)
3077
+ {
3078
+ return $this->addMonthsWithOverflow(-1 * $value);
3079
+ }
3080
+
3081
+ /**
3082
+ * Remove a month from the instance
3083
+ *
3084
+ * @param int $value
3085
+ *
3086
+ * @return static
3087
+ */
3088
+ public function subMonthWithOverflow($value = 1)
3089
+ {
3090
+ return $this->subMonthsWithOverflow($value);
3091
+ }
3092
+
3093
+ /**
3094
+ * Add months without overflowing to the instance. Positive $value
3095
+ * travels forward while negative $value travels into the past.
3096
+ *
3097
+ * @param int $value
3098
+ *
3099
+ * @return static
3100
+ */
3101
+ public function addMonthsNoOverflow($value)
3102
+ {
3103
+ $day = $this->day;
3104
+
3105
+ $this->modify((int) $value.' month');
3106
+
3107
+ if ($day !== $this->day) {
3108
+ $this->modify('last day of previous month');
3109
+ }
3110
+
3111
+ return $this;
3112
+ }
3113
+
3114
+ /**
3115
+ * Add a month with no overflow to the instance
3116
+ *
3117
+ * @param int $value
3118
+ *
3119
+ * @return static
3120
+ */
3121
+ public function addMonthNoOverflow($value = 1)
3122
+ {
3123
+ return $this->addMonthsNoOverflow($value);
3124
+ }
3125
+
3126
+ /**
3127
+ * Remove months with no overflow from the instance
3128
+ *
3129
+ * @param int $value
3130
+ *
3131
+ * @return static
3132
+ */
3133
+ public function subMonthsNoOverflow($value)
3134
+ {
3135
+ return $this->addMonthsNoOverflow(-1 * $value);
3136
+ }
3137
+
3138
+ /**
3139
+ * Remove a month with no overflow from the instance
3140
+ *
3141
+ * @param int $value
3142
+ *
3143
+ * @return static
3144
+ */
3145
+ public function subMonthNoOverflow($value = 1)
3146
+ {
3147
+ return $this->subMonthsNoOverflow($value);
3148
+ }
3149
+
3150
+ /**
3151
+ * Add days to the instance. Positive $value travels forward while
3152
+ * negative $value travels into the past.
3153
+ *
3154
+ * @param int $value
3155
+ *
3156
+ * @return static
3157
+ */
3158
+ public function addDays($value)
3159
+ {
3160
+ return $this->modify((int) $value.' day');
3161
+ }
3162
+
3163
+ /**
3164
+ * Add a day to the instance
3165
+ *
3166
+ * @param int $value
3167
+ *
3168
+ * @return static
3169
+ */
3170
+ public function addDay($value = 1)
3171
+ {
3172
+ return $this->addDays($value);
3173
+ }
3174
+
3175
+ /**
3176
+ * Remove days from the instance
3177
+ *
3178
+ * @param int $value
3179
+ *
3180
+ * @return static
3181
+ */
3182
+ public function subDays($value)
3183
+ {
3184
+ return $this->addDays(-1 * $value);
3185
+ }
3186
+
3187
+ /**
3188
+ * Remove a day from the instance
3189
+ *
3190
+ * @param int $value
3191
+ *
3192
+ * @return static
3193
+ */
3194
+ public function subDay($value = 1)
3195
+ {
3196
+ return $this->subDays($value);
3197
+ }
3198
+
3199
+ /**
3200
+ * Add weekdays to the instance. Positive $value travels forward while
3201
+ * negative $value travels into the past.
3202
+ *
3203
+ * @param int $value
3204
+ *
3205
+ * @return static
3206
+ */
3207
+ public function addWeekdays($value)
3208
+ {
3209
+ // Fix for weekday bug https://bugs.php.net/bug.php?id=54909
3210
+ $t = $this->toTimeString();
3211
+ $this->modify((int) $value.' weekday');
3212
+
3213
+ return $this->setTimeFromTimeString($t);
3214
+ }
3215
+
3216
+ /**
3217
+ * Add a weekday to the instance
3218
+ *
3219
+ * @param int $value
3220
+ *
3221
+ * @return static
3222
+ */
3223
+ public function addWeekday($value = 1)
3224
+ {
3225
+ return $this->addWeekdays($value);
3226
+ }
3227
+
3228
+ /**
3229
+ * Remove weekdays from the instance
3230
+ *
3231
+ * @param int $value
3232
+ *
3233
+ * @return static
3234
+ */
3235
+ public function subWeekdays($value)
3236
+ {
3237
+ return $this->addWeekdays(-1 * $value);
3238
+ }
3239
+
3240
+ /**
3241
+ * Remove a weekday from the instance
3242
+ *
3243
+ * @param int $value
3244
+ *
3245
+ * @return static
3246
+ */
3247
+ public function subWeekday($value = 1)
3248
+ {
3249
+ return $this->subWeekdays($value);
3250
+ }
3251
+
3252
+ /**
3253
+ * Add weeks to the instance. Positive $value travels forward while
3254
+ * negative $value travels into the past.
3255
+ *
3256
+ * @param int $value
3257
+ *
3258
+ * @return static
3259
+ */
3260
+ public function addWeeks($value)
3261
+ {
3262
+ return $this->modify((int) $value.' week');
3263
+ }
3264
+
3265
+ /**
3266
+ * Add a week to the instance
3267
+ *
3268
+ * @param int $value
3269
+ *
3270
+ * @return static
3271
+ */
3272
+ public function addWeek($value = 1)
3273
+ {
3274
+ return $this->addWeeks($value);
3275
+ }
3276
+
3277
+ /**
3278
+ * Remove weeks to the instance
3279
+ *
3280
+ * @param int $value
3281
+ *
3282
+ * @return static
3283
+ */
3284
+ public function subWeeks($value)
3285
+ {
3286
+ return $this->addWeeks(-1 * $value);
3287
+ }
3288
+
3289
+ /**
3290
+ * Remove a week from the instance
3291
+ *
3292
+ * @param int $value
3293
+ *
3294
+ * @return static
3295
+ */
3296
+ public function subWeek($value = 1)
3297
+ {
3298
+ return $this->subWeeks($value);
3299
+ }
3300
+
3301
+ /**
3302
+ * Add hours to the instance. Positive $value travels forward while
3303
+ * negative $value travels into the past.
3304
+ *
3305
+ * @param int $value
3306
+ *
3307
+ * @return static
3308
+ */
3309
+ public function addHours($value)
3310
+ {
3311
+ return $this->modify((int) $value.' hour');
3312
+ }
3313
+
3314
+ /**
3315
+ * Add hours to the instance using timestamp. Positive $value travels
3316
+ * forward while negative $value travels into the past.
3317
+ *
3318
+ * @param int $value
3319
+ *
3320
+ * @return static
3321
+ */
3322
+ public function addRealHours($value)
3323
+ {
3324
+ return $this->addRealMinutes($value * static::MINUTES_PER_HOUR);
3325
+ }
3326
+
3327
+ /**
3328
+ * Add an hour to the instance.
3329
+ *
3330
+ * @param int $value
3331
+ *
3332
+ * @return static
3333
+ */
3334
+ public function addHour($value = 1)
3335
+ {
3336
+ return $this->addHours($value);
3337
+ }
3338
+
3339
+ /**
3340
+ * Add an hour to the instance using timestamp.
3341
+ *
3342
+ * @param int $value
3343
+ *
3344
+ * @return static
3345
+ */
3346
+ public function addRealHour($value = 1)
3347
+ {
3348
+ return $this->addRealHours($value);
3349
+ }
3350
+
3351
+ /**
3352
+ * Remove hours from the instance.
3353
+ *
3354
+ * @param int $value
3355
+ *
3356
+ * @return static
3357
+ */
3358
+ public function subHours($value)
3359
+ {
3360
+ return $this->addHours(-1 * $value);
3361
+ }
3362
+
3363
+ /**
3364
+ * Remove hours from the instance using timestamp.
3365
+ *
3366
+ * @param int $value
3367
+ *
3368
+ * @return static
3369
+ */
3370
+ public function subRealHours($value)
3371
+ {
3372
+ return $this->addRealHours(-1 * $value);
3373
+ }
3374
+
3375
+ /**
3376
+ * Remove an hour from the instance.
3377
+ *
3378
+ * @param int $value
3379
+ *
3380
+ * @return static
3381
+ */
3382
+ public function subHour($value = 1)
3383
+ {
3384
+ return $this->subHours($value);
3385
+ }
3386
+
3387
+ /**
3388
+ * Remove an hour from the instance.
3389
+ *
3390
+ * @param int $value
3391
+ *
3392
+ * @return static
3393
+ */
3394
+ public function subRealHour($value = 1)
3395
+ {
3396
+ return $this->subRealHours($value);
3397
+ }
3398
+
3399
+ /**
3400
+ * Add minutes to the instance using timestamp. Positive $value
3401
+ * travels forward while negative $value travels into the past.
3402
+ *
3403
+ * @param int $value
3404
+ *
3405
+ * @return static
3406
+ */
3407
+ public function addMinutes($value)
3408
+ {
3409
+ return $this->modify((int) $value.' minute');
3410
+ }
3411
+
3412
+ /**
3413
+ * Add minutes to the instance using timestamp. Positive $value travels
3414
+ * forward while negative $value travels into the past.
3415
+ *
3416
+ * @param int $value
3417
+ *
3418
+ * @return static
3419
+ */
3420
+ public function addRealMinutes($value)
3421
+ {
3422
+ return $this->addRealSeconds($value * static::SECONDS_PER_MINUTE);
3423
+ }
3424
+
3425
+ /**
3426
+ * Add a minute to the instance.
3427
+ *
3428
+ * @param int $value
3429
+ *
3430
+ * @return static
3431
+ */
3432
+ public function addMinute($value = 1)
3433
+ {
3434
+ return $this->addMinutes($value);
3435
+ }
3436
+
3437
+ /**
3438
+ * Add a minute to the instance using timestamp.
3439
+ *
3440
+ * @param int $value
3441
+ *
3442
+ * @return static
3443
+ */
3444
+ public function addRealMinute($value = 1)
3445
+ {
3446
+ return $this->addRealMinutes($value);
3447
+ }
3448
+
3449
+ /**
3450
+ * Remove a minute from the instance.
3451
+ *
3452
+ * @param int $value
3453
+ *
3454
+ * @return static
3455
+ */
3456
+ public function subMinute($value = 1)
3457
+ {
3458
+ return $this->subMinutes($value);
3459
+ }
3460
+
3461
+ /**
3462
+ * Remove a minute from the instance using timestamp.
3463
+ *
3464
+ * @param int $value
3465
+ *
3466
+ * @return static
3467
+ */
3468
+ public function subRealMinute($value = 1)
3469
+ {
3470
+ return $this->addRealMinutes(-1 * $value);
3471
+ }
3472
+
3473
+ /**
3474
+ * Remove minutes from the instance.
3475
+ *
3476
+ * @param int $value
3477
+ *
3478
+ * @return static
3479
+ */
3480
+ public function subMinutes($value)
3481
+ {
3482
+ return $this->addMinutes(-1 * $value);
3483
+ }
3484
+
3485
+ /**
3486
+ * Remove a minute from the instance using timestamp.
3487
+ *
3488
+ * @param int $value
3489
+ *
3490
+ * @return static
3491
+ */
3492
+ public function subRealMinutes($value = 1)
3493
+ {
3494
+ return $this->subRealMinute($value);
3495
+ }
3496
+
3497
+ /**
3498
+ * Add seconds to the instance. Positive $value travels forward while
3499
+ * negative $value travels into the past.
3500
+ *
3501
+ * @param int $value
3502
+ *
3503
+ * @return static
3504
+ */
3505
+ public function addSeconds($value)
3506
+ {
3507
+ return $this->modify((int) $value.' second');
3508
+ }
3509
+
3510
+ /**
3511
+ * Add seconds to the instance using timestamp. Positive $value travels
3512
+ * forward while negative $value travels into the past.
3513
+ *
3514
+ * @param int $value
3515
+ *
3516
+ * @return static
3517
+ */
3518
+ public function addRealSeconds($value)
3519
+ {
3520
+ return $this->setTimestamp($this->getTimestamp() + $value);
3521
+ }
3522
+
3523
+ /**
3524
+ * Add a second to the instance.
3525
+ *
3526
+ * @param int $value
3527
+ *
3528
+ * @return static
3529
+ */
3530
+ public function addSecond($value = 1)
3531
+ {
3532
+ return $this->addSeconds($value);
3533
+ }
3534
+
3535
+ /**
3536
+ * Add a second to the instance using timestamp.
3537
+ *
3538
+ * @param int $value
3539
+ *
3540
+ * @return static
3541
+ */
3542
+ public function addRealSecond($value = 1)
3543
+ {
3544
+ return $this->addRealSeconds($value);
3545
+ }
3546
+
3547
+ /**
3548
+ * Remove seconds from the instance.
3549
+ *
3550
+ * @param int $value
3551
+ *
3552
+ * @return static
3553
+ */
3554
+ public function subSeconds($value)
3555
+ {
3556
+ return $this->addSeconds(-1 * $value);
3557
+ }
3558
+
3559
+ /**
3560
+ * Remove seconds from the instance using timestamp.
3561
+ *
3562
+ * @param int $value
3563
+ *
3564
+ * @return static
3565
+ */
3566
+ public function subRealSeconds($value)
3567
+ {
3568
+ return $this->addRealSeconds(-1 * $value);
3569
+ }
3570
+
3571
+ /**
3572
+ * Remove a second from the instance
3573
+ *
3574
+ * @param int $value
3575
+ *
3576
+ * @return static
3577
+ */
3578
+ public function subSecond($value = 1)
3579
+ {
3580
+ return $this->subSeconds($value);
3581
+ }
3582
+
3583
+ /**
3584
+ * Remove a second from the instance using timestamp.
3585
+ *
3586
+ * @param int $value
3587
+ *
3588
+ * @return static
3589
+ */
3590
+ public function subRealSecond($value = 1)
3591
+ {
3592
+ return $this->subRealSeconds($value);
3593
+ }
3594
+
3595
+ ///////////////////////////////////////////////////////////////////
3596
+ /////////////////////////// DIFFERENCES ///////////////////////////
3597
+ ///////////////////////////////////////////////////////////////////
3598
+
3599
+ /**
3600
+ * Get the difference as a CarbonInterval instance
3601
+ *
3602
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3603
+ * @param bool $absolute Get the absolute of the difference
3604
+ *
3605
+ * @return CarbonInterval
3606
+ */
3607
+ public function diffAsCarbonInterval($date = null, $absolute = true)
3608
+ {
3609
+ return CarbonInterval::instance($this->diff($this->resolveCarbon($date), $absolute));
3610
+ }
3611
+
3612
+ /**
3613
+ * Get the difference in years
3614
+ *
3615
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3616
+ * @param bool $absolute Get the absolute of the difference
3617
+ *
3618
+ * @return int
3619
+ */
3620
+ public function diffInYears($date = null, $absolute = true)
3621
+ {
3622
+ return (int) $this->diff($this->resolveCarbon($date), $absolute)->format('%r%y');
3623
+ }
3624
+
3625
+ /**
3626
+ * Get the difference in months
3627
+ *
3628
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3629
+ * @param bool $absolute Get the absolute of the difference
3630
+ *
3631
+ * @return int
3632
+ */
3633
+ public function diffInMonths($date = null, $absolute = true)
3634
+ {
3635
+ $date = $this->resolveCarbon($date);
3636
+
3637
+ return $this->diffInYears($date, $absolute) * static::MONTHS_PER_YEAR + (int) $this->diff($date, $absolute)->format('%r%m');
3638
+ }
3639
+
3640
+ /**
3641
+ * Get the difference in weeks
3642
+ *
3643
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3644
+ * @param bool $absolute Get the absolute of the difference
3645
+ *
3646
+ * @return int
3647
+ */
3648
+ public function diffInWeeks($date = null, $absolute = true)
3649
+ {
3650
+ return (int) ($this->diffInDays($date, $absolute) / static::DAYS_PER_WEEK);
3651
+ }
3652
+
3653
+ /**
3654
+ * Get the difference in days
3655
+ *
3656
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3657
+ * @param bool $absolute Get the absolute of the difference
3658
+ *
3659
+ * @return int
3660
+ */
3661
+ public function diffInDays($date = null, $absolute = true)
3662
+ {
3663
+ return (int) $this->diff($this->resolveCarbon($date), $absolute)->format('%r%a');
3664
+ }
3665
+
3666
+ /**
3667
+ * Get the difference in days using a filter closure
3668
+ *
3669
+ * @param Closure $callback
3670
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3671
+ * @param bool $absolute Get the absolute of the difference
3672
+ *
3673
+ * @return int
3674
+ */
3675
+ public function diffInDaysFiltered(Closure $callback, $date = null, $absolute = true)
3676
+ {
3677
+ return $this->diffFiltered(CarbonInterval::day(), $callback, $date, $absolute);
3678
+ }
3679
+
3680
+ /**
3681
+ * Get the difference in hours using a filter closure
3682
+ *
3683
+ * @param Closure $callback
3684
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3685
+ * @param bool $absolute Get the absolute of the difference
3686
+ *
3687
+ * @return int
3688
+ */
3689
+ public function diffInHoursFiltered(Closure $callback, $date = null, $absolute = true)
3690
+ {
3691
+ return $this->diffFiltered(CarbonInterval::hour(), $callback, $date, $absolute);
3692
+ }
3693
+
3694
+ /**
3695
+ * Get the difference by the given interval using a filter closure
3696
+ *
3697
+ * @param CarbonInterval $ci An interval to traverse by
3698
+ * @param Closure $callback
3699
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3700
+ * @param bool $absolute Get the absolute of the difference
3701
+ *
3702
+ * @return int
3703
+ */
3704
+ public function diffFiltered(CarbonInterval $ci, Closure $callback, $date = null, $absolute = true)
3705
+ {
3706
+ $start = $this;
3707
+ $end = $this->resolveCarbon($date);
3708
+ $inverse = false;
3709
+
3710
+ if ($end < $start) {
3711
+ $start = $end;
3712
+ $end = $this;
3713
+ $inverse = true;
3714
+ }
3715
+
3716
+ $period = new DatePeriod($start, $ci, $end);
3717
+ $values = array_filter(iterator_to_array($period), function ($date) use ($callback) {
3718
+ return call_user_func($callback, Carbon::instance($date));
3719
+ });
3720
+
3721
+ $diff = count($values);
3722
+
3723
+ return $inverse && !$absolute ? -$diff : $diff;
3724
+ }
3725
+
3726
+ /**
3727
+ * Get the difference in weekdays
3728
+ *
3729
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3730
+ * @param bool $absolute Get the absolute of the difference
3731
+ *
3732
+ * @return int
3733
+ */
3734
+ public function diffInWeekdays($date = null, $absolute = true)
3735
+ {
3736
+ return $this->diffInDaysFiltered(function (Carbon $date) {
3737
+ return $date->isWeekday();
3738
+ }, $date, $absolute);
3739
+ }
3740
+
3741
+ /**
3742
+ * Get the difference in weekend days using a filter
3743
+ *
3744
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3745
+ * @param bool $absolute Get the absolute of the difference
3746
+ *
3747
+ * @return int
3748
+ */
3749
+ public function diffInWeekendDays($date = null, $absolute = true)
3750
+ {
3751
+ return $this->diffInDaysFiltered(function (Carbon $date) {
3752
+ return $date->isWeekend();
3753
+ }, $date, $absolute);
3754
+ }
3755
+
3756
+ /**
3757
+ * Get the difference in hours.
3758
+ *
3759
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3760
+ * @param bool $absolute Get the absolute of the difference
3761
+ *
3762
+ * @return int
3763
+ */
3764
+ public function diffInHours($date = null, $absolute = true)
3765
+ {
3766
+ return (int) ($this->diffInSeconds($date, $absolute) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
3767
+ }
3768
+
3769
+ /**
3770
+ * Get the difference in hours using timestamps.
3771
+ *
3772
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3773
+ * @param bool $absolute Get the absolute of the difference
3774
+ *
3775
+ * @return int
3776
+ */
3777
+ public function diffInRealHours($date = null, $absolute = true)
3778
+ {
3779
+ return (int) ($this->diffInRealSeconds($date, $absolute) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
3780
+ }
3781
+
3782
+ /**
3783
+ * Get the difference in minutes.
3784
+ *
3785
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3786
+ * @param bool $absolute Get the absolute of the difference
3787
+ *
3788
+ * @return int
3789
+ */
3790
+ public function diffInMinutes($date = null, $absolute = true)
3791
+ {
3792
+ return (int) ($this->diffInSeconds($date, $absolute) / static::SECONDS_PER_MINUTE);
3793
+ }
3794
+
3795
+ /**
3796
+ * Get the difference in minutes using timestamps.
3797
+ *
3798
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3799
+ * @param bool $absolute Get the absolute of the difference
3800
+ *
3801
+ * @return int
3802
+ */
3803
+ public function diffInRealMinutes($date = null, $absolute = true)
3804
+ {
3805
+ return (int) ($this->diffInRealSeconds($date, $absolute) / static::SECONDS_PER_MINUTE);
3806
+ }
3807
+
3808
+ /**
3809
+ * Get the difference in seconds.
3810
+ *
3811
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3812
+ * @param bool $absolute Get the absolute of the difference
3813
+ *
3814
+ * @return int
3815
+ */
3816
+ public function diffInSeconds($date = null, $absolute = true)
3817
+ {
3818
+ $diff = $this->diff($this->resolveCarbon($date));
3819
+ $value = $diff->days * static::HOURS_PER_DAY * static::MINUTES_PER_HOUR * static::SECONDS_PER_MINUTE +
3820
+ $diff->h * static::MINUTES_PER_HOUR * static::SECONDS_PER_MINUTE +
3821
+ $diff->i * static::SECONDS_PER_MINUTE +
3822
+ $diff->s;
3823
+
3824
+ return $absolute || !$diff->invert ? $value : -$value;
3825
+ }
3826
+
3827
+ /**
3828
+ * Get the difference in seconds using timestamps.
3829
+ *
3830
+ * @param \Carbon\Carbon|\DateTimeInterface|string|null $date
3831
+ * @param bool $absolute Get the absolute of the difference
3832
+ *
3833
+ * @return int
3834
+ */
3835
+ public function diffInRealSeconds($date = null, $absolute = true)
3836
+ {
3837
+ $date = $this->resolveCarbon($date);
3838
+ $value = $date->getTimestamp() - $this->getTimestamp();
3839
+
3840
+ return $absolute ? abs($value) : $value;
3841
+ }
3842
+
3843
+ /**
3844
+ * The number of seconds since midnight.
3845
+ *
3846
+ * @return int
3847
+ */
3848
+ public function secondsSinceMidnight()
3849
+ {
3850
+ return $this->diffInSeconds($this->copy()->startOfDay());
3851
+ }
3852
+
3853
+ /**
3854
+ * The number of seconds until 23:59:59.
3855
+ *
3856
+ * @return int
3857
+ */
3858
+ public function secondsUntilEndOfDay()
3859
+ {
3860
+ return $this->diffInSeconds($this->copy()->endOfDay());
3861
+ }
3862
+
3863
+ /**
3864
+ * Get the difference in a human readable format in the current locale.
3865
+ *
3866
+ * When comparing a value in the past to default now:
3867
+ * 1 hour ago
3868
+ * 5 months ago
3869
+ *
3870
+ * When comparing a value in the future to default now:
3871
+ * 1 hour from now
3872
+ * 5 months from now
3873
+ *
3874
+ * When comparing a value in the past to another value:
3875
+ * 1 hour before
3876
+ * 5 months before
3877
+ *
3878
+ * When comparing a value in the future to another value:
3879
+ * 1 hour after
3880
+ * 5 months after
3881
+ *
3882
+ * @param Carbon|null $other
3883
+ * @param bool $absolute removes time difference modifiers ago, after, etc
3884
+ * @param bool $short displays short format of time units
3885
+ * @param int $parts displays number of parts in the interval
3886
+ *
3887
+ * @return string
3888
+ */
3889
+ public function diffForHumans($other = null, $absolute = false, $short = false, $parts = 1)
3890
+ {
3891
+ $isNow = $other === null;
3892
+ $interval = array();
3893
+
3894
+ $parts = min(6, max(1, (int) $parts));
3895
+ $count = 1;
3896
+ $unit = $short ? 's' : 'second';
3897
+
3898
+ if ($isNow) {
3899
+ $other = $this->nowWithSameTz();
3900
+ } elseif (!$other instanceof DateTime && !$other instanceof DateTimeInterface) {
3901
+ $other = static::parse($other);
3902
+ }
3903
+
3904
+ $diffInterval = $this->diff($other);
3905
+
3906
+ $diffIntervalArray = array(
3907
+ array('value' => $diffInterval->y, 'unit' => 'year', 'unitShort' => 'y'),
3908
+ array('value' => $diffInterval->m, 'unit' => 'month', 'unitShort' => 'm'),
3909
+ array('value' => $diffInterval->d, 'unit' => 'day', 'unitShort' => 'd'),
3910
+ array('value' => $diffInterval->h, 'unit' => 'hour', 'unitShort' => 'h'),
3911
+ array('value' => $diffInterval->i, 'unit' => 'minute', 'unitShort' => 'min'),
3912
+ array('value' => $diffInterval->s, 'unit' => 'second', 'unitShort' => 's'),
3913
+ );
3914
+
3915
+ foreach ($diffIntervalArray as $diffIntervalData) {
3916
+ if ($diffIntervalData['value'] > 0) {
3917
+ $unit = $short ? $diffIntervalData['unitShort'] : $diffIntervalData['unit'];
3918
+ $count = $diffIntervalData['value'];
3919
+
3920
+ if ($diffIntervalData['unit'] === 'day' && $count >= static::DAYS_PER_WEEK) {
3921
+ $unit = $short ? 'w' : 'week';
3922
+ $count = (int) ($count / static::DAYS_PER_WEEK);
3923
+
3924
+ $interval[] = static::translator()->transChoice($unit, $count, array(':count' => $count));
3925
+
3926
+ // get the count days excluding weeks (might be zero)
3927
+ $numOfDaysCount = (int) ($diffIntervalData['value'] - ($count * static::DAYS_PER_WEEK));
3928
+
3929
+ if ($numOfDaysCount > 0 && count($interval) < $parts) {
3930
+ $unit = $short ? 'd' : 'day';
3931
+ $count = $numOfDaysCount;
3932
+ $interval[] = static::translator()->transChoice($unit, $count, array(':count' => $count));
3933
+ }
3934
+ } else {
3935
+ $interval[] = static::translator()->transChoice($unit, $count, array(':count' => $count));
3936
+ }
3937
+ }
3938
+
3939
+ // break the loop after we get the required number of parts in array
3940
+ if (count($interval) >= $parts) {
3941
+ break;
3942
+ }
3943
+ }
3944
+
3945
+ if (count($interval) === 0) {
3946
+ if ($isNow && static::getHumanDiffOptions() & self::JUST_NOW) {
3947
+ $key = 'diff_now';
3948
+ $translation = static::translator()->trans($key);
3949
+ if ($translation !== $key) {
3950
+ return $translation;
3951
+ }
3952
+ }
3953
+ $count = static::getHumanDiffOptions() & self::NO_ZERO_DIFF ? 1 : 0;
3954
+ $unit = $short ? 's' : 'second';
3955
+ $interval[] = static::translator()->transChoice($unit, $count, array(':count' => $count));
3956
+ }
3957
+
3958
+ // join the interval parts by a space
3959
+ $time = implode(' ', $interval);
3960
+
3961
+ unset($diffIntervalArray, $interval);
3962
+
3963
+ if ($absolute) {
3964
+ return $time;
3965
+ }
3966
+
3967
+ $isFuture = $diffInterval->invert === 1;
3968
+
3969
+ $transId = $isNow ? ($isFuture ? 'from_now' : 'ago') : ($isFuture ? 'after' : 'before');
3970
+
3971
+ if ($parts === 1) {
3972
+ if ($isNow && $unit === 'day') {
3973
+ if ($count === 1 && static::getHumanDiffOptions() & self::ONE_DAY_WORDS) {
3974
+ $key = $isFuture ? 'diff_tomorrow' : 'diff_yesterday';
3975
+ $translation = static::translator()->trans($key);
3976
+ if ($translation !== $key) {
3977
+ return $translation;
3978
+ }
3979
+ }
3980
+ if ($count === 2 && static::getHumanDiffOptions() & self::TWO_DAY_WORDS) {
3981
+ $key = $isFuture ? 'diff_after_tomorrow' : 'diff_before_yesterday';
3982
+ $translation = static::translator()->trans($key);
3983
+ if ($translation !== $key) {
3984
+ return $translation;
3985
+ }
3986
+ }
3987
+ }
3988
+ // Some langs have special pluralization for past and future tense.
3989
+ $key = $unit.'_'.$transId;
3990
+ $count = isset($count) ? $count : 1;
3991
+ if ($key !== static::translator()->transChoice($key, $count)) {
3992
+ $time = static::translator()->transChoice($key, $count, array(':count' => $count));
3993
+ }
3994
+ }
3995
+
3996
+ return static::translator()->trans($transId, array(':time' => $time));
3997
+ }
3998
+
3999
+ ///////////////////////////////////////////////////////////////////
4000
+ //////////////////////////// MODIFIERS ////////////////////////////
4001
+ ///////////////////////////////////////////////////////////////////
4002
+
4003
+ /**
4004
+ * Resets the time to 00:00:00 start of day
4005
+ *
4006
+ * @return static
4007
+ */
4008
+ public function startOfDay()
4009
+ {
4010
+ return $this->modify('00:00:00.000000');
4011
+ }
4012
+
4013
+ /**
4014
+ * Resets the time to 23:59:59 end of day
4015
+ *
4016
+ * @return static
4017
+ */
4018
+ public function endOfDay()
4019
+ {
4020
+ return $this->modify('23.59.59.999999');
4021
+ }
4022
+
4023
+ /**
4024
+ * Resets the date to the first day of the month and the time to 00:00:00
4025
+ *
4026
+ * @return static
4027
+ */
4028
+ public function startOfMonth()
4029
+ {
4030
+ return $this->setDate($this->year, $this->month, 1)->startOfDay();
4031
+ }
4032
+
4033
+ /**
4034
+ * Resets the date to end of the month and time to 23:59:59
4035
+ *
4036
+ * @return static
4037
+ */
4038
+ public function endOfMonth()
4039
+ {
4040
+ return $this->setDate($this->year, $this->month, $this->daysInMonth)->endOfDay();
4041
+ }
4042
+
4043
+ /**
4044
+ * Resets the date to the first day of the quarter and the time to 00:00:00
4045
+ *
4046
+ * @return static
4047
+ */
4048
+ public function startOfQuarter()
4049
+ {
4050
+ $month = ($this->quarter - 1) * static::MONTHS_PER_QUARTER + 1;
4051
+
4052
+ return $this->setDate($this->year, $month, 1)->startOfDay();
4053
+ }
4054
+
4055
+ /**
4056
+ * Resets the date to end of the quarter and time to 23:59:59
4057
+ *
4058
+ * @return static
4059
+ */
4060
+ public function endOfQuarter()
4061
+ {
4062
+ return $this->startOfQuarter()->addMonths(static::MONTHS_PER_QUARTER - 1)->endOfMonth();
4063
+ }
4064
+
4065
+ /**
4066
+ * Resets the date to the first day of the year and the time to 00:00:00
4067
+ *
4068
+ * @return static
4069
+ */
4070
+ public function startOfYear()
4071
+ {
4072
+ return $this->setDate($this->year, 1, 1)->startOfDay();
4073
+ }
4074
+
4075
+ /**
4076
+ * Resets the date to end of the year and time to 23:59:59
4077
+ *
4078
+ * @return static
4079
+ */
4080
+ public function endOfYear()
4081
+ {
4082
+ return $this->setDate($this->year, 12, 31)->endOfDay();
4083
+ }
4084
+
4085
+ /**
4086
+ * Resets the date to the first day of the decade and the time to 00:00:00
4087
+ *
4088
+ * @return static
4089
+ */
4090
+ public function startOfDecade()
4091
+ {
4092
+ $year = $this->year - $this->year % static::YEARS_PER_DECADE;
4093
+
4094
+ return $this->setDate($year, 1, 1)->startOfDay();
4095
+ }
4096
+
4097
+ /**
4098
+ * Resets the date to end of the decade and time to 23:59:59
4099
+ *
4100
+ * @return static
4101
+ */
4102
+ public function endOfDecade()
4103
+ {
4104
+ $year = $this->year - $this->year % static::YEARS_PER_DECADE + static::YEARS_PER_DECADE - 1;
4105
+
4106
+ return $this->setDate($year, 12, 31)->endOfDay();
4107
+ }
4108
+
4109
+ /**
4110
+ * Resets the date to the first day of the century and the time to 00:00:00
4111
+ *
4112
+ * @return static
4113
+ */
4114
+ public function startOfCentury()
4115
+ {
4116
+ $year = $this->year - ($this->year - 1) % static::YEARS_PER_CENTURY;
4117
+
4118
+ return $this->setDate($year, 1, 1)->startOfDay();
4119
+ }
4120
+
4121
+ /**
4122
+ * Resets the date to end of the century and time to 23:59:59
4123
+ *
4124
+ * @return static
4125
+ */
4126
+ public function endOfCentury()
4127
+ {
4128
+ $year = $this->year - 1 - ($this->year - 1) % static::YEARS_PER_CENTURY + static::YEARS_PER_CENTURY;
4129
+
4130
+ return $this->setDate($year, 12, 31)->endOfDay();
4131
+ }
4132
+
4133
+ /**
4134
+ * Resets the date to the first day of week (defined in $weekStartsAt) and the time to 00:00:00
4135
+ *
4136
+ * @return static
4137
+ */
4138
+ public function startOfWeek()
4139
+ {
4140
+ while ($this->dayOfWeek !== static::$weekStartsAt) {
4141
+ $this->subDay();
4142
+ }
4143
+
4144
+ return $this->startOfDay();
4145
+ }
4146
+
4147
+ /**
4148
+ * Resets the date to end of week (defined in $weekEndsAt) and time to 23:59:59
4149
+ *
4150
+ * @return static
4151
+ */
4152
+ public function endOfWeek()
4153
+ {
4154
+ while ($this->dayOfWeek !== static::$weekEndsAt) {
4155
+ $this->addDay();
4156
+ }
4157
+
4158
+ return $this->endOfDay();
4159
+ }
4160
+
4161
+ /**
4162
+ * Modify to start of current hour, minutes and seconds become 0
4163
+ *
4164
+ * @return static
4165
+ */
4166
+ public function startOfHour()
4167
+ {
4168
+ return $this->setTime($this->hour, 0, 0);
4169
+ }
4170
+
4171
+ /**
4172
+ * Modify to end of current hour, minutes and seconds become 59
4173
+ *
4174
+ * @return static
4175
+ */
4176
+ public function endOfHour()
4177
+ {
4178
+ return $this->setTime($this->hour, 59, 59);
4179
+ }
4180
+
4181
+ /**
4182
+ * Modify to start of current minute, seconds become 0
4183
+ *
4184
+ * @return static
4185
+ */
4186
+ public function startOfMinute()
4187
+ {
4188
+ return $this->setTime($this->hour, $this->minute, 0);
4189
+ }
4190
+
4191
+ /**
4192
+ * Modify to end of current minute, seconds become 59
4193
+ *
4194
+ * @return static
4195
+ */
4196
+ public function endOfMinute()
4197
+ {
4198
+ return $this->setTime($this->hour, $this->minute, 59);
4199
+ }
4200
+
4201
+ /**
4202
+ * Modify to midday, default to self::$midDayAt
4203
+ *
4204
+ * @return static
4205
+ */
4206
+ public function midDay()
4207
+ {
4208
+ return $this->setTime(self::$midDayAt, 0, 0);
4209
+ }
4210
+
4211
+ /**
4212
+ * Modify to the next occurrence of a given day of the week.
4213
+ * If no dayOfWeek is provided, modify to the next occurrence
4214
+ * of the current day of the week. Use the supplied constants
4215
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4216
+ *
4217
+ * @param int|null $dayOfWeek
4218
+ *
4219
+ * @return static
4220
+ */
4221
+ public function next($dayOfWeek = null)
4222
+ {
4223
+ if ($dayOfWeek === null) {
4224
+ $dayOfWeek = $this->dayOfWeek;
4225
+ }
4226
+
4227
+ return $this->startOfDay()->modify('next '.static::$days[$dayOfWeek]);
4228
+ }
4229
+
4230
+ /**
4231
+ * Go forward or backward to the next week- or weekend-day.
4232
+ *
4233
+ * @param bool $weekday
4234
+ * @param bool $forward
4235
+ *
4236
+ * @return $this
4237
+ */
4238
+ private function nextOrPreviousDay($weekday = true, $forward = true)
4239
+ {
4240
+ $step = $forward ? 1 : -1;
4241
+
4242
+ do {
4243
+ $this->addDay($step);
4244
+ } while ($weekday ? $this->isWeekend() : $this->isWeekday());
4245
+
4246
+ return $this;
4247
+ }
4248
+
4249
+ /**
4250
+ * Go forward to the next weekday.
4251
+ *
4252
+ * @return $this
4253
+ */
4254
+ public function nextWeekday()
4255
+ {
4256
+ return $this->nextOrPreviousDay();
4257
+ }
4258
+
4259
+ /**
4260
+ * Go backward to the previous weekday.
4261
+ *
4262
+ * @return $this
4263
+ */
4264
+ public function previousWeekday()
4265
+ {
4266
+ return $this->nextOrPreviousDay(true, false);
4267
+ }
4268
+
4269
+ /**
4270
+ * Go forward to the next weekend day.
4271
+ *
4272
+ * @return $this
4273
+ */
4274
+ public function nextWeekendDay()
4275
+ {
4276
+ return $this->nextOrPreviousDay(false);
4277
+ }
4278
+
4279
+ /**
4280
+ * Go backward to the previous weekend day.
4281
+ *
4282
+ * @return $this
4283
+ */
4284
+ public function previousWeekendDay()
4285
+ {
4286
+ return $this->nextOrPreviousDay(false, false);
4287
+ }
4288
+
4289
+ /**
4290
+ * Modify to the previous occurrence of a given day of the week.
4291
+ * If no dayOfWeek is provided, modify to the previous occurrence
4292
+ * of the current day of the week. Use the supplied constants
4293
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4294
+ *
4295
+ * @param int|null $dayOfWeek
4296
+ *
4297
+ * @return static
4298
+ */
4299
+ public function previous($dayOfWeek = null)
4300
+ {
4301
+ if ($dayOfWeek === null) {
4302
+ $dayOfWeek = $this->dayOfWeek;
4303
+ }
4304
+
4305
+ return $this->startOfDay()->modify('last '.static::$days[$dayOfWeek]);
4306
+ }
4307
+
4308
+ /**
4309
+ * Modify to the first occurrence of a given day of the week
4310
+ * in the current month. If no dayOfWeek is provided, modify to the
4311
+ * first day of the current month. Use the supplied constants
4312
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4313
+ *
4314
+ * @param int|null $dayOfWeek
4315
+ *
4316
+ * @return static
4317
+ */
4318
+ public function firstOfMonth($dayOfWeek = null)
4319
+ {
4320
+ $this->startOfDay();
4321
+
4322
+ if ($dayOfWeek === null) {
4323
+ return $this->day(1);
4324
+ }
4325
+
4326
+ return $this->modify('first '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year);
4327
+ }
4328
+
4329
+ /**
4330
+ * Modify to the last occurrence of a given day of the week
4331
+ * in the current month. If no dayOfWeek is provided, modify to the
4332
+ * last day of the current month. Use the supplied constants
4333
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4334
+ *
4335
+ * @param int|null $dayOfWeek
4336
+ *
4337
+ * @return static
4338
+ */
4339
+ public function lastOfMonth($dayOfWeek = null)
4340
+ {
4341
+ $this->startOfDay();
4342
+
4343
+ if ($dayOfWeek === null) {
4344
+ return $this->day($this->daysInMonth);
4345
+ }
4346
+
4347
+ return $this->modify('last '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year);
4348
+ }
4349
+
4350
+ /**
4351
+ * Modify to the given occurrence of a given day of the week
4352
+ * in the current month. If the calculated occurrence is outside the scope
4353
+ * of the current month, then return false and no modifications are made.
4354
+ * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
4355
+ *
4356
+ * @param int $nth
4357
+ * @param int $dayOfWeek
4358
+ *
4359
+ * @return mixed
4360
+ */
4361
+ public function nthOfMonth($nth, $dayOfWeek)
4362
+ {
4363
+ $date = $this->copy()->firstOfMonth();
4364
+ $check = $date->format('Y-m');
4365
+ $date->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
4366
+
4367
+ return $date->format('Y-m') === $check ? $this->modify($date) : false;
4368
+ }
4369
+
4370
+ /**
4371
+ * Modify to the first occurrence of a given day of the week
4372
+ * in the current quarter. If no dayOfWeek is provided, modify to the
4373
+ * first day of the current quarter. Use the supplied constants
4374
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4375
+ *
4376
+ * @param int|null $dayOfWeek day of the week default null
4377
+ *
4378
+ * @return static
4379
+ */
4380
+ public function firstOfQuarter($dayOfWeek = null)
4381
+ {
4382
+ return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER - 2, 1)->firstOfMonth($dayOfWeek);
4383
+ }
4384
+
4385
+ /**
4386
+ * Modify to the last occurrence of a given day of the week
4387
+ * in the current quarter. If no dayOfWeek is provided, modify to the
4388
+ * last day of the current quarter. Use the supplied constants
4389
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4390
+ *
4391
+ * @param int|null $dayOfWeek day of the week default null
4392
+ *
4393
+ * @return static
4394
+ */
4395
+ public function lastOfQuarter($dayOfWeek = null)
4396
+ {
4397
+ return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER, 1)->lastOfMonth($dayOfWeek);
4398
+ }
4399
+
4400
+ /**
4401
+ * Modify to the given occurrence of a given day of the week
4402
+ * in the current quarter. If the calculated occurrence is outside the scope
4403
+ * of the current quarter, then return false and no modifications are made.
4404
+ * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
4405
+ *
4406
+ * @param int $nth
4407
+ * @param int $dayOfWeek
4408
+ *
4409
+ * @return mixed
4410
+ */
4411
+ public function nthOfQuarter($nth, $dayOfWeek)
4412
+ {
4413
+ $date = $this->copy()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
4414
+ $lastMonth = $date->month;
4415
+ $year = $date->year;
4416
+ $date->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
4417
+
4418
+ return ($lastMonth < $date->month || $year !== $date->year) ? false : $this->modify($date);
4419
+ }
4420
+
4421
+ /**
4422
+ * Modify to the first occurrence of a given day of the week
4423
+ * in the current year. If no dayOfWeek is provided, modify to the
4424
+ * first day of the current year. Use the supplied constants
4425
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4426
+ *
4427
+ * @param int|null $dayOfWeek day of the week default null
4428
+ *
4429
+ * @return static
4430
+ */
4431
+ public function firstOfYear($dayOfWeek = null)
4432
+ {
4433
+ return $this->month(1)->firstOfMonth($dayOfWeek);
4434
+ }
4435
+
4436
+ /**
4437
+ * Modify to the last occurrence of a given day of the week
4438
+ * in the current year. If no dayOfWeek is provided, modify to the
4439
+ * last day of the current year. Use the supplied constants
4440
+ * to indicate the desired dayOfWeek, ex. static::MONDAY.
4441
+ *
4442
+ * @param int|null $dayOfWeek day of the week default null
4443
+ *
4444
+ * @return static
4445
+ */
4446
+ public function lastOfYear($dayOfWeek = null)
4447
+ {
4448
+ return $this->month(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
4449
+ }
4450
+
4451
+ /**
4452
+ * Modify to the given occurrence of a given day of the week
4453
+ * in the current year. If the calculated occurrence is outside the scope
4454
+ * of the current year, then return false and no modifications are made.
4455
+ * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
4456
+ *
4457
+ * @param int $nth
4458
+ * @param int $dayOfWeek
4459
+ *
4460
+ * @return mixed
4461
+ */
4462
+ public function nthOfYear($nth, $dayOfWeek)
4463
+ {
4464
+ $date = $this->copy()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
4465
+
4466
+ return $this->year === $date->year ? $this->modify($date) : false;
4467
+ }
4468
+
4469
+ /**
4470
+ * Modify the current instance to the average of a given instance (default now) and the current instance.
4471
+ *
4472
+ * @param \Carbon\Carbon|\DateTimeInterface|null $date
4473
+ *
4474
+ * @return static
4475
+ */
4476
+ public function average($date = null)
4477
+ {
4478
+ return $this->addSeconds((int) ($this->diffInSeconds($this->resolveCarbon($date), false) / 2));
4479
+ }
4480
+
4481
+ ///////////////////////////////////////////////////////////////////
4482
+ /////////////////////////// SERIALIZATION /////////////////////////
4483
+ ///////////////////////////////////////////////////////////////////
4484
+
4485
+ /**
4486
+ * Return a serialized string of the instance.
4487
+ *
4488
+ * @return string
4489
+ */
4490
+ public function serialize()
4491
+ {
4492
+ return serialize($this);
4493
+ }
4494
+
4495
+ /**
4496
+ * Create an instance from a serialized string.
4497
+ *
4498
+ * @param string $value
4499
+ *
4500
+ * @throws \InvalidArgumentException
4501
+ *
4502
+ * @return static
4503
+ */
4504
+ public static function fromSerialized($value)
4505
+ {
4506
+ $instance = @unserialize($value);
4507
+
4508
+ if (!$instance instanceof static) {
4509
+ throw new InvalidArgumentException('Invalid serialized value.');
4510
+ }
4511
+
4512
+ return $instance;
4513
+ }
4514
+
4515
+ /**
4516
+ * The __set_state handler.
4517
+ *
4518
+ * @param array $array
4519
+ *
4520
+ * @return static
4521
+ */
4522
+ public static function __set_state($array)
4523
+ {
4524
+ return static::instance(parent::__set_state($array));
4525
+ }
4526
+
4527
+ /**
4528
+ * Prepare the object for JSON serialization.
4529
+ *
4530
+ * @return array|string
4531
+ */
4532
+ public function jsonSerialize()
4533
+ {
4534
+ if (static::$serializer) {
4535
+ return call_user_func(static::$serializer, $this);
4536
+ }
4537
+
4538
+ $carbon = $this;
4539
+
4540
+ return call_user_func(function () use ($carbon) {
4541
+ return get_object_vars($carbon);
4542
+ });
4543
+ }
4544
+
4545
+ /**
4546
+ * JSON serialize all Carbon instances using the given callback.
4547
+ *
4548
+ * @param callable $callback
4549
+ *
4550
+ * @return void
4551
+ */
4552
+ public static function serializeUsing($callback)
4553
+ {
4554
+ static::$serializer = $callback;
4555
+ }
4556
+
4557
+ ///////////////////////////////////////////////////////////////////
4558
+ /////////////////////////////// MACRO /////////////////////////////
4559
+ ///////////////////////////////////////////////////////////////////
4560
+
4561
+ /**
4562
+ * Register a custom macro.
4563
+ *
4564
+ * @param string $name
4565
+ * @param object|callable $macro
4566
+ *
4567
+ * @return void
4568
+ */
4569
+ public static function macro($name, $macro)
4570
+ {
4571
+ static::$localMacros[$name] = $macro;
4572
+ }
4573
+
4574
+ /**
4575
+ * Mix another object into the class.
4576
+ *
4577
+ * @param object $mixin
4578
+ *
4579
+ * @return void
4580
+ */
4581
+ public static function mixin($mixin)
4582
+ {
4583
+ $reflection = new \ReflectionClass($mixin);
4584
+ $methods = $reflection->getMethods(
4585
+ \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED
4586
+ );
4587
+
4588
+ foreach ($methods as $method) {
4589
+ $method->setAccessible(true);
4590
+
4591
+ static::macro($method->name, $method->invoke($mixin));
4592
+ }
4593
+ }
4594
+
4595
+ /**
4596
+ * Checks if macro is registered.
4597
+ *
4598
+ * @param string $name
4599
+ *
4600
+ * @return bool
4601
+ */
4602
+ public static function hasMacro($name)
4603
+ {
4604
+ return isset(static::$localMacros[$name]);
4605
+ }
4606
+
4607
+ /**
4608
+ * Dynamically handle calls to the class.
4609
+ *
4610
+ * @param string $method
4611
+ * @param array $parameters
4612
+ *
4613
+ * @throws \BadMethodCallException
4614
+ *
4615
+ * @return mixed
4616
+ */
4617
+ public static function __callStatic($method, $parameters)
4618
+ {
4619
+ if (!static::hasMacro($method)) {
4620
+ throw new \BadMethodCallException("Method $method does not exist.");
4621
+ }
4622
+
4623
+ if (static::$localMacros[$method] instanceof Closure && method_exists('Closure', 'bind')) {
4624
+ return call_user_func_array(Closure::bind(static::$localMacros[$method], null, get_called_class()), $parameters);
4625
+ }
4626
+
4627
+ return call_user_func_array(static::$localMacros[$method], $parameters);
4628
+ }
4629
+
4630
+ /**
4631
+ * Dynamically handle calls to the class.
4632
+ *
4633
+ * @param string $method
4634
+ * @param array $parameters
4635
+ *
4636
+ * @throws \BadMethodCallException|\ReflectionException
4637
+ *
4638
+ * @return mixed
4639
+ */
4640
+ public function __call($method, $parameters)
4641
+ {
4642
+ if (!static::hasMacro($method)) {
4643
+ throw new \BadMethodCallException("Method $method does not exist.");
4644
+ }
4645
+
4646
+ $macro = static::$localMacros[$method];
4647
+
4648
+ $reflexion = new \ReflectionFunction($macro);
4649
+ $reflectionParameters = $reflexion->getParameters();
4650
+ $expectedCount = count($reflectionParameters);
4651
+ $actualCount = count($parameters);
4652
+ if ($expectedCount > $actualCount && $reflectionParameters[$expectedCount - 1]->name === 'self') {
4653
+ for ($i = $actualCount; $i < $expectedCount - 1; $i++) {
4654
+ $parameters[] = $reflectionParameters[$i]->getDefaultValue();
4655
+ }
4656
+ $parameters[] = $this;
4657
+ }
4658
+
4659
+ if ($macro instanceof Closure && method_exists($macro, 'bindTo')) {
4660
+ return call_user_func_array($macro->bindTo($this, get_class($this)), $parameters);
4661
+ }
4662
+
4663
+ return call_user_func_array($macro, $parameters);
4664
+ }
4665
+ }
app/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php ADDED
@@ -0,0 +1,1130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Carbon;
13
+
14
+ use Closure;
15
+ use DateInterval;
16
+ use InvalidArgumentException;
17
+ use ReflectionClass;
18
+ use ReflectionFunction;
19
+ use ReflectionMethod;
20
+ use Symfony\Component\Translation\TranslatorInterface;
21
+
22
+ /**
23
+ * A simple API extension for DateInterval.
24
+ * The implementation provides helpers to handle weeks but only days are saved.
25
+ * Weeks are calculated based on the total days of the current instance.
26
+ *
27
+ * @property int $years Total years of the current interval.
28
+ * @property int $months Total months of the current interval.
29
+ * @property int $weeks Total weeks of the current interval calculated from the days.
30
+ * @property int $dayz Total days of the current interval (weeks * 7 + days).
31
+ * @property int $hours Total hours of the current interval.
32
+ * @property int $minutes Total minutes of the current interval.
33
+ * @property int $seconds Total seconds of the current interval.
34
+ * @property-read int $dayzExcludeWeeks Total days remaining in the final week of the current instance (days % 7).
35
+ * @property-read int $daysExcludeWeeks alias of dayzExcludeWeeks
36
+ * @property-read float $totalYears Number of years equivalent to the interval.
37
+ * @property-read float $totalMonths Number of months equivalent to the interval.
38
+ * @property-read float $totalWeeks Number of weeks equivalent to the interval.
39
+ * @property-read float $totalDays Number of days equivalent to the interval.
40
+ * @property-read float $totalDayz Alias for totalDays.
41
+ * @property-read float $totalHours Number of hours equivalent to the interval.
42
+ * @property-read float $totalMinutes Number of minutes equivalent to the interval.
43
+ * @property-read float $totalSeconds Number of seconds equivalent to the interval.
44
+ *
45
+ * @method static CarbonInterval years($years = 1) Create instance specifying a number of years.
46
+ * @method static CarbonInterval year($years = 1) Alias for years()
47
+ * @method static CarbonInterval months($months = 1) Create instance specifying a number of months.
48
+ * @method static CarbonInterval month($months = 1) Alias for months()
49
+ * @method static CarbonInterval weeks($weeks = 1) Create instance specifying a number of weeks.
50
+ * @method static CarbonInterval week($weeks = 1) Alias for weeks()
51
+ * @method static CarbonInterval days($days = 1) Create instance specifying a number of days.
52
+ * @method static CarbonInterval dayz($days = 1) Alias for days()
53
+ * @method static CarbonInterval day($days = 1) Alias for days()
54
+ * @method static CarbonInterval hours($hours = 1) Create instance specifying a number of hours.
55
+ * @method static CarbonInterval hour($hours = 1) Alias for hours()
56
+ * @method static CarbonInterval minutes($minutes = 1) Create instance specifying a number of minutes.
57
+ * @method static CarbonInterval minute($minutes = 1) Alias for minutes()
58
+ * @method static CarbonInterval seconds($seconds = 1) Create instance specifying a number of seconds.
59
+ * @method static CarbonInterval second($seconds = 1) Alias for seconds()
60
+ * @method CarbonInterval years($years = 1) Set the years portion of the current interval.
61
+ * @method CarbonInterval year($years = 1) Alias for years().
62
+ * @method CarbonInterval months($months = 1) Set the months portion of the current interval.
63
+ * @method CarbonInterval month($months = 1) Alias for months().
64
+ * @method CarbonInterval weeks($weeks = 1) Set the weeks portion of the current interval. Will overwrite dayz value.
65
+ * @method CarbonInterval week($weeks = 1) Alias for weeks().
66
+ * @method CarbonInterval days($days = 1) Set the days portion of the current interval.
67
+ * @method CarbonInterval dayz($days = 1) Alias for days().
68
+ * @method CarbonInterval day($days = 1) Alias for days().
69
+ * @method CarbonInterval hours($hours = 1) Set the hours portion of the current interval.
70
+ * @method CarbonInterval hour($hours = 1) Alias for hours().
71
+ * @method CarbonInterval minutes($minutes = 1) Set the minutes portion of the current interval.
72
+ * @method CarbonInterval minute($minutes = 1) Alias for minutes().
73
+ * @method CarbonInterval seconds($seconds = 1) Set the seconds portion of the current interval.
74
+ * @method CarbonInterval second($seconds = 1) Alias for seconds().
75
+ */
76
+ class CarbonInterval extends DateInterval
77
+ {
78
+ /**
79
+ * Interval spec period designators
80
+ */
81
+ const PERIOD_PREFIX = 'P';
82
+ const PERIOD_YEARS = 'Y';
83
+ const PERIOD_MONTHS = 'M';
84
+ const PERIOD_DAYS = 'D';
85
+ const PERIOD_TIME_PREFIX = 'T';
86
+ const PERIOD_HOURS = 'H';
87
+ const PERIOD_MINUTES = 'M';
88
+ const PERIOD_SECONDS = 'S';
89
+
90
+ /**
91
+ * A translator to ... er ... translate stuff
92
+ *
93
+ * @var \Symfony\Component\Translation\TranslatorInterface
94
+ */
95
+ protected static $translator;
96
+
97
+ /**
98
+ * @var array|null
99
+ */
100
+ protected static $cascadeFactors;
101
+
102
+ /**
103
+ * @var array|null
104
+ */
105
+ private static $flipCascadeFactors;
106
+
107
+ /**
108
+ * The registered macros.
109
+ *
110
+ * @var array
111
+ */
112
+ protected static $macros = array();
113
+
114
+ /**
115
+ * Before PHP 5.4.20/5.5.4 instead of FALSE days will be set to -99999 when the interval instance
116
+ * was created by DateTime::diff().
117
+ */
118
+ const PHP_DAYS_FALSE = -99999;
119
+
120
+ /**
121
+ * Mapping of units and factors for cascading.
122
+ *
123
+ * Should only be modified by changing the factors or referenced constants.
124
+ *
125
+ * @return array
126
+ */
127
+ public static function getCascadeFactors()
128
+ {
129
+ return static::$cascadeFactors ?: array(
130
+ 'minutes' => array(Carbon::SECONDS_PER_MINUTE, 'seconds'),
131
+ 'hours' => array(Carbon::MINUTES_PER_HOUR, 'minutes'),
132
+ 'dayz' => array(Carbon::HOURS_PER_DAY, 'hours'),
133
+ 'months' => array(Carbon::DAYS_PER_WEEK * Carbon::WEEKS_PER_MONTH, 'dayz'),
134
+ 'years' => array(Carbon::MONTHS_PER_YEAR, 'months'),
135
+ );
136
+ }
137
+
138
+ private static function standardizeUnit($unit)
139
+ {
140
+ $unit = rtrim($unit, 'sz').'s';
141
+
142
+ return $unit === 'days' ? 'dayz' : $unit;
143
+ }
144
+
145
+ private static function getFlipCascadeFactors()
146
+ {
147
+ if (!self::$flipCascadeFactors) {
148
+ self::$flipCascadeFactors = array();
149
+ foreach (static::getCascadeFactors() as $to => $tuple) {
150
+ list($factor, $from) = $tuple;
151
+
152
+ self::$flipCascadeFactors[self::standardizeUnit($from)] = array(self::standardizeUnit($to), $factor);
153
+ }
154
+ }
155
+
156
+ return self::$flipCascadeFactors;
157
+ }
158
+
159
+ /**
160
+ * @param array $cascadeFactors
161
+ */
162
+ public static function setCascadeFactors(array $cascadeFactors)
163
+ {
164
+ self::$flipCascadeFactors = null;
165
+ static::$cascadeFactors = $cascadeFactors;
166
+ }
167
+
168
+ /**
169
+ * Determine if the interval was created via DateTime:diff() or not.
170
+ *
171
+ * @param DateInterval $interval
172
+ *
173
+ * @return bool
174
+ */
175
+ private static function wasCreatedFromDiff(DateInterval $interval)
176
+ {
177
+ return $interval->days !== false && $interval->days !== static::PHP_DAYS_FALSE;
178
+ }
179
+
180
+ ///////////////////////////////////////////////////////////////////
181
+ //////////////////////////// CONSTRUCTORS /////////////////////////
182
+ ///////////////////////////////////////////////////////////////////
183
+
184
+ /**
185
+ * Create a new CarbonInterval instance.
186
+ *
187
+ * @param int $years
188
+ * @param int $months
189
+ * @param int $weeks
190
+ * @param int $days
191
+ * @param int $hours
192
+ * @param int $minutes
193
+ * @param int $seconds
194
+ */
195
+ public function __construct($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null)
196
+ {
197
+ $spec = $years;
198
+
199
+ if (!is_string($spec) || floatval($years) || preg_match('/^[0-9.]/', $years)) {
200
+ $spec = static::PERIOD_PREFIX;
201
+
202
+ $spec .= $years > 0 ? $years.static::PERIOD_YEARS : '';
203
+ $spec .= $months > 0 ? $months.static::PERIOD_MONTHS : '';
204
+
205
+ $specDays = 0;
206
+ $specDays += $weeks > 0 ? $weeks * static::getDaysPerWeek() : 0;
207
+ $specDays += $days > 0 ? $days : 0;
208
+
209
+ $spec .= $specDays > 0 ? $specDays.static::PERIOD_DAYS : '';
210
+
211
+ if ($hours > 0 || $minutes > 0 || $seconds > 0) {
212
+ $spec .= static::PERIOD_TIME_PREFIX;
213
+ $spec .= $hours > 0 ? $hours.static::PERIOD_HOURS : '';
214
+ $spec .= $minutes > 0 ? $minutes.static::PERIOD_MINUTES : '';
215
+ $spec .= $seconds > 0 ? $seconds.static::PERIOD_SECONDS : '';
216
+ }
217
+
218
+ if ($spec === static::PERIOD_PREFIX) {
219
+ // Allow the zero interval.
220
+ $spec .= '0'.static::PERIOD_YEARS;
221
+ }
222
+ }
223
+
224
+ parent::__construct($spec);
225
+ }
226
+
227
+ /**
228
+ * Returns the factor for a given source-to-target couple.
229
+ *
230
+ * @param string $source
231
+ * @param string $target
232
+ *
233
+ * @return int|null
234
+ */
235
+ public static function getFactor($source, $target)
236
+ {
237
+ $source = self::standardizeUnit($source);
238
+ $target = self::standardizeUnit($target);
239
+ $factors = static::getFlipCascadeFactors();
240
+ if (isset($factors[$source])) {
241
+ list($to, $factor) = $factors[$source];
242
+ if ($to === $target) {
243
+ return $factor;
244
+ }
245
+ }
246
+
247
+ return null;
248
+ }
249
+
250
+ /**
251
+ * Returns current config for days per week.
252
+ *
253
+ * @return int
254
+ */
255
+ public static function getDaysPerWeek()
256
+ {
257
+ return static::getFactor('dayz', 'weeks') ?: Carbon::DAYS_PER_WEEK;
258
+ }
259
+
260
+ /**
261
+ * Returns current config for hours per day.
262
+ *
263
+ * @return int
264
+ */
265
+ public static function getHoursPerDay()
266
+ {
267
+ return static::getFactor('hours', 'dayz') ?: Carbon::HOURS_PER_DAY;
268
+ }
269
+
270
+ /**
271
+ * Returns current config for minutes per hour.
272
+ *
273
+ * @return int
274
+ */
275
+ public static function getMinutesPerHours()
276
+ {
277
+ return static::getFactor('minutes', 'hours') ?: Carbon::MINUTES_PER_HOUR;
278
+ }
279
+
280
+ /**
281
+ * Returns current config for seconds per minute.
282
+ *
283
+ * @return int
284
+ */
285
+ public static function getSecondsPerMinutes()
286
+ {
287
+ return static::getFactor('seconds', 'minutes') ?: Carbon::SECONDS_PER_MINUTE;
288
+ }
289
+
290
+ /**
291
+ * Create a new CarbonInterval instance from specific values.
292
+ * This is an alias for the constructor that allows better fluent
293
+ * syntax as it allows you to do CarbonInterval::create(1)->fn() rather than
294
+ * (new CarbonInterval(1))->fn().
295
+ *
296
+ * @param int $years
297
+ * @param int $months
298
+ * @param int $weeks
299
+ * @param int $days
300
+ * @param int $hours
301
+ * @param int $minutes
302
+ * @param int $seconds
303
+ *
304
+ * @return static
305
+ */
306
+ public static function create($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null)
307
+ {
308
+ return new static($years, $months, $weeks, $days, $hours, $minutes, $seconds);
309
+ }
310
+
311
+ /**
312
+ * Get a copy of the instance.
313
+ *
314
+ * @return static
315
+ */
316
+ public function copy()
317
+ {
318
+ $date = new static($this->spec());
319
+ $date->invert = $this->invert;
320
+
321
+ return $date;
322
+ }
323
+
324
+ /**
325
+ * Provide static helpers to create instances. Allows CarbonInterval::years(3).
326
+ *
327
+ * Note: This is done using the magic method to allow static and instance methods to
328
+ * have the same names.
329
+ *
330
+ * @param string $name
331
+ * @param array $args
332
+ *
333
+ * @return static
334
+ */
335
+ public static function __callStatic($name, $args)
336
+ {
337
+ $arg = count($args) === 0 ? 1 : $args[0];
338
+
339
+ switch ($name) {
340
+ case 'years':
341
+ case 'year':
342
+ return new static($arg);
343
+
344
+ case 'months':
345
+ case 'month':
346
+ return new static(null, $arg);
347
+
348
+ case 'weeks':
349
+ case 'week':
350
+ return new static(null, null, $arg);
351
+
352
+ case 'days':
353
+ case 'dayz':
354
+ case 'day':
355
+ return new static(null, null, null, $arg);
356
+
357
+ case 'hours':
358
+ case 'hour':
359
+ return new static(null, null, null, null, $arg);
360
+
361
+ case 'minutes':
362
+ case 'minute':
363
+ return new static(null, null, null, null, null, $arg);
364
+
365
+ case 'seconds':
366
+ case 'second':
367
+ return new static(null, null, null, null, null, null, $arg);
368
+ }
369
+
370
+ if (static::hasMacro($name)) {
371
+ return call_user_func_array(
372
+ array(new static(0), $name), $args
373
+ );
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Creates a CarbonInterval from string.
379
+ *
380
+ * Format:
381
+ *
382
+ * Suffix | Unit | Example | DateInterval expression
383
+ * -------|---------|---------|------------------------
384
+ * y | years | 1y | P1Y
385
+ * mo | months | 3mo | P3M
386
+ * w | weeks | 2w | P2W
387
+ * d | days | 28d | P28D
388
+ * h | hours | 4h | PT4H
389
+ * m | minutes | 12m | PT12M
390
+ * s | seconds | 59s | PT59S
391
+ *
392
+ * e. g. `1w 3d 4h 32m 23s` is converted to 10 days 4 hours 32 minutes and 23 seconds.
393
+ *
394
+ * Special cases:
395
+ * - An empty string will return a zero interval
396
+ * - Fractions are allowed for weeks, days, hours and minutes and will be converted
397
+ * and rounded to the next smaller value (caution: 0.5w = 4d)
398
+ *
399
+ * @param string $intervalDefinition
400
+ *
401
+ * @return static
402
+ */
403
+ public static function fromString($intervalDefinition)
404
+ {
405
+ if (empty($intervalDefinition)) {
406
+ return new static(0);
407
+ }
408
+
409
+ $years = 0;
410
+ $months = 0;
411
+ $weeks = 0;
412
+ $days = 0;
413
+ $hours = 0;
414
+ $minutes = 0;
415
+ $seconds = 0;
416
+
417
+ $pattern = '/(\d+(?:\.\d+)?)\h*([^\d\h]*)/i';
418
+ preg_match_all($pattern, $intervalDefinition, $parts, PREG_SET_ORDER);
419
+ while ($match = array_shift($parts)) {
420
+ list($part, $value, $unit) = $match;
421
+ $intValue = intval($value);
422
+ $fraction = floatval($value) - $intValue;
423
+ switch (strtolower($unit)) {
424
+ case 'year':
425
+ case 'years':
426
+ case 'y':
427
+ $years += $intValue;
428
+ break;
429
+
430
+ case 'month':
431
+ case 'months':
432
+ case 'mo':
433
+ $months += $intValue;
434
+ break;
435
+
436
+ case 'week':
437
+ case 'weeks':
438
+ case 'w':
439
+ $weeks += $intValue;
440
+ if ($fraction) {
441
+ $parts[] = array(null, $fraction * static::getDaysPerWeek(), 'd');
442
+ }
443
+ break;
444
+
445
+ case 'day':
446
+ case 'days':
447
+ case 'd':
448
+ $days += $intValue;
449
+ if ($fraction) {
450
+ $parts[] = array(null, $fraction * static::getHoursPerDay(), 'h');
451
+ }
452
+ break;
453
+
454
+ case 'hour':
455
+ case 'hours':
456
+ case 'h':
457
+ $hours += $intValue;
458
+ if ($fraction) {
459
+ $parts[] = array(null, $fraction * static::getMinutesPerHours(), 'm');
460
+ }
461
+ break;
462
+
463
+ case 'minute':
464
+ case 'minutes':
465
+ case 'm':
466
+ $minutes += $intValue;
467
+ if ($fraction) {
468
+ $seconds += round($fraction * static::getSecondsPerMinutes());
469
+ }
470
+ break;
471
+
472
+ case 'second':
473
+ case 'seconds':
474
+ case 's':
475
+ $seconds += $intValue;
476
+ break;
477
+
478
+ default:
479
+ throw new InvalidArgumentException(
480
+ sprintf('Invalid part %s in definition %s', $part, $intervalDefinition)
481
+ );
482
+ }
483
+ }
484
+
485
+ return new static($years, $months, $weeks, $days, $hours, $minutes, $seconds);
486
+ }
487
+
488
+ /**
489
+ * Create a CarbonInterval instance from a DateInterval one. Can not instance
490
+ * DateInterval objects created from DateTime::diff() as you can't externally
491
+ * set the $days field.
492
+ *
493
+ * @param DateInterval $di
494
+ *
495
+ * @return static
496
+ */
497
+ public static function instance(DateInterval $di)
498
+ {
499
+ $instance = new static(static::getDateIntervalSpec($di));
500
+ $instance->invert = $di->invert;
501
+
502
+ return $instance;
503
+ }
504
+
505
+ /**
506
+ * Make a CarbonInterval instance from given variable if possible.
507
+ *
508
+ * Always return a new instance. Parse only strings and only these likely to be intervals (skip dates
509
+ * and recurrences). Throw an exception for invalid format, but otherwise return null.
510
+ *
511
+ * @param mixed $var
512
+ *
513
+ * @return static|null
514
+ */
515
+ public static function make($var)
516
+ {
517
+ if ($var instanceof DateInterval) {
518
+ return static::instance($var);
519
+ }
520
+
521
+ if (is_string($var)) {
522
+ $var = trim($var);
523
+
524
+ if (substr($var, 0, 1) === 'P') {
525
+ return new static($var);
526
+ }
527
+
528
+ if (preg_match('/^(?:\h*\d+(?:\.\d+)?\h*[a-z]+)+$/i', $var)) {
529
+ return static::fromString($var);
530
+ }
531
+ }
532
+ }
533
+
534
+ ///////////////////////////////////////////////////////////////////
535
+ /////////////////////// LOCALIZATION //////////////////////////////
536
+ ///////////////////////////////////////////////////////////////////
537
+
538
+ /**
539
+ * Initialize the translator instance if necessary.
540
+ *
541
+ * @return \Symfony\Component\Translation\TranslatorInterface
542
+ */
543
+ protected static function translator()
544
+ {
545
+ if (static::$translator === null) {
546
+ static::$translator = Translator::get();
547
+ }
548
+
549
+ return static::$translator;
550
+ }
551
+
552
+ /**
553
+ * Get the translator instance in use.
554
+ *
555
+ * @return \Symfony\Component\Translation\TranslatorInterface
556
+ */
557
+ public static function getTranslator()
558
+ {
559
+ return static::translator();
560
+ }
561
+
562
+ /**
563
+ * Set the translator instance to use.
564
+ *
565
+ * @param TranslatorInterface $translator
566
+ */
567
+ public static function setTranslator(TranslatorInterface $translator)
568
+ {
569
+ static::$translator = $translator;
570
+ }
571
+
572
+ /**
573
+ * Get the current translator locale.
574
+ *
575
+ * @return string
576
+ */
577
+ public static function getLocale()
578
+ {
579
+ return static::translator()->getLocale();
580
+ }
581
+
582
+ /**
583
+ * Set the current translator locale.
584
+ *
585
+ * @param string $locale
586
+ */
587
+ public static function setLocale($locale)
588
+ {
589
+ return static::translator()->setLocale($locale) !== false;
590
+ }
591
+
592
+ ///////////////////////////////////////////////////////////////////
593
+ ///////////////////////// GETTERS AND SETTERS /////////////////////
594
+ ///////////////////////////////////////////////////////////////////
595
+
596
+ /**
597
+ * Get a part of the CarbonInterval object.
598
+ *
599
+ * @param string $name
600
+ *
601
+ * @throws \InvalidArgumentException
602
+ *
603
+ * @return int|float
604
+ */
605
+ public function __get($name)
606
+ {
607
+ if (substr($name, 0, 5) === 'total') {
608
+ return $this->total(substr($name, 5));
609
+ }
610
+
611
+ switch ($name) {
612
+ case 'years':
613
+ return $this->y;
614
+
615
+ case 'months':
616
+ return $this->m;
617
+
618
+ case 'dayz':
619
+ return $this->d;
620
+
621
+ case 'hours':
622
+ return $this->h;
623
+
624
+ case 'minutes':
625
+ return $this->i;
626
+
627
+ case 'seconds':
628
+ return $this->s;
629
+
630
+ case 'weeks':
631
+ return (int) floor($this->d / static::getDaysPerWeek());
632
+
633
+ case 'daysExcludeWeeks':
634
+ case 'dayzExcludeWeeks':
635
+ return $this->d % static::getDaysPerWeek();
636
+
637
+ default:
638
+ throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
639
+ }
640
+ }
641
+
642
+ /**
643
+ * Set a part of the CarbonInterval object.
644
+ *
645
+ * @param string $name
646
+ * @param int $val
647
+ *
648
+ * @throws \InvalidArgumentException
649
+ */
650
+ public function __set($name, $val)
651
+ {
652
+ switch ($name) {
653
+ case 'years':
654
+ $this->y = $val;
655
+ break;
656
+
657
+ case 'months':
658
+ $this->m = $val;
659
+ break;
660
+
661
+ case 'weeks':
662
+ $this->d = $val * static::getDaysPerWeek();
663
+ break;
664
+
665
+ case 'dayz':
666
+ $this->d = $val;
667
+ break;
668
+
669
+ case 'hours':
670
+ $this->h = $val;
671
+ break;
672
+
673
+ case 'minutes':
674
+ $this->i = $val;
675
+ break;
676
+
677
+ case 'seconds':
678
+ $this->s = $val;
679
+ break;
680
+ }
681
+ }
682
+
683
+ /**
684
+ * Allow setting of weeks and days to be cumulative.
685
+ *
686
+ * @param int $weeks Number of weeks to set
687
+ * @param int $days Number of days to set
688
+ *
689
+ * @return static
690
+ */
691
+ public function weeksAndDays($weeks, $days)
692
+ {
693
+ $this->dayz = ($weeks * static::getDaysPerWeek()) + $days;
694
+
695
+ return $this;
696
+ }
697
+
698
+ /**
699
+ * Register a custom macro.
700
+ *
701
+ * @param string $name
702
+ * @param object|callable $macro
703
+ *
704
+ * @return void
705
+ */
706
+ public static function macro($name, $macro)
707
+ {
708
+ static::$macros[$name] = $macro;
709
+ }
710
+
711
+ /**
712
+ * Register macros from a mixin object.
713
+ *
714
+ * @param object $mixin
715
+ *
716
+ * @throws \ReflectionException
717
+ *
718
+ * @return void
719
+ */
720
+ public static function mixin($mixin)
721
+ {
722
+ $reflection = new ReflectionClass($mixin);
723
+
724
+ $methods = $reflection->getMethods(
725
+ ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
726
+ );
727
+
728
+ foreach ($methods as $method) {
729
+ $method->setAccessible(true);
730
+
731
+ static::macro($method->name, $method->invoke($mixin));
732
+ }
733
+ }
734
+
735
+ /**
736
+ * Check if macro is registered.
737
+ *
738
+ * @param string $name
739
+ *
740
+ * @return bool
741
+ */
742
+ public static function hasMacro($name)
743
+ {
744
+ return isset(static::$macros[$name]);
745
+ }
746
+
747
+ /**
748
+ * Call given macro.
749
+ *
750
+ * @param string $name
751
+ * @param array $parameters
752
+ *
753
+ * @return mixed
754
+ */
755
+ protected function callMacro($name, $parameters)
756
+ {
757
+ $macro = static::$macros[$name];
758
+
759
+ $reflection = new ReflectionFunction($macro);
760
+
761
+ $reflectionParameters = $reflection->getParameters();
762
+
763
+ $expectedCount = count($reflectionParameters);
764
+ $actualCount = count($parameters);
765
+
766
+ if ($expectedCount > $actualCount && $reflectionParameters[$expectedCount - 1]->name === 'self') {
767
+ for ($i = $actualCount; $i < $expectedCount - 1; $i++) {
768
+ $parameters[] = $reflectionParameters[$i]->getDefaultValue();
769
+ }
770
+
771
+ $parameters[] = $this;
772
+ }
773
+
774
+ if ($macro instanceof Closure && method_exists($macro, 'bindTo')) {
775
+ $macro = $macro->bindTo($this, get_class($this));
776
+ }
777
+
778
+ return call_user_func_array($macro, $parameters);
779
+ }
780
+
781
+ /**
782
+ * Allow fluent calls on the setters... CarbonInterval::years(3)->months(5)->day().
783
+ *
784
+ * Note: This is done using the magic method to allow static and instance methods to
785
+ * have the same names.
786
+ *
787
+ * @param string $name
788
+ * @param array $args
789
+ *
790
+ * @return static
791
+ */
792
+ public function __call($name, $args)
793
+ {
794
+ if (static::hasMacro($name)) {
795
+ return $this->callMacro($name, $args);
796
+ }
797
+
798
+ $arg = count($args) === 0 ? 1 : $args[0];
799
+
800
+ switch ($name) {
801
+ case 'years':
802
+ case 'year':
803
+ $this->years = $arg;
804
+ break;
805
+
806
+ case 'months':
807
+ case 'month':
808
+ $this->months = $arg;
809
+ break;
810
+
811
+ case 'weeks':
812
+ case 'week':
813
+ $this->dayz = $arg * static::getDaysPerWeek();
814
+ break;
815
+
816
+ case 'days':
817
+ case 'dayz':
818
+ case 'day':
819
+ $this->dayz = $arg;
820
+ break;
821
+
822
+ case 'hours':
823
+ case 'hour':
824
+ $this->hours = $arg;
825
+ break;
826
+
827
+ case 'minutes':
828
+ case 'minute':
829
+ $this->minutes = $arg;
830
+ break;
831
+
832
+ case 'seconds':
833
+ case 'second':
834
+ $this->seconds = $arg;
835
+ break;
836
+ }
837
+
838
+ return $this;
839
+ }
840
+
841
+ /**
842
+ * Get the current interval in a human readable format in the current locale.
843
+ *
844
+ * @param bool $short (false by default), returns short units if true
845
+ *
846
+ * @return string
847
+ */
848
+ public function forHumans($short = false)
849
+ {
850
+ $periods = array(
851
+ 'year' => array('y', $this->years),
852
+ 'month' => array('m', $this->months),
853
+ 'week' => array('w', $this->weeks),
854
+ 'day' => array('d', $this->daysExcludeWeeks),
855
+ 'hour' => array('h', $this->hours),
856
+ 'minute' => array('min', $this->minutes),
857
+ 'second' => array('s', $this->seconds),
858
+ );
859
+
860
+ $parts = array();
861
+ foreach ($periods as $unit => $options) {
862
+ list($shortUnit, $count) = $options;
863
+ if ($count > 0) {
864
+ $parts[] = static::translator()->transChoice($short ? $shortUnit : $unit, $count, array(':count' => $count));
865
+ }
866
+ }
867
+
868
+ return implode(' ', $parts);
869
+ }
870
+
871
+ /**
872
+ * Format the instance as a string using the forHumans() function.
873
+ *
874
+ * @return string
875
+ */
876
+ public function __toString()
877
+ {
878
+ return $this->forHumans();
879
+ }
880
+
881
+ /**
882
+ * Convert the interval to a CarbonPeriod.
883
+ *
884
+ * @return CarbonPeriod
885
+ */
886
+ public function toPeriod()
887
+ {
888
+ return CarbonPeriod::createFromArray(
889
+ array_merge(array($this), func_get_args())
890
+ );
891
+ }
892
+
893
+ /**
894
+ * Invert the interval.
895
+ *
896
+ * @return $this
897
+ */
898
+ public function invert()
899
+ {
900
+ $this->invert = $this->invert ? 0 : 1;
901
+
902
+ return $this;
903
+ }
904
+
905
+ /**
906
+ * Add the passed interval to the current instance.
907
+ *
908
+ * @param DateInterval $interval
909
+ *
910
+ * @return static
911
+ */
912
+ public function add(DateInterval $interval)
913
+ {
914
+ $sign = $interval->invert === 1 ? -1 : 1;
915
+
916
+ if (static::wasCreatedFromDiff($interval)) {
917
+ $this->dayz += $interval->days * $sign;
918
+ } else {
919
+ $this->years += $interval->y * $sign;
920
+ $this->months += $interval->m * $sign;
921
+ $this->dayz += $interval->d * $sign;
922
+ $this->hours += $interval->h * $sign;
923
+ $this->minutes += $interval->i * $sign;
924
+ $this->seconds += $interval->s * $sign;
925
+ }
926
+
927
+ return $this;
928
+ }
929
+
930
+ /**
931
+ * Multiply current instance given number of times
932
+ *
933
+ * @param float $factor
934
+ *
935
+ * @return $this
936
+ */
937
+ public function times($factor)
938
+ {
939
+ if ($factor < 0) {
940
+ $this->invert = $this->invert ? 0 : 1;
941
+ $factor = -$factor;
942
+ }
943
+
944
+ $this->years = round($this->years * $factor);
945
+ $this->months = round($this->months * $factor);
946
+ $this->dayz = round($this->dayz * $factor);
947
+ $this->hours = round($this->hours * $factor);
948
+ $this->minutes = round($this->minutes * $factor);
949
+ $this->seconds = round($this->seconds * $factor);
950
+
951
+ return $this;
952
+ }
953
+
954
+ /**
955
+ * Get the interval_spec string of a date interval.
956
+ *
957
+ * @param DateInterval $interval
958
+ *
959
+ * @return string
960
+ */
961
+ public static function getDateIntervalSpec(DateInterval $interval)
962
+ {
963
+ $date = array_filter(array(
964
+ static::PERIOD_YEARS => $interval->y,
965
+ static::PERIOD_MONTHS => $interval->m,
966
+ static::PERIOD_DAYS => $interval->d,
967
+ ));
968
+
969
+ $time = array_filter(array(
970
+ static::PERIOD_HOURS => $interval->h,
971
+ static::PERIOD_MINUTES => $interval->i,
972
+ static::PERIOD_SECONDS => $interval->s,
973
+ ));
974
+
975
+ $specString = static::PERIOD_PREFIX;
976
+
977
+ foreach ($date as $key => $value) {
978
+ $specString .= $value.$key;
979
+ }
980
+
981
+ if (count($time) > 0) {
982
+ $specString .= static::PERIOD_TIME_PREFIX;
983
+ foreach ($time as $key => $value) {
984
+ $specString .= $value.$key;
985
+ }
986
+ }
987
+
988
+ return $specString === static::PERIOD_PREFIX ? 'PT0S' : $specString;
989
+ }
990
+
991
+ /**
992
+ * Get the interval_spec string.
993
+ *
994
+ * @return string
995
+ */
996
+ public function spec()
997
+ {
998
+ return static::getDateIntervalSpec($this);
999
+ }
1000
+
1001
+ /**
1002
+ * Comparing 2 date intervals.
1003
+ *
1004
+ * @param DateInterval $a
1005
+ * @param DateInterval $b
1006
+ *
1007
+ * @return int
1008
+ */
1009
+ public static function compareDateIntervals(DateInterval $a, DateInterval $b)
1010
+ {
1011
+ $current = Carbon::now();
1012
+ $passed = $current->copy()->add($b);
1013
+ $current->add($a);
1014
+
1015
+ if ($current < $passed) {
1016
+ return -1;
1017
+ }
1018
+ if ($current > $passed) {
1019
+ return 1;
1020
+ }
1021
+
1022
+ return 0;
1023
+ }
1024
+
1025
+ /**
1026
+ * Comparing with passed interval.
1027
+ *
1028
+ * @param DateInterval $interval
1029
+ *
1030
+ * @return int
1031
+ */
1032
+ public function compare(DateInterval $interval)
1033
+ {
1034
+ return static::compareDateIntervals($this, $interval);
1035
+ }
1036
+
1037
+ /**
1038
+ * Convert overflowed values into bigger units.
1039
+ *
1040
+ * @return $this
1041
+ */
1042
+ public function cascade()
1043
+ {
1044
+ foreach (static::getFlipCascadeFactors() as $source => $cascade) {
1045
+ list($target, $factor) = $cascade;
1046
+
1047
+ if ($source === 'dayz' && $target === 'weeks') {
1048
+ continue;
1049
+ }
1050
+
1051
+ $value = $this->$source;
1052
+ $this->$source = $modulo = $value % $factor;
1053
+ $this->$target += ($value - $modulo) / $factor;
1054
+ }
1055
+
1056
+ return $this;
1057
+ }
1058
+
1059
+ /**
1060
+ * Get amount of given unit equivalent to the interval.
1061
+ *
1062
+ * @param string $unit
1063
+ *
1064
+ * @throws \InvalidArgumentException
1065
+ *
1066
+ * @return float
1067
+ */
1068
+ public function total($unit)
1069
+ {
1070
+ $realUnit = $unit = strtolower($unit);
1071
+
1072
+ if (in_array($unit, array('days', 'weeks'))) {
1073
+ $realUnit = 'dayz';
1074
+ } elseif (!in_array($unit, array('seconds', 'minutes', 'hours', 'dayz', 'months', 'years'))) {
1075
+ throw new InvalidArgumentException("Unknown unit '$unit'.");
1076
+ }
1077
+
1078
+ $result = 0;
1079
+ $cumulativeFactor = 0;
1080
+ $unitFound = false;
1081
+
1082
+ foreach (static::getFlipCascadeFactors() as $source => $cascade) {
1083
+ list($target, $factor) = $cascade;
1084
+
1085
+ if ($source === $realUnit) {
1086
+ $unitFound = true;
1087
+ $result += $this->$source;
1088
+ $cumulativeFactor = 1;
1089
+ }
1090
+
1091
+ if ($factor === false) {
1092
+ if ($unitFound) {
1093
+ break;
1094
+ }
1095
+
1096
+ $result = 0;
1097
+ $cumulativeFactor = 0;
1098
+
1099
+ continue;
1100
+ }
1101
+
1102
+ if ($target === $realUnit) {
1103
+ $unitFound = true;
1104
+ }
1105
+
1106
+ if ($cumulativeFactor) {
1107
+ $cumulativeFactor *= $factor;
1108
+ $result += $this->$target * $cumulativeFactor;
1109
+
1110
+ continue;
1111
+ }
1112
+
1113
+ $result = ($result + $this->$source) / $factor;
1114
+ }
1115
+
1116
+ if (isset($target) && !$cumulativeFactor) {
1117
+ $result += $this->$target;
1118
+ }
1119
+
1120
+ if (!$unitFound) {
1121
+ throw new \InvalidArgumentException("Unit $unit have no configuration to get total from other units.");
1122
+ }
1123
+
1124
+ if ($unit === 'weeks') {
1125
+ return $result / static::getDaysPerWeek();
1126
+ }
1127
+
1128
+ return $result;
1129
+ }
1130
+ }
app/vendor/nesbot/carbon/src/Carbon/CarbonPeriod.php ADDED
@@ -0,0 +1,1445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Carbon;
13
+
14
+ use BadMethodCallException;
15
+ use Closure;
16
+ use Countable;
17
+ use DateInterval;
18
+ use DateTime;
19
+ use DateTimeInterface;
20
+ use InvalidArgumentException;
21
+ use Iterator;
22
+ use ReflectionClass;
23
+ use ReflectionFunction;
24
+ use ReflectionMethod;
25
+ use RuntimeException;
26
+
27
+ /**
28
+ * Substitution of DatePeriod with some modifications and many more features.
29
+ * Fully compatible with PHP 5.3+!
30
+ *
31
+ * @method static CarbonPeriod start($date, $inclusive = null) Create instance specifying start date.
32
+ * @method static CarbonPeriod since($date, $inclusive = null) Alias for start().
33
+ * @method static CarbonPeriod sinceNow($inclusive = null) Create instance with start date set to now.
34
+ * @method static CarbonPeriod end($date = null, $inclusive = null) Create instance specifying end date.
35
+ * @method static CarbonPeriod until($date = null, $inclusive = null) Alias for end().
36
+ * @method static CarbonPeriod untilNow($inclusive = null) Create instance with end date set to now.
37
+ * @method static CarbonPeriod dates($start, $end = null) Create instance with start and end date.
38
+ * @method static CarbonPeriod between($start, $end = null) Create instance with start and end date.
39
+ * @method static CarbonPeriod recurrences($recurrences = null) Create instance with maximum number of recurrences.
40
+ * @method static CarbonPeriod times($recurrences = null) Alias for recurrences().
41
+ * @method static CarbonPeriod options($options = null) Create instance with options.
42
+ * @method static CarbonPeriod toggle($options, $state = null) Create instance with options toggled on or off.
43
+ * @method static CarbonPeriod filter($callback, $name = null) Create instance with filter added to the stack.
44
+ * @method static CarbonPeriod push($callback, $name = null) Alias for filter().
45
+ * @method static CarbonPeriod prepend($callback, $name = null) Create instance with filter prepened to the stack.
46
+ * @method static CarbonPeriod filters(array $filters) Create instance with filters stack.
47
+ * @method static CarbonPeriod interval($interval) Create instance with given date interval.
48
+ * @method static CarbonPeriod each($interval) Create instance with given date interval.
49
+ * @method static CarbonPeriod every($interval) Create instance with given date interval.
50
+ * @method static CarbonPeriod step($interval) Create instance with given date interval.
51
+ * @method static CarbonPeriod stepBy($interval) Create instance with given date interval.
52
+ * @method static CarbonPeriod invert() Create instance with inverted date interval.
53
+ * @method static CarbonPeriod years($years = 1) Create instance specifying a number of years for date interval.
54
+ * @method static CarbonPeriod year($years = 1) Alias for years().
55
+ * @method static CarbonPeriod months($months = 1) Create instance specifying a number of months for date interval.
56
+ * @method static CarbonPeriod month($months = 1) Alias for months().
57
+ * @method static CarbonPeriod weeks($weeks = 1) Create instance specifying a number of weeks for date interval.
58
+ * @method static CarbonPeriod week($weeks = 1) Alias for weeks().
59
+ * @method static CarbonPeriod days($days = 1) Create instance specifying a number of days for date interval.
60
+ * @method static CarbonPeriod dayz($days = 1) Alias for days().
61
+ * @method static CarbonPeriod day($days = 1) Alias for days().
62
+ * @method static CarbonPeriod hours($hours = 1) Create instance specifying a number of hours for date interval.
63
+ * @method static CarbonPeriod hour($hours = 1) Alias for hours().
64
+ * @method static CarbonPeriod minutes($minutes = 1) Create instance specifying a number of minutes for date interval.
65
+ * @method static CarbonPeriod minute($minutes = 1) Alias for minutes().
66
+ * @method static CarbonPeriod seconds($seconds = 1) Create instance specifying a number of seconds for date interval.
67
+ * @method static CarbonPeriod second($seconds = 1) Alias for seconds().
68
+ * @method CarbonPeriod start($date, $inclusive = null) Change the period start date.
69
+ * @method CarbonPeriod since($date, $inclusive = null) Alias for start().
70
+ * @method CarbonPeriod sinceNow($inclusive = null) Change the period start date to now.
71
+ * @method CarbonPeriod end($date = null, $inclusive = null) Change the period end date.
72
+ * @method CarbonPeriod until($date = null, $inclusive = null) Alias for end().
73
+ * @method CarbonPeriod untilNow($inclusive = null) Change the period end date to now.
74
+ * @method CarbonPeriod dates($start, $end = null) Change the period start and end date.
75
+ * @method CarbonPeriod recurrences($recurrences = null) Change the maximum number of recurrences.
76
+ * @method CarbonPeriod times($recurrences = null) Alias for recurrences().
77
+ * @method CarbonPeriod options($options = null) Change the period options.
78
+ * @method CarbonPeriod toggle($options, $state = null) Toggle given options on or off.
79
+ * @method CarbonPeriod filter($callback, $name = null) Add a filter to the stack.
80
+ * @method CarbonPeriod push($callback, $name = null) Alias for filter().
81
+ * @method CarbonPeriod prepend($callback, $name = null) Prepend a filter to the stack.
82
+ * @method CarbonPeriod filters(array $filters = array()) Set filters stack.
83
+ * @method CarbonPeriod interval($interval) Change the period date interval.
84
+ * @method CarbonPeriod invert() Invert the period date interval.
85
+ * @method CarbonPeriod years($years = 1) Set the years portion of the date interval.
86
+ * @method CarbonPeriod year($years = 1) Alias for years().
87
+ * @method CarbonPeriod months($months = 1) Set the months portion of the date interval.
88
+ * @method CarbonPeriod month($months = 1) Alias for months().
89
+ * @method CarbonPeriod weeks($weeks = 1) Set the weeks portion of the date interval.
90
+ * @method CarbonPeriod week($weeks = 1) Alias for weeks().
91
+ * @method CarbonPeriod days($days = 1) Set the days portion of the date interval.
92
+ * @method CarbonPeriod dayz($days = 1) Alias for days().
93
+ * @method CarbonPeriod day($days = 1) Alias for days().
94
+ * @method CarbonPeriod hours($hours = 1) Set the hours portion of the date interval.
95
+ * @method CarbonPeriod hour($hours = 1) Alias for hours().
96
+ * @method CarbonPeriod minutes($minutes = 1) Set the minutes portion of the date interval.
97
+ * @method CarbonPeriod minute($minutes = 1) Alias for minutes().
98
+ * @method CarbonPeriod seconds($seconds = 1) Set the seconds portion of the date interval.
99
+ * @method CarbonPeriod second($seconds = 1) Alias for seconds().
100
+ */
101
+ class CarbonPeriod implements Iterator, Countable
102
+ {
103
+ /**
104
+ * Built-in filters.
105
+ *
106
+ * @var string
107
+ */
108
+ const RECURRENCES_FILTER = 'Carbon\CarbonPeriod::filterRecurrences';
109
+ const END_DATE_FILTER = 'Carbon\CarbonPeriod::filterEndDate';
110
+
111
+ /**
112
+ * Special value which can be returned by filters to end iteration. Also a filter.
113
+ *
114
+ * @var string
115
+ */
116
+ const END_ITERATION = 'Carbon\CarbonPeriod::endIteration';
117
+
118
+ /**
119
+ * Available options.
120
+ *
121
+ * @var int
122
+ */
123
+ const EXCLUDE_START_DATE = 1;
124
+ const EXCLUDE_END_DATE = 2;
125
+
126
+ /**
127
+ * Number of maximum attempts before giving up on finding next valid date.
128
+ *
129
+ * @var int
130
+ */
131
+ const NEXT_MAX_ATTEMPTS = 1000;
132
+
133
+ /**
134
+ * The registered macros.
135
+ *
136
+ * @var array
137
+ */
138
+ protected static $macros = array();
139
+
140
+ /**
141
+ * Underlying date interval instance. Always present, one day by default.
142
+ *
143
+ * @var CarbonInterval
144
+ */
145
+ protected $dateInterval;
146
+
147
+ /**
148
+ * Whether current date interval was set by default.
149
+ *
150
+ * @var bool
151
+ */
152
+ protected $isDefaultInterval;
153
+
154
+ /**
155
+ * The filters stack.
156
+ *
157
+ * @var array
158
+ */
159
+ protected $filters = array();
160
+
161
+ /**
162
+ * Period start date. Applied on rewind. Always present, now by default.
163
+ *
164
+ * @var Carbon
165
+ */
166
+ protected $startDate;
167
+
168
+ /**
169
+ * Period end date. For inverted interval should be before the start date. Applied via a filter.
170
+ *
171
+ * @var Carbon|null
172
+ */
173
+ protected $endDate;
174
+
175
+ /**
176
+ * Limit for number of recurrences. Applied via a filter.
177
+ *
178
+ * @var int|null
179
+ */
180
+ protected $recurrences;
181
+
182
+ /**
183
+ * Iteration options.
184
+ *
185
+ * @var int
186
+ */
187
+ protected $options;
188
+
189
+ /**
190
+ * Index of current date. Always sequential, even if some dates are skipped by filters.
191
+ * Equal to null only before the first iteration.
192
+ *
193
+ * @var int
194
+ */
195
+ protected $key;
196
+
197
+ /**
198
+ * Current date. May temporarily hold unaccepted value when looking for a next valid date.
199
+ * Equal to null only before the first iteration.
200
+ *
201
+ * @var Carbon
202
+ */
203
+ protected $current;
204
+
205
+ /**
206
+ * Timezone of current date. Taken from the start date.
207
+ *
208
+ * @var \DateTimeZone|null
209
+ */
210
+ protected $timezone;
211
+
212
+ /**
213
+ * The cached validation result for current date.
214
+ *
215
+ * @var bool|static::END_ITERATION
216
+ */
217
+ protected $validationResult;
218
+
219
+ /**
220
+ * Create a new instance.
221
+ *
222
+ * @return static
223
+ */
224
+ public static function create()
225
+ {
226
+ return static::createFromArray(func_get_args());
227
+ }
228
+
229
+ /**
230
+ * Create a new instance from an array of parameters.
231
+ *
232
+ * @param array $params
233
+ *
234
+ * @return static
235
+ */
236
+ public static function createFromArray(array $params)
237
+ {
238
+ // PHP 5.3 equivalent of new static(...$params).
239
+ $reflection = new ReflectionClass(get_class());
240
+
241
+ return $reflection->newInstanceArgs($params);
242
+ }
243
+
244
+ /**
245
+ * Create CarbonPeriod from ISO 8601 string.
246
+ *
247
+ * @param string $iso
248
+ * @param int|null $options
249
+ *
250
+ * @return static
251
+ */
252
+ public static function createFromIso($iso, $options = null)
253
+ {
254
+ $params = static::parseIso8601($iso);
255
+
256
+ $instance = static::createFromArray($params);
257
+
258
+ if ($options !== null) {
259
+ $instance->setOptions($options);
260
+ }
261
+
262
+ return $instance;
263
+ }
264
+
265
+ /**
266
+ * Return whether given interval contains non zero value of any time unit.
267
+ *
268
+ * @param \DateInterval $interval
269
+ *
270
+ * @return bool
271
+ */
272
+ protected static function intervalHasTime(DateInterval $interval)
273
+ {
274
+ // The array_key_exists and get_object_vars are used as a workaround to check microsecond support.
275
+ // Both isset and property_exists will fail on PHP 7.0.14 - 7.0.21 due to the following bug:
276
+ // https://bugs.php.net/bug.php?id=74852
277
+ return $interval->h || $interval->i || $interval->s || array_key_exists('f', get_object_vars($interval)) && $interval->f;
278
+ }
279
+
280
+ /**
281
+ * Return whether given callable is a string pointing to one of Carbon's is* methods
282
+ * and should be automatically converted to a filter callback.
283
+ *
284
+ * @param callable $callable
285
+ *
286
+ * @return bool
287
+ */
288
+ protected static function isCarbonPredicateMethod($callable)
289
+ {
290
+ return is_string($callable) && substr($callable, 0, 2) === 'is' && (method_exists('Carbon\Carbon', $callable) || Carbon::hasMacro($callable));
291
+ }
292
+
293
+ /**
294
+ * Return whether given variable is an ISO 8601 specification.
295
+ *
296
+ * Note: Check is very basic, as actual validation will be done later when parsing.
297
+ * We just want to ensure that variable is not any other type of a valid parameter.
298
+ *
299
+ * @param mixed $var
300
+ *
301
+ * @return bool
302
+ */
303
+ protected static function isIso8601($var)
304
+ {
305
+ if (!is_string($var)) {
306
+ return false;
307
+ }
308
+
309
+ // Match slash but not within a timezone name.
310
+ $part = '[a-z]+(?:[_-][a-z]+)*';
311
+
312
+ preg_match("#\b$part/$part\b|(/)#i", $var, $match);
313
+
314
+ return isset($match[1]);
315
+ }
316
+
317
+ /**
318
+ * Parse given ISO 8601 string into an array of arguments.
319
+ *
320
+ * @param string $iso
321
+ *
322
+ * @return array
323
+ */
324
+ protected static function parseIso8601($iso)
325
+ {
326
+ $result = array();
327
+
328
+ $interval = null;
329
+ $start = null;
330
+ $end = null;
331
+
332
+ foreach (explode('/', $iso) as $key => $part) {
333
+ if ($key === 0 && preg_match('/^R([0-9]*)$/', $part, $match)) {
334
+ $parsed = strlen($match[1]) ? (int) $match[1] : null;
335
+ } elseif ($interval === null && $parsed = CarbonInterval::make($part)) {
336
+ $interval = $part;
337
+ } elseif ($start === null && $parsed = Carbon::make($part)) {
338
+ $start = $part;
339
+ } elseif ($end === null && $parsed = Carbon::make(static::addMissingParts($start, $part))) {
340
+ $end = $part;
341
+ } else {
342
+ throw new InvalidArgumentException("Invalid ISO 8601 specification: $iso.");
343
+ }
344
+
345
+ $result[] = $parsed;
346
+ }
347
+
348
+ return $result;
349
+ }
350
+
351
+ /**
352
+ * Add missing parts of the target date from the soure date.
353
+ *
354
+ * @param string $source
355
+ * @param string $target
356
+ *
357
+ * @return string
358
+ */
359
+ protected static function addMissingParts($source, $target)
360
+ {
361
+ $pattern = '/'.preg_replace('/[0-9]+/', '[0-9]+', preg_quote($target, '/')).'$/';
362
+
363
+ $result = preg_replace($pattern, $target, $source, 1, $count);
364
+
365
+ return $count ? $result : $target;
366
+ }
367
+
368
+ /**
369
+ * Register a custom macro.
370
+ *
371
+ * @param string $name
372
+ * @param object|callable $macro
373
+ *
374
+ * @return void
375
+ */
376
+ public static function macro($name, $macro)
377
+ {
378
+ static::$macros[$name] = $macro;
379
+ }
380
+
381
+ /**
382
+ * Register macros from a mixin object.
383
+ *
384
+ * @param object $mixin
385
+ *
386
+ * @throws \ReflectionException
387
+ *
388
+ * @return void
389
+ */
390
+ public static function mixin($mixin)
391
+ {
392
+ $reflection = new ReflectionClass($mixin);
393
+
394
+ $methods = $reflection->getMethods(
395
+ ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
396
+ );
397
+
398
+ foreach ($methods as $method) {
399
+ $method->setAccessible(true);
400
+
401
+ static::macro($method->name, $method->invoke($mixin));
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Check if macro is registered.
407
+ *
408
+ * @param string $name
409
+ *
410
+ * @return bool
411
+ */
412
+ public static function hasMacro($name)
413
+ {
414
+ return isset(static::$macros[$name]);
415
+ }
416
+
417
+ /**
418
+ * Provide static proxy for instance aliases.
419
+ *
420
+ * @param string $method
421
+ * @param array $parameters
422
+ *
423
+ * @return mixed
424
+ */
425
+ public static function __callStatic($method, $parameters)
426
+ {
427
+ return call_user_func_array(
428
+ array(new static, $method), $parameters
429
+ );
430
+ }
431
+
432
+ /**
433
+ * CarbonPeriod constructor.
434
+ *
435
+ * @throws InvalidArgumentException
436
+ */
437
+ public function __construct()
438
+ {
439
+ // Parse and assign arguments one by one. First argument may be an ISO 8601 spec,
440
+ // which will be first parsed into parts and then processed the same way.
441
+ $arguments = func_get_args();
442
+
443
+ if (count($arguments) && static::isIso8601($iso = $arguments[0])) {
444
+ array_splice($arguments, 0, 1, static::parseIso8601($iso));
445
+ }
446
+
447
+ foreach ($arguments as $argument) {
448
+ if ($this->dateInterval === null && $parsed = CarbonInterval::make($argument)) {
449
+ $this->setDateInterval($parsed);
450
+ } elseif ($this->startDate === null && $parsed = Carbon::make($argument)) {
451
+ $this->setStartDate($parsed);
452
+ } elseif ($this->endDate === null && $parsed = Carbon::make($argument)) {
453
+ $this->setEndDate($parsed);
454
+ } elseif ($this->recurrences === null && $this->endDate === null && is_numeric($argument)) {
455
+ $this->setRecurrences($argument);
456
+ } elseif ($this->options === null && (is_int($argument) || $argument === null)) {
457
+ $this->setOptions($argument);
458
+ } else {
459
+ throw new InvalidArgumentException('Invalid constructor parameters.');
460
+ }
461
+ }
462
+
463
+ if ($this->startDate === null) {
464
+ $this->setStartDate(Carbon::now());
465
+ }
466
+
467
+ if ($this->dateInterval === null) {
468
+ $this->setDateInterval(CarbonInterval::day());
469
+
470
+ $this->isDefaultInterval = true;
471
+ }
472
+
473
+ if ($this->options === null) {
474
+ $this->setOptions(0);
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Change the period date interval.
480
+ *
481
+ * @param DateInterval|string $interval
482
+ *
483
+ * @throws \InvalidArgumentException
484
+ *
485
+ * @return $this
486
+ */
487
+ public function setDateInterval($interval)
488
+ {
489
+ if (!$interval = CarbonInterval::make($interval)) {
490
+ throw new InvalidArgumentException('Invalid interval.');
491
+ }
492
+
493
+ if ($interval->spec() === 'PT0S') {
494
+ throw new InvalidArgumentException('Empty interval is not accepted.');
495
+ }
496
+
497
+ $this->dateInterval = $interval;
498
+
499
+ $this->isDefaultInterval = false;
500
+
501
+ $this->handleChangedParameters();
502
+
503
+ return $this;
504
+ }
505
+
506
+ /**
507
+ * Invert the period date interval.
508
+ *
509
+ * @return $this
510
+ */
511
+ public function invertDateInterval()
512
+ {
513
+ $interval = $this->dateInterval->invert();
514
+
515
+ return $this->setDateInterval($interval);
516
+ }
517
+
518
+ /**
519
+ * Set start and end date.
520
+ *
521
+ * @param DateTime|DateTimeInterface|string $start
522
+ * @param DateTime|DateTimeInterface|string|null $end
523
+ *
524
+ * @return $this
525
+ */
526
+ public function setDates($start, $end)
527
+ {
528
+ $this->setStartDate($start);
529
+ $this->setEndDate($end);
530
+
531
+ return $this;
532
+ }
533
+
534
+ /**
535
+ * Change the period options.
536
+ *
537
+ * @param int|null $options
538
+ *
539
+ * @throws \InvalidArgumentException
540
+ *
541
+ * @return $this
542
+ */
543
+ public function setOptions($options)
544
+ {
545
+ if (!is_int($options) && !is_null($options)) {
546
+ throw new InvalidArgumentException('Invalid options.');
547
+ }
548
+
549
+ $this->options = $options ?: 0;
550
+
551
+ $this->handleChangedParameters();
552
+
553
+ return $this;
554
+ }
555
+
556
+ /**
557
+ * Get the period options.
558
+ *
559
+ * @return int
560
+ */
561
+ public function getOptions()
562
+ {
563
+ return $this->options;
564
+ }
565
+
566
+ /**
567
+ * Toggle given options on or off.
568
+ *
569
+ * @param int $options
570
+ * @param bool|null $state
571
+ *
572
+ * @throws \InvalidArgumentException
573
+ *
574
+ * @return $this
575
+ */
576
+ public function toggleOptions($options, $state = null)
577
+ {
578
+ if ($state === null) {
579
+ $state = ($this->options & $options) !== $options;
580
+ }
581
+
582
+ return $this->setOptions($state ?
583
+ $this->options | $options :
584
+ $this->options & ~$options
585
+ );
586
+ }
587
+
588
+ /**
589
+ * Toggle EXCLUDE_START_DATE option.
590
+ *
591
+ * @param bool $state
592
+ *
593
+ * @return $this
594
+ */
595
+ public function excludeStartDate($state = true)
596
+ {
597
+ return $this->toggleOptions(static::EXCLUDE_START_DATE, $state);
598
+ }
599
+
600
+ /**
601
+ * Toggle EXCLUDE_END_DATE option.
602
+ *
603
+ * @param bool $state
604
+ *
605
+ * @return $this
606
+ */
607
+ public function excludeEndDate($state = true)
608
+ {
609
+ return $this->toggleOptions(static::EXCLUDE_END_DATE, $state);
610
+ }
611
+
612
+ /**
613
+ * Get the underlying date interval.
614
+ *
615
+ * @return CarbonInterval
616
+ */
617
+ public function getDateInterval()
618
+ {
619
+ return $this->dateInterval->copy();
620
+ }
621
+
622
+ /**
623
+ * Get start date of the period.
624
+ *
625
+ * @return Carbon
626
+ */
627
+ public function getStartDate()
628
+ {
629
+ return $this->startDate->copy();
630
+ }
631
+
632
+ /**
633
+ * Get end date of the period.
634
+ *
635
+ * @return Carbon|null
636
+ */
637
+ public function getEndDate()
638
+ {
639
+ if ($this->endDate) {
640
+ return $this->endDate->copy();
641
+ }
642
+ }
643
+
644
+ /**
645
+ * Get number of recurrences.
646
+ *
647
+ * @return int|null
648
+ */
649
+ public function getRecurrences()
650
+ {
651
+ return $this->recurrences;
652
+ }
653
+
654
+ /**
655
+ * Returns true if the start date should be excluded.
656
+ *
657
+ * @return bool
658
+ */
659
+ public function isStartExcluded()
660
+ {
661
+ return ($this->options & static::EXCLUDE_START_DATE) !== 0;
662
+ }
663
+
664
+ /**
665
+ * Returns true if the end date should be excluded.
666
+ *
667
+ * @return bool
668
+ */
669
+ public function isEndExcluded()
670
+ {
671
+ return ($this->options & static::EXCLUDE_END_DATE) !== 0;
672
+ }
673
+
674
+ /**
675
+ * Add a filter to the stack.
676
+ *
677
+ * @param callable $callback
678
+ * @param string $name
679
+ *
680
+ * @return $this
681
+ */
682
+ public function addFilter($callback, $name = null)
683
+ {
684
+ $tuple = $this->createFilterTuple(func_get_args());
685
+
686
+ $this->filters[] = $tuple;
687
+
688
+ $this->handleChangedParameters();
689
+
690
+ return $this;
691
+ }
692
+
693
+ /**
694
+ * Prepend a filter to the stack.
695
+ *
696
+ * @param callable $callback
697
+ * @param string $name
698
+ *
699
+ * @return $this
700
+ */
701
+ public function prependFilter($callback, $name = null)
702
+ {
703
+ $tuple = $this->createFilterTuple(func_get_args());
704
+
705
+ array_unshift($this->filters, $tuple);
706
+
707
+ $this->handleChangedParameters();
708
+
709
+ return $this;
710
+ }
711
+
712
+ /**
713
+ * Create a filter tuple from raw parameters.
714
+ *
715
+ * Will create an automatic filter callback for one of Carbon's is* methods.
716
+ *
717
+ * @param array $parameters
718
+ *
719
+ * @return array
720
+ */
721
+ protected function createFilterTuple(array $parameters)
722
+ {
723
+ $method = array_shift($parameters);
724
+
725
+ if (!$this->isCarbonPredicateMethod($method)) {
726
+ return array($method, array_shift($parameters));
727
+ }
728
+
729
+ return array(function ($date) use ($method, $parameters) {
730
+ return call_user_func_array(array($date, $method), $parameters);
731
+ }, $method);
732
+ }
733
+
734
+ /**
735
+ * Remove a filter by instance or name.
736
+ *
737
+ * @param callable|string $filter
738
+ *
739
+ * @return $this
740
+ */
741
+ public function removeFilter($filter)
742
+ {
743
+ $key = is_callable($filter) ? 0 : 1;
744
+
745
+ $this->filters = array_values(array_filter(
746
+ $this->filters,
747
+ function ($tuple) use ($key, $filter) {
748
+ return $tuple[$key] !== $filter;
749
+ }
750
+ ));
751
+
752
+ $this->updateInternalState();
753
+
754
+ $this->handleChangedParameters();
755
+
756
+ return $this;
757
+ }
758
+
759
+ /**
760
+ * Return whether given instance or name is in the filter stack.
761
+ *
762
+ * @param callable|string $filter
763
+ *
764
+ * @return bool
765
+ */
766
+ public function hasFilter($filter)
767
+ {
768
+ $key = is_callable($filter) ? 0 : 1;
769
+
770
+ foreach ($this->filters as $tuple) {
771
+ if ($tuple[$key] === $filter) {
772
+ return true;
773
+ }
774
+ }
775
+
776
+ return false;
777
+ }
778
+
779
+ /**
780
+ * Get filters stack.
781
+ *
782
+ * @return array
783
+ */
784
+ public function getFilters()
785
+ {
786
+ return $this->filters;
787
+ }
788
+
789
+ /**
790
+ * Set filters stack.
791
+ *
792
+ * @param array $filters
793
+ *
794
+ * @return $this
795
+ */
796
+ public function setFilters(array $filters)
797
+ {
798
+ $this->filters = $filters;
799
+
800
+ $this->updateInternalState();
801
+
802
+ $this->handleChangedParameters();
803
+
804
+ return $this;
805
+ }
806
+
807
+ /**
808
+ * Reset filters stack.
809
+ *
810
+ * @return $this
811
+ */
812
+ public function resetFilters()
813
+ {
814
+ $this->filters = array();
815
+
816
+ if ($this->endDate !== null) {
817
+ $this->filters[] = array(static::END_DATE_FILTER, null);
818
+ }
819
+
820
+ if ($this->recurrences !== null) {
821
+ $this->filters[] = array(static::RECURRENCES_FILTER, null);
822
+ }
823
+
824
+ $this->handleChangedParameters();
825
+
826
+ return $this;
827
+ }
828
+
829
+ /**
830
+ * Update properties after removing built-in filters.
831
+ *
832
+ * @return void
833
+ */
834
+ protected function updateInternalState()
835
+ {
836
+ if (!$this->hasFilter(static::END_DATE_FILTER)) {
837
+ $this->endDate = null;
838
+ }
839
+
840
+ if (!$this->hasFilter(static::RECURRENCES_FILTER)) {
841
+ $this->recurrences = null;
842
+ }
843
+ }
844
+
845
+ /**
846
+ * Add a recurrences filter (set maximum number of recurrences).
847
+ *
848
+ * @param int|null $recurrences
849
+ *
850
+ * @throws \InvalidArgumentException
851
+ *
852
+ * @return $this
853
+ */
854
+ public function setRecurrences($recurrences)
855
+ {
856
+ if (!is_numeric($recurrences) && !is_null($recurrences) || $recurrences < 0) {
857
+ throw new InvalidArgumentException('Invalid number of recurrences.');
858
+ }
859
+
860
+ if ($recurrences === null) {
861
+ return $this->removeFilter(static::RECURRENCES_FILTER);
862
+ }
863
+
864
+ $this->recurrences = (int) $recurrences;
865
+
866
+ if (!$this->hasFilter(static::RECURRENCES_FILTER)) {
867
+ return $this->addFilter(static::RECURRENCES_FILTER);
868
+ }
869
+
870
+ $this->handleChangedParameters();
871
+
872
+ return $this;
873
+ }
874
+
875
+ /**
876
+ * Recurrences filter callback (limits number of recurrences).
877
+ *
878
+ * @param \Carbon\Carbon $current
879
+ * @param int $key
880
+ *
881
+ * @return bool|static::END_ITERATION
882
+ */
883
+ protected function filterRecurrences($current, $key)
884
+ {
885
+ if ($key < $this->recurrences) {
886
+ return true;
887
+ }
888
+
889
+ return static::END_ITERATION;
890
+ }
891
+
892
+ /**
893
+ * Change the period start date.
894
+ *
895
+ * @param DateTime|DateTimeInterface|string $date
896
+ * @param bool|null $inclusive
897
+ *
898
+ * @throws \InvalidArgumentException
899
+ *
900
+ * @return $this
901
+ */
902
+ public function setStartDate($date, $inclusive = null)
903
+ {
904
+ if (!$date = Carbon::make($date)) {
905
+ throw new InvalidArgumentException('Invalid start date.');
906
+ }
907
+
908
+ $this->startDate = $date;
909
+
910
+ if ($inclusive !== null) {
911
+ $this->toggleOptions(static::EXCLUDE_START_DATE, !$inclusive);
912
+ }
913
+
914
+ return $this;
915
+ }
916
+
917
+ /**
918
+ * Change the period end date.
919
+ *
920
+ * @param DateTime|DateTimeInterface|string|null $date
921
+ * @param bool|null $inclusive
922
+ *
923
+ * @throws \InvalidArgumentException
924
+ *
925
+ * @return $this
926
+ */
927
+ public function setEndDate($date, $inclusive = null)
928
+ {
929
+ if (!is_null($date) && !$date = Carbon::make($date)) {
930
+ throw new InvalidArgumentException('Invalid end date.');
931
+ }
932
+
933
+ if (!$date) {
934
+ return $this->removeFilter(static::END_DATE_FILTER);
935
+ }
936
+
937
+ $this->endDate = $date;
938
+
939
+ if ($inclusive !== null) {
940
+ $this->toggleOptions(static::EXCLUDE_END_DATE, !$inclusive);
941
+ }
942
+
943
+ if (!$this->hasFilter(static::END_DATE_FILTER)) {
944
+ return $this->addFilter(static::END_DATE_FILTER);
945
+ }
946
+
947
+ $this->handleChangedParameters();
948
+
949
+ return $this;
950
+ }
951
+
952
+ /**
953
+ * End date filter callback.
954
+ *
955
+ * @param \Carbon\Carbon $current
956
+ *
957
+ * @return bool|static::END_ITERATION
958
+ */
959
+ protected function filterEndDate($current)
960
+ {
961
+ if (!$this->isEndExcluded() && $current == $this->endDate) {
962
+ return true;
963
+ }
964
+
965
+ if ($this->dateInterval->invert ? $current > $this->endDate : $current < $this->endDate) {
966
+ return true;
967
+ }
968
+
969
+ return static::END_ITERATION;
970
+ }
971
+
972
+ /**
973
+ * End iteration filter callback.
974
+ *
975
+ * @return static::END_ITERATION
976
+ */
977
+ protected function endIteration()
978
+ {
979
+ return static::END_ITERATION;
980
+ }
981
+
982
+ /**
983
+ * Handle change of the parameters.
984
+ *
985
+ * @return void
986
+ */
987
+ protected function handleChangedParameters()
988
+ {
989
+ $this->validationResult = null;
990
+ }
991
+
992
+ /**
993
+ * Validate current date and stop iteration when necessary.
994
+ *
995
+ * Returns true when current date is valid, false if it is not, or static::END_ITERATION
996
+ * when iteration should be stopped.
997
+ *
998
+ * @return bool|static::END_ITERATION
999
+ */
1000
+ protected function validateCurrentDate()
1001
+ {
1002
+ if ($this->current === null) {
1003
+ $this->rewind();
1004
+ }
1005
+
1006
+ // Check after the first rewind to avoid repeating the initial validation.
1007
+ if ($this->validationResult !== null) {
1008
+ return $this->validationResult;
1009
+ }
1010
+
1011
+ return $this->validationResult = $this->checkFilters();
1012
+ }
1013
+
1014
+ /**
1015
+ * Check whether current value and key pass all the filters.
1016
+ *
1017
+ * @return bool|static::END_ITERATION
1018
+ */
1019
+ protected function checkFilters()
1020
+ {
1021
+ $current = $this->prepareForReturn($this->current);
1022
+
1023
+ foreach ($this->filters as $tuple) {
1024
+ $result = call_user_func(
1025
+ $tuple[0], $current->copy(), $this->key, $this
1026
+ );
1027
+
1028
+ if ($result === static::END_ITERATION) {
1029
+ return static::END_ITERATION;
1030
+ }
1031
+
1032
+ if (!$result) {
1033
+ return false;
1034
+ }
1035
+ }
1036
+
1037
+ return true;
1038
+ }
1039
+
1040
+ /**
1041
+ * Prepare given date to be returned to the external logic.
1042
+ *
1043
+ * @param Carbon $date
1044
+ *
1045
+ * @return Carbon
1046
+ */
1047
+ protected function prepareForReturn(Carbon $date)
1048
+ {
1049
+ $date = $date->copy();
1050
+
1051
+ if ($this->timezone) {
1052
+ $date->setTimezone($this->timezone);
1053
+ }
1054
+
1055
+ return $date;
1056
+ }
1057
+
1058
+ /**
1059
+ * Check if the current position is valid.
1060
+ *
1061
+ * @return bool
1062
+ */
1063
+ public function valid()
1064
+ {
1065
+ return $this->validateCurrentDate() === true;
1066
+ }
1067
+
1068
+ /**
1069
+ * Return the current key.
1070
+ *
1071
+ * @return int|null
1072
+ */
1073
+ public function key()
1074
+ {
1075
+ if ($this->valid()) {
1076
+ return $this->key;
1077
+ }
1078
+ }
1079
+
1080
+ /**
1081
+ * Return the current date.
1082
+ *
1083
+ * @return Carbon|null
1084
+ */
1085
+ public function current()
1086
+ {
1087
+ if ($this->valid()) {
1088
+ return $this->prepareForReturn($this->current);
1089
+ }
1090
+ }
1091
+
1092
+ /**
1093
+ * Move forward to the next date.
1094
+ *
1095
+ * @throws \RuntimeException
1096
+ *
1097
+ * @return void
1098
+ */
1099
+ public function next()
1100
+ {
1101
+ if ($this->current === null) {
1102
+ $this->rewind();
1103
+ }
1104
+
1105
+ if ($this->validationResult !== static::END_ITERATION) {
1106
+ $this->key++;
1107
+
1108
+ $this->incrementCurrentDateUntilValid();
1109
+ }
1110
+ }
1111
+
1112
+ /**
1113
+ * Rewind to the start date.
1114
+ *
1115
+ * Iterating over a date in the UTC timezone avoids bug during backward DST change.
1116
+ *
1117
+ * @see https://bugs.php.net/bug.php?id=72255
1118
+ * @see https://bugs.php.net/bug.php?id=74274
1119
+ * @see https://wiki.php.net/rfc/datetime_and_daylight_saving_time
1120
+ *
1121
+ * @throws \RuntimeException
1122
+ *
1123
+ * @return void
1124
+ */
1125
+ public function rewind()
1126
+ {
1127
+ $this->key = 0;
1128
+ $this->current = $this->startDate->copy();
1129
+ $this->timezone = static::intervalHasTime($this->dateInterval) ? $this->current->getTimezone() : null;
1130
+
1131
+ if ($this->timezone) {
1132
+ $this->current->setTimezone('UTC');
1133
+ }
1134
+
1135
+ $this->validationResult = null;
1136
+
1137
+ if ($this->isStartExcluded() || $this->validateCurrentDate() === false) {
1138
+ $this->incrementCurrentDateUntilValid();
1139
+ }
1140
+ }
1141
+
1142
+ /**
1143
+ * Skip iterations and returns iteration state (false if ended, true if still valid).
1144
+ *
1145
+ * @param int $count steps number to skip (1 by default)
1146
+ *
1147
+ * @return bool
1148
+ */
1149
+ public function skip($count = 1)
1150
+ {
1151
+ for ($i = $count; $this->valid() && $i > 0; $i--) {
1152
+ $this->next();
1153
+ }
1154
+
1155
+ return $this->valid();
1156
+ }
1157
+
1158
+ /**
1159
+ * Keep incrementing the current date until a valid date is found or the iteration is ended.
1160
+ *
1161
+ * @throws \RuntimeException
1162
+ *
1163
+ * @return void
1164
+ */
1165
+ protected function incrementCurrentDateUntilValid()
1166
+ {
1167
+ $attempts = 0;
1168
+
1169
+ do {
1170
+ $this->current->add($this->dateInterval);
1171
+
1172
+ $this->validationResult = null;
1173
+
1174
+ if (++$attempts > static::NEXT_MAX_ATTEMPTS) {
1175
+ throw new RuntimeException('Could not find next valid date.');
1176
+ }
1177
+ } while ($this->validateCurrentDate() === false);
1178
+ }
1179
+
1180
+ /**
1181
+ * Format the date period as ISO 8601.
1182
+ *
1183
+ * @return string
1184
+ */
1185
+ public function toIso8601String()
1186
+ {
1187
+ $parts = array();
1188
+
1189
+ if ($this->recurrences !== null) {
1190
+ $parts[] = 'R'.$this->recurrences;
1191
+ }
1192
+
1193
+ $parts[] = $this->startDate->toIso8601String();
1194
+
1195
+ $parts[] = $this->dateInterval->spec();
1196
+
1197
+ if ($this->endDate !== null) {
1198
+ $parts[] = $this->endDate->toIso8601String();
1199
+ }
1200
+
1201
+ return implode('/', $parts);
1202
+ }
1203
+
1204
+ /**
1205
+ * Convert the date period into a string.
1206
+ *
1207
+ * @return string
1208
+ */
1209
+ public function toString()
1210
+ {
1211
+ $translator = Carbon::getTranslator();
1212
+
1213
+ $parts = array();
1214
+
1215
+ $format = !$this->startDate->isStartOfDay() || $this->endDate && !$this->endDate->isStartOfDay()
1216
+ ? 'Y-m-d H:i:s'
1217
+ : 'Y-m-d';
1218
+
1219
+ if ($this->recurrences !== null) {
1220
+ $parts[] = $translator->transChoice('period_recurrences', $this->recurrences, array(':count' => $this->recurrences));
1221
+ }
1222
+
1223
+ $parts[] = $translator->trans('period_interval', array(':interval' => $this->dateInterval->forHumans()));
1224
+
1225
+ $parts[] = $translator->trans('period_start_date', array(':date' => $this->startDate->format($format)));
1226
+
1227
+ if ($this->endDate !== null) {
1228
+ $parts[] = $translator->trans('period_end_date', array(':date' => $this->endDate->format($format)));
1229
+ }
1230
+
1231
+ $result = implode(' ', $parts);
1232
+
1233
+ return mb_strtoupper(mb_substr($result, 0, 1)).mb_substr($result, 1);
1234
+ }
1235
+
1236
+ /**
1237
+ * Format the date period as ISO 8601.
1238
+ *
1239
+ * @return string
1240
+ */
1241
+ public function spec()
1242
+ {
1243
+ return $this->toIso8601String();
1244
+ }
1245
+
1246
+ /**
1247
+ * Convert the date period into an array without changing current iteration state.
1248
+ *
1249
+ * @return array
1250
+ */
1251
+ public function toArray()
1252
+ {
1253
+ $state = array(
1254
+ $this->key,
1255
+ $this->current ? $this->current->copy() : null,
1256
+ $this->validationResult,
1257
+ );
1258
+
1259
+ $result = iterator_to_array($this);
1260
+
1261
+ list(
1262
+ $this->key,
1263
+ $this->current,
1264
+ $this->validationResult
1265
+ ) = $state;
1266
+
1267
+ return $result;
1268
+ }
1269
+
1270
+ /**
1271
+ * Count dates in the date period.
1272
+ *
1273
+ * @return int
1274
+ */
1275
+ public function count()
1276
+ {
1277
+ return count($this->toArray());
1278
+ }
1279
+
1280
+ /**
1281
+ * Return the first date in the date period.
1282
+ *
1283
+ * @return Carbon|null
1284
+ */
1285
+ public function first()
1286
+ {
1287
+ if ($array = $this->toArray()) {
1288
+ return $array[0];
1289
+ }
1290
+ }
1291
+
1292
+ /**
1293
+ * Return the last date in the date period.
1294
+ *
1295
+ * @return Carbon|null
1296
+ */
1297
+ public function last()
1298
+ {
1299
+ if ($array = $this->toArray()) {
1300
+ return $array[count($array) - 1];
1301
+ }
1302
+ }
1303
+
1304
+ /**
1305
+ * Call given macro.
1306
+ *
1307
+ * @param string $name
1308
+ * @param array $parameters
1309
+ *
1310
+ * @return mixed
1311
+ */
1312
+ protected function callMacro($name, $parameters)
1313
+ {
1314
+ $macro = static::$macros[$name];
1315
+
1316
+ $reflection = new ReflectionFunction($macro);
1317
+
1318
+ $reflectionParameters = $reflection->getParameters();
1319
+
1320
+ $expectedCount = count($reflectionParameters);
1321
+ $actualCount = count($parameters);
1322
+
1323
+ if ($expectedCount > $actualCount && $reflectionParameters[$expectedCount - 1]->name === 'self') {
1324
+ for ($i = $actualCount; $i < $expectedCount - 1; $i++) {
1325
+ $parameters[] = $reflectionParameters[$i]->getDefaultValue();
1326
+ }
1327
+
1328
+ $parameters[] = $this;
1329
+ }
1330
+
1331
+ if ($macro instanceof Closure && method_exists($macro, 'bindTo')) {
1332
+ $macro = $macro->bindTo($this, get_class($this));
1333
+ }
1334
+
1335
+ return call_user_func_array($macro, $parameters);
1336
+ }
1337
+
1338
+ /**
1339
+ * Convert the date period into a string.
1340
+ *
1341
+ * @return string
1342
+ */
1343
+ public function __toString()
1344
+ {
1345
+ return $this->toString();
1346
+ }
1347
+
1348
+ /**
1349
+ * Add aliases for setters.
1350
+ *
1351
+ * CarbonPeriod::days(3)->hours(5)->invert()
1352
+ * ->sinceNow()->until('2010-01-10')
1353
+ * ->filter(...)
1354
+ * ->count()
1355
+ *
1356
+ * Note: We use magic method to let static and instance aliases with the same names.
1357
+ *
1358
+ * @param string $method
1359
+ * @param array $parameters
1360
+ *
1361
+ * @return mixed
1362
+ */
1363
+ public function __call($method, $parameters)
1364
+ {
1365
+ if (static::hasMacro($method)) {
1366
+ return $this->callMacro($method, $parameters);
1367
+ }
1368
+
1369
+ $first = count($parameters) >= 1 ? $parameters[0] : null;
1370
+ $second = count($parameters) >= 2 ? $parameters[1] : null;
1371
+
1372
+ switch ($method) {
1373
+ case 'start':
1374
+ case 'since':
1375
+ return $this->setStartDate($first, $second);
1376
+
1377
+ case 'sinceNow':
1378
+ return $this->setStartDate(new Carbon, $first);
1379
+
1380
+ case 'end':
1381
+ case 'until':
1382
+ return $this->setEndDate($first, $second);
1383
+
1384
+ case 'untilNow':
1385
+ return $this->setEndDate(new Carbon, $first);
1386
+
1387
+ case 'dates':
1388
+ case 'between':
1389
+ return $this->setDates($first, $second);
1390
+
1391
+ case 'recurrences':
1392
+ case 'times':
1393
+ return $this->setRecurrences($first);
1394
+
1395
+ case 'options':
1396
+ return $this->setOptions($first);
1397
+
1398
+ case 'toggle':
1399
+ return $this->toggleOptions($first, $second);
1400
+
1401
+ case 'filter':
1402
+ case 'push':
1403
+ return $this->addFilter($first, $second);
1404
+
1405
+ case 'prepend':
1406
+ return $this->prependFilter($first, $second);
1407
+
1408
+ case 'filters':
1409
+ return $this->setFilters($first ?: array());
1410
+
1411
+ case 'interval':
1412
+ case 'each':
1413
+ case 'every':
1414
+ case 'step':
1415
+ case 'stepBy':
1416
+ return $this->setDateInterval($first);
1417
+
1418
+ case 'invert':
1419
+ return $this->invertDateInterval();
1420
+
1421
+ case 'years':
1422
+ case 'year':
1423
+ case 'months':
1424
+ case 'month':
1425
+ case 'weeks':
1426
+ case 'week':
1427
+ case 'days':
1428
+ case 'dayz':
1429
+ case 'day':
1430
+ case 'hours':
1431
+ case 'hour':
1432
+ case 'minutes':
1433
+ case 'minute':
1434
+ case 'seconds':
1435
+ case 'second':
1436
+ return $this->setDateInterval(call_user_func(
1437
+ // Override default P1D when instantiating via fluent setters.
1438
+ array($this->isDefaultInterval ? new CarbonInterval('PT0S') : $this->dateInterval, $method),
1439
+ count($parameters) === 0 ? 1 : $first
1440
+ ));
1441
+ }
1442
+
1443
+ throw new BadMethodCallException("Method $method does not exist.");
1444
+ }
1445
+ }
app/vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Carbon\Exceptions;
13
+
14
+ use Exception;
15
+ use InvalidArgumentException;
16
+
17
+ class InvalidDateException extends InvalidArgumentException
18
+ {
19
+ /**
20
+ * The invalid field.
21
+ *
22
+ * @var string
23
+ */
24
+ private $field;
25
+
26
+ /**
27
+ * The invalid value.
28
+ *
29
+ * @var mixed
30
+ */
31
+ private $value;
32
+
33
+ /**
34
+ * Constructor.
35
+ *
36
+ * @param string $field
37
+ * @param mixed $value
38
+ * @param int $code
39
+ * @param \Exception|null $previous
40
+ */
41
+ public function __construct($field, $value, $code = 0, Exception $previous = null)
42
+ {
43
+ $this->field = $field;
44
+ $this->value = $value;
45
+ parent::__construct($field.' : '.$value.' is not a valid value.', $code, $previous);
46
+ }
47
+
48
+ /**
49
+ * Get the invalid field.
50
+ *
51
+ * @return string
52
+ */
53
+ public function getField()
54
+ {
55
+ return $this->field;
56
+ }
57
+
58
+ /**
59
+ * Get the invalid value.
60
+ *
61
+ * @return mixed
62
+ */
63
+ public function getValue()
64
+ {
65
+ return $this->value;
66
+ }
67
+ }
app/vendor/nesbot/carbon/src/Carbon/Lang/af.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count jaar|:count jare',
14
+ 'y' => ':count jaar|:count jare',
15
+ 'month' => ':count maand|:count maande',
16
+ 'm' => ':count maand|:count maande',
17
+ 'week' => ':count week|:count weke',
18
+ 'w' => ':count week|:count weke',
19
+ 'day' => ':count dag|:count dae',
20
+ 'd' => ':count dag|:count dae',
21
+ 'hour' => ':count uur|:count ure',
22
+ 'h' => ':count uur|:count ure',
23
+ 'minute' => ':count minuut|:count minute',
24
+ 'min' => ':count minuut|:count minute',
25
+ 'second' => ':count sekond|:count sekondes',
26
+ 's' => ':count sekond|:count sekondes',
27
+ 'ago' => ':time terug',
28
+ 'from_now' => ':time van nou af',
29
+ 'after' => ':time na',
30
+ 'before' => ':time voor',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ar.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '{0}سنة|{1}سنة|{2}سنتين|[3,10]:count سنوات|[11,Inf]:count سنة',
14
+ 'y' => '{0}سنة|{1}سنة|{2}سنتين|[3,10]:count سنوات|[11,Inf]:count سنة',
15
+ 'month' => '{0}شهر|{1} شهر|{2}شهرين|[3,10]:count أشهر|[11,Inf]:count شهر',
16
+ 'm' => '{0}شهر|{1} شهر|{2}شهرين|[3,10]:count أشهر|[11,Inf]:count شهر',
17
+ 'week' => '{0}أسبوع|{1}أسبوع|{2}أسبوعين|[3,10]:count أسابيع|[11,Inf]:count أسبوع',
18
+ 'w' => '{0}أسبوع|{1}أسبوع|{2}أسبوعين|[3,10]:count أسابيع|[11,Inf]:count أسبوع',
19
+ 'day' => '{0}يوم|{1}يوم|{2}يومين|[3,10]:count أيام|[11,Inf] يوم',
20
+ 'd' => '{0}يوم|{1}يوم|{2}يومين|[3,10]:count أيام|[11,Inf] يوم',
21
+ 'hour' => '{0}ساعة|{1}ساعة|{2}ساعتين|[3,10]:count ساعات|[11,Inf]:count ساعة',
22
+ 'h' => '{0}ساعة|{1}ساعة|{2}ساعتين|[3,10]:count ساعات|[11,Inf]:count ساعة',
23
+ 'minute' => '{0}دقيقة|{1}دقيقة|{2}دقيقتين|[3,10]:count دقائق|[11,Inf]:count دقيقة',
24
+ 'min' => '{0}دقيقة|{1}دقيقة|{2}دقيقتين|[3,10]:count دقائق|[11,Inf]:count دقيقة',
25
+ 'second' => '{0}ثانية|{1}ثانية|{2}ثانيتين|[3,10]:count ثوان|[11,Inf]:count ثانية',
26
+ 's' => '{0}ثانية|{1}ثانية|{2}ثانيتين|[3,10]:count ثوان|[11,Inf]:count ثانية',
27
+ 'ago' => 'منذ :time',
28
+ 'from_now' => ':time من الآن',
29
+ 'after' => 'بعد :time',
30
+ 'before' => 'قبل :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ar_Shakl.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '[0,1] سَنَة|{2} سَنَتَيْن|[3,10]:count سَنَوَات|[11,Inf]:count سَنَة',
14
+ 'y' => '[0,1] سَنَة|{2} سَنَتَيْن|[3,10]:count سَنَوَات|[11,Inf]:count سَنَة',
15
+ 'month' => '[0,1] شَهْرَ|{2} شَهْرَيْن|[3,10]:count أَشْهُر|[11,Inf]:count شَهْرَ',
16
+ 'm' => '[0,1] شَهْرَ|{2} شَهْرَيْن|[3,10]:count أَشْهُر|[11,Inf]:count شَهْرَ',
17
+ 'week' => '[0,1] أُسْبُوع|{2} أُسْبُوعَيْن|[3,10]:count أَسَابِيع|[11,Inf]:count أُسْبُوع',
18
+ 'w' => '[0,1] أُسْبُوع|{2} أُسْبُوعَيْن|[3,10]:count أَسَابِيع|[11,Inf]:count أُسْبُوع',
19
+ 'day' => '[0,1] يَوْم|{2} يَوْمَيْن|[3,10]:count أَيَّام|[11,Inf] يَوْم',
20
+ 'd' => '[0,1] يَوْم|{2} يَوْمَيْن|[3,10]:count أَيَّام|[11,Inf] يَوْم',
21
+ 'hour' => '[0,1] سَاعَة|{2} سَاعَتَيْن|[3,10]:count سَاعَات|[11,Inf]:count سَاعَة',
22
+ 'h' => '[0,1] سَاعَة|{2} سَاعَتَيْن|[3,10]:count سَاعَات|[11,Inf]:count سَاعَة',
23
+ 'minute' => '[0,1] دَقِيقَة|{2} دَقِيقَتَيْن|[3,10]:count دَقَائِق|[11,Inf]:count دَقِيقَة',
24
+ 'min' => '[0,1] دَقِيقَة|{2} دَقِيقَتَيْن|[3,10]:count دَقَائِق|[11,Inf]:count دَقِيقَة',
25
+ 'second' => '[0,1] ثَانِيَة|{2} ثَانِيَتَيْن|[3,10]:count ثَوَان|[11,Inf]:count ثَانِيَة',
26
+ 's' => '[0,1] ثَانِيَة|{2} ثَانِيَتَيْن|[3,10]:count ثَوَان|[11,Inf]:count ثَانِيَة',
27
+ 'ago' => 'مُنْذُ :time',
28
+ 'from_now' => 'مِنَ الْآن :time',
29
+ 'after' => 'بَعْدَ :time',
30
+ 'before' => 'قَبْلَ :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/az.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count il',
14
+ 'y' => ':count il',
15
+ 'month' => ':count ay',
16
+ 'm' => ':count ay',
17
+ 'week' => ':count həftə',
18
+ 'w' => ':count həftə',
19
+ 'day' => ':count gün',
20
+ 'd' => ':count gün',
21
+ 'hour' => ':count saat',
22
+ 'h' => ':count saat',
23
+ 'minute' => ':count dəqiqə',
24
+ 'min' => ':count dəqiqə',
25
+ 'second' => ':count saniyə',
26
+ 's' => ':count saniyə',
27
+ 'ago' => ':time əvvəl',
28
+ 'from_now' => ':time sonra',
29
+ 'after' => ':time sonra',
30
+ 'before' => ':time əvvəl',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/bg.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count година|:count години',
14
+ 'y' => ':count година|:count години',
15
+ 'month' => ':count месец|:count месеца',
16
+ 'm' => ':count месец|:count месеца',
17
+ 'week' => ':count седмица|:count седмици',
18
+ 'w' => ':count седмица|:count седмици',
19
+ 'day' => ':count ден|:count дни',
20
+ 'd' => ':count ден|:count дни',
21
+ 'hour' => ':count час|:count часа',
22
+ 'h' => ':count час|:count часа',
23
+ 'minute' => ':count минута|:count минути',
24
+ 'min' => ':count минута|:count минути',
25
+ 'second' => ':count секунда|:count секунди',
26
+ 's' => ':count секунда|:count секунди',
27
+ 'ago' => 'преди :time',
28
+ 'from_now' => ':time от сега',
29
+ 'after' => 'след :time',
30
+ 'before' => 'преди :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/bn.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '১ বছর|:count বছর',
14
+ 'y' => '১ বছর|:count বছর',
15
+ 'month' => '১ মাস|:count মাস',
16
+ 'm' => '১ মাস|:count মাস',
17
+ 'week' => '১ সপ্তাহ|:count সপ্তাহ',
18
+ 'w' => '১ সপ্তাহ|:count সপ্তাহ',
19
+ 'day' => '১ দিন|:count দিন',
20
+ 'd' => '১ দিন|:count দিন',
21
+ 'hour' => '১ ঘন্টা|:count ঘন্টা',
22
+ 'h' => '১ ঘন্টা|:count ঘন্টা',
23
+ 'minute' => '১ মিনিট|:count মিনিট',
24
+ 'min' => '১ মিনিট|:count মিনিট',
25
+ 'second' => '১ সেকেন্ড|:count সেকেন্ড',
26
+ 's' => '১ সেকেন্ড|:count সেকেন্ড',
27
+ 'ago' => ':time পূর্বে',
28
+ 'from_now' => 'এখন থেকে :time',
29
+ 'after' => ':time পরে',
30
+ 'before' => ':time আগে',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/bs_BA.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count godina|:count godine|:count godina',
14
+ 'y' => ':count godina|:count godine|:count godina',
15
+ 'month' => ':count mjesec|:count mjeseca|:count mjeseci',
16
+ 'm' => ':count mjesec|:count mjeseca|:count mjeseci',
17
+ 'week' => ':count nedjelja|:count nedjelje|:count nedjelja',
18
+ 'w' => ':count nedjelja|:count nedjelje|:count nedjelja',
19
+ 'day' => ':count dan|:count dana|:count dana',
20
+ 'd' => ':count dan|:count dana|:count dana',
21
+ 'hour' => ':count sat|:count sata|:count sati',
22
+ 'h' => ':count sat|:count sata|:count sati',
23
+ 'minute' => ':count minut|:count minuta|:count minuta',
24
+ 'min' => ':count minut|:count minuta|:count minuta',
25
+ 'second' => ':count sekund|:count sekunda|:count sekundi',
26
+ 's' => ':count sekund|:count sekunda|:count sekundi',
27
+ 'ago' => 'prije :time',
28
+ 'from_now' => 'za :time',
29
+ 'after' => 'nakon :time',
30
+ 'before' => ':time ranije',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ca.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count any|:count anys',
14
+ 'y' => ':count any|:count anys',
15
+ 'month' => ':count mes|:count mesos',
16
+ 'm' => ':count mes|:count mesos',
17
+ 'week' => ':count setmana|:count setmanes',
18
+ 'w' => ':count setmana|:count setmanes',
19
+ 'day' => ':count dia|:count dies',
20
+ 'd' => ':count dia|:count dies',
21
+ 'hour' => ':count hora|:count hores',
22
+ 'h' => ':count hora|:count hores',
23
+ 'minute' => ':count minut|:count minuts',
24
+ 'min' => ':count minut|:count minuts',
25
+ 'second' => ':count segon|:count segons',
26
+ 's' => ':count segon|:count segons',
27
+ 'ago' => 'fa :time',
28
+ 'from_now' => 'dins de :time',
29
+ 'after' => ':time després',
30
+ 'before' => ':time abans',
31
+ 'diff_now' => 'ara mateix',
32
+ 'diff_yesterday' => 'ahir',
33
+ 'diff_tomorrow' => 'demà',
34
+ 'diff_before_yesterday' => "abans d'ahir",
35
+ 'diff_after_tomorrow' => 'demà passat',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/cs.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count rok|:count roky|:count let',
14
+ 'y' => ':count rok|:count roky|:count let',
15
+ 'month' => ':count měsíc|:count měsíce|:count měsíců',
16
+ 'm' => ':count měsíc|:count měsíce|:count měsíců',
17
+ 'week' => ':count týden|:count týdny|:count týdnů',
18
+ 'w' => ':count týden|:count týdny|:count týdnů',
19
+ 'day' => ':count den|:count dny|:count dní',
20
+ 'd' => ':count den|:count dny|:count dní',
21
+ 'hour' => ':count hodinu|:count hodiny|:count hodin',
22
+ 'h' => ':count hodinu|:count hodiny|:count hodin',
23
+ 'minute' => ':count minutu|:count minuty|:count minut',
24
+ 'min' => ':count minutu|:count minuty|:count minut',
25
+ 'second' => ':count sekundu|:count sekundy|:count sekund',
26
+ 's' => ':count sekundu|:count sekundy|:count sekund',
27
+ 'ago' => ':time nazpět',
28
+ 'from_now' => 'za :time',
29
+ 'after' => ':time později',
30
+ 'before' => ':time předtím',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/cy.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the Carbon package.
4
+ *
5
+ * (c) Brian Nesbitt <brian@nesbot.com>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+ return array(
11
+ 'year' => '1 flwyddyn|:count blynedd',
12
+ 'y' => ':countbl',
13
+ 'month' => '1 mis|:count fis',
14
+ 'm' => ':countmi',
15
+ 'week' => ':count wythnos',
16
+ 'w' => ':countw',
17
+ 'day' => ':count diwrnod',
18
+ 'd' => ':countd',
19
+ 'hour' => ':count awr',
20
+ 'h' => ':counth',
21
+ 'minute' => ':count munud',
22
+ 'min' => ':countm',
23
+ 'second' => ':count eiliad',
24
+ 's' => ':counts',
25
+ 'ago' => ':time yn ôl',
26
+ 'from_now' => ':time o hyn ymlaen',
27
+ 'after' => ':time ar ôl',
28
+ 'before' => ':time o\'r blaen',
29
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/da.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count år|:count år',
14
+ 'y' => ':count år|:count år',
15
+ 'month' => ':count måned|:count måneder',
16
+ 'm' => ':count måned|:count måneder',
17
+ 'week' => ':count uge|:count uger',
18
+ 'w' => ':count uge|:count uger',
19
+ 'day' => ':count dag|:count dage',
20
+ 'd' => ':count dag|:count dage',
21
+ 'hour' => ':count time|:count timer',
22
+ 'h' => ':count time|:count timer',
23
+ 'minute' => ':count minut|:count minutter',
24
+ 'min' => ':count minut|:count minutter',
25
+ 'second' => ':count sekund|:count sekunder',
26
+ 's' => ':count sekund|:count sekunder',
27
+ 'ago' => ':time siden',
28
+ 'from_now' => 'om :time',
29
+ 'after' => ':time efter',
30
+ 'before' => ':time før',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/de.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count Jahr|:count Jahre',
14
+ 'y' => ':countJ|:countJ',
15
+ 'month' => ':count Monat|:count Monate',
16
+ 'm' => ':countMon|:countMon',
17
+ 'week' => ':count Woche|:count Wochen',
18
+ 'w' => ':countWo|:countWo',
19
+ 'day' => ':count Tag|:count Tage',
20
+ 'd' => ':countTg|:countTg',
21
+ 'hour' => ':count Stunde|:count Stunden',
22
+ 'h' => ':countStd|:countStd',
23
+ 'minute' => ':count Minute|:count Minuten',
24
+ 'min' => ':countMin|:countMin',
25
+ 'second' => ':count Sekunde|:count Sekunden',
26
+ 's' => ':countSek|:countSek',
27
+ 'ago' => 'vor :time',
28
+ 'from_now' => 'in :time',
29
+ 'after' => ':time später',
30
+ 'before' => ':time zuvor',
31
+
32
+ 'year_from_now' => ':count Jahr|:count Jahren',
33
+ 'month_from_now' => ':count Monat|:count Monaten',
34
+ 'week_from_now' => ':count Woche|:count Wochen',
35
+ 'day_from_now' => ':count Tag|:count Tagen',
36
+ 'year_ago' => ':count Jahr|:count Jahren',
37
+ 'month_ago' => ':count Monat|:count Monaten',
38
+ 'week_ago' => ':count Woche|:count Wochen',
39
+ 'day_ago' => ':count Tag|:count Tagen',
40
+
41
+ 'diff_now' => 'Gerade eben',
42
+ 'diff_yesterday' => 'Gestern',
43
+ 'diff_tomorrow' => 'Heute',
44
+ 'diff_before_yesterday' => 'Vorgestern',
45
+ 'diff_after_tomorrow' => 'Übermorgen',
46
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/dv_MV.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Ahmed Ali <ajaaibu@gmail.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '{0}އަހަރެއް|[1,Inf]:count އަހަރު',
14
+ 'y' => '{0}އަހަރެއް|[1,Inf]:count އަހަރު',
15
+ 'month' => '{0}މައްސަރެއް|[1,Inf]:count މަސް',
16
+ 'm' => '{0}މައްސަރެއް|[1,Inf]:count މަސް',
17
+ 'week' => '{0}ހަފްތާއެއް|[1,Inf]:count ހަފްތާ',
18
+ 'w' => '{0}ހަފްތާއެއް|[1,Inf]:count ހަފްތާ',
19
+ 'day' => '{0}ދުވަސް|[1,Inf]:count ދުވަސް',
20
+ 'd' => '{0}ދުވަސް|[1,Inf]:count ދުވަސް',
21
+ 'hour' => '{0}ގަޑިއިރެއް|[1,Inf]:count ގަޑި',
22
+ 'h' => '{0}ގަޑިއިރެއް|[1,Inf]:count ގަޑި',
23
+ 'minute' => '{0}މިނެޓެއް|[1,Inf]:count މިނެޓް',
24
+ 'min' => '{0}މިނެޓެއް|[1,Inf]:count މިނެޓް',
25
+ 'second' => '{0}ސިކުންތެއް|[1,Inf]:count ސިކުންތު',
26
+ 's' => '{0}ސިކުންތެއް|[1,Inf]:count ސިކުންތު',
27
+ 'ago' => ':time ކުރިން',
28
+ 'from_now' => ':time ފަހުން',
29
+ 'after' => ':time ފަހުން',
30
+ 'before' => ':time ކުރި',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/el.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count χρόνος|:count χρόνια',
14
+ 'y' => ':count χρόνος|:count χρόνια',
15
+ 'month' => ':count μήνας|:count μήνες',
16
+ 'm' => ':count μήνας|:count μήνες',
17
+ 'week' => ':count εβδομάδα|:count εβδομάδες',
18
+ 'w' => ':count εβδομάδα|:count εβδομάδες',
19
+ 'day' => ':count μέρα|:count μέρες',
20
+ 'd' => ':count μέρα|:count μέρες',
21
+ 'hour' => ':count ώρα|:count ώρες',
22
+ 'h' => ':count ώρα|:count ώρες',
23
+ 'minute' => ':count λεπτό|:count λεπτά',
24
+ 'min' => ':count λεπτό|:count λεπτά',
25
+ 'second' => ':count δευτερόλεπτο|:count δευτερόλεπτα',
26
+ 's' => ':count δευτερόλεπτο|:count δευτερόλεπτα',
27
+ 'ago' => 'πριν από :time',
28
+ 'from_now' => 'σε :time από τώρα',
29
+ 'after' => ':time μετά',
30
+ 'before' => ':time πριν',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/en.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count year|:count years',
14
+ 'y' => ':countyr|:countyrs',
15
+ 'month' => ':count month|:count months',
16
+ 'm' => ':countmo|:countmos',
17
+ 'week' => ':count week|:count weeks',
18
+ 'w' => ':countw|:countw',
19
+ 'day' => ':count day|:count days',
20
+ 'd' => ':countd|:countd',
21
+ 'hour' => ':count hour|:count hours',
22
+ 'h' => ':counth|:counth',
23
+ 'minute' => ':count minute|:count minutes',
24
+ 'min' => ':countm|:countm',
25
+ 'second' => ':count second|:count seconds',
26
+ 's' => ':counts|:counts',
27
+ 'ago' => ':time ago',
28
+ 'from_now' => ':time from now',
29
+ 'after' => ':time after',
30
+ 'before' => ':time before',
31
+ 'diff_now' => 'just now',
32
+ 'diff_yesterday' => 'yesterday',
33
+ 'diff_tomorrow' => 'tomorrow',
34
+ 'diff_before_yesterday' => 'before yesterday',
35
+ 'diff_after_tomorrow' => 'after tomorrow',
36
+ 'period_recurrences' => 'once|:count times',
37
+ 'period_interval' => 'every :interval',
38
+ 'period_start_date' => 'from :date',
39
+ 'period_end_date' => 'to :date',
40
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/eo.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count jaro|:count jaroj',
14
+ 'y' => ':count jaro|:count jaroj',
15
+ 'month' => ':count monato|:count monatoj',
16
+ 'm' => ':count monato|:count monatoj',
17
+ 'week' => ':count semajno|:count semajnoj',
18
+ 'w' => ':count semajno|:count semajnoj',
19
+ 'day' => ':count tago|:count tagoj',
20
+ 'd' => ':count tago|:count tagoj',
21
+ 'hour' => ':count horo|:count horoj',
22
+ 'h' => ':count horo|:count horoj',
23
+ 'minute' => ':count minuto|:count minutoj',
24
+ 'min' => ':count minuto|:count minutoj',
25
+ 'second' => ':count sekundo|:count sekundoj',
26
+ 's' => ':count sekundo|:count sekundoj',
27
+ 'ago' => 'antaŭ :time',
28
+ 'from_now' => 'je :time',
29
+ 'after' => ':time poste',
30
+ 'before' => ':time antaŭe',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/es.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count año|:count años',
14
+ 'y' => ':count año|:count años',
15
+ 'month' => ':count mes|:count meses',
16
+ 'm' => ':count mes|:count meses',
17
+ 'week' => ':count semana|:count semanas',
18
+ 'w' => ':count semana|:count semanas',
19
+ 'day' => ':count día|:count días',
20
+ 'd' => ':count día|:count días',
21
+ 'hour' => ':count hora|:count horas',
22
+ 'h' => ':count hora|:count horas',
23
+ 'minute' => ':count minuto|:count minutos',
24
+ 'min' => ':count minuto|:count minutos',
25
+ 'second' => ':count segundo|:count segundos',
26
+ 's' => ':count segundo|:count segundos',
27
+ 'ago' => 'hace :time',
28
+ 'from_now' => 'dentro de :time',
29
+ 'after' => ':time después',
30
+ 'before' => ':time antes',
31
+ 'diff_now' => 'ahora mismo',
32
+ 'diff_yesterday' => 'ayer',
33
+ 'diff_tomorrow' => 'mañana',
34
+ 'diff_before_yesterday' => 'anteayer',
35
+ 'diff_after_tomorrow' => 'pasado mañana',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/et.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count aasta|:count aastat',
14
+ 'y' => ':count aasta|:count aastat',
15
+ 'month' => ':count kuu|:count kuud',
16
+ 'm' => ':count kuu|:count kuud',
17
+ 'week' => ':count nädal|:count nädalat',
18
+ 'w' => ':count nädal|:count nädalat',
19
+ 'day' => ':count päev|:count päeva',
20
+ 'd' => ':count päev|:count päeva',
21
+ 'hour' => ':count tund|:count tundi',
22
+ 'h' => ':count tund|:count tundi',
23
+ 'minute' => ':count minut|:count minutit',
24
+ 'min' => ':count minut|:count minutit',
25
+ 'second' => ':count sekund|:count sekundit',
26
+ 's' => ':count sekund|:count sekundit',
27
+ 'ago' => ':time tagasi',
28
+ 'from_now' => ':time pärast',
29
+ 'after' => ':time pärast',
30
+ 'before' => ':time enne',
31
+ 'year_from_now' => ':count aasta',
32
+ 'month_from_now' => ':count kuu',
33
+ 'week_from_now' => ':count nädala',
34
+ 'day_from_now' => ':count päeva',
35
+ 'hour_from_now' => ':count tunni',
36
+ 'minute_from_now' => ':count minuti',
37
+ 'second_from_now' => ':count sekundi',
38
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/eu.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => 'Urte 1|:count urte',
14
+ 'y' => 'Urte 1|:count urte',
15
+ 'month' => 'Hile 1|:count hile',
16
+ 'm' => 'Hile 1|:count hile',
17
+ 'week' => 'Aste 1|:count aste',
18
+ 'w' => 'Aste 1|:count aste',
19
+ 'day' => 'Egun 1|:count egun',
20
+ 'd' => 'Egun 1|:count egun',
21
+ 'hour' => 'Ordu 1|:count ordu',
22
+ 'h' => 'Ordu 1|:count ordu',
23
+ 'minute' => 'Minutu 1|:count minutu',
24
+ 'min' => 'Minutu 1|:count minutu',
25
+ 'second' => 'Segundu 1|:count segundu',
26
+ 's' => 'Segundu 1|:count segundu',
27
+ 'ago' => 'Orain dela :time',
28
+ 'from_now' => ':time barru',
29
+ 'after' => ':time geroago',
30
+ 'before' => ':time lehenago',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/fa.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count سال',
14
+ 'y' => ':count سال',
15
+ 'month' => ':count ماه',
16
+ 'm' => ':count ماه',
17
+ 'week' => ':count هفته',
18
+ 'w' => ':count هفته',
19
+ 'day' => ':count روز',
20
+ 'd' => ':count روز',
21
+ 'hour' => ':count ساعت',
22
+ 'h' => ':count ساعت',
23
+ 'minute' => ':count دقیقه',
24
+ 'min' => ':count دقیقه',
25
+ 'second' => ':count ثانیه',
26
+ 's' => ':count ثانیه',
27
+ 'ago' => ':time پیش',
28
+ 'from_now' => ':time بعد',
29
+ 'after' => ':time پس از',
30
+ 'before' => ':time پیش از',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/fi.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count vuosi|:count vuotta',
14
+ 'y' => ':count vuosi|:count vuotta',
15
+ 'month' => ':count kuukausi|:count kuukautta',
16
+ 'm' => ':count kuukausi|:count kuukautta',
17
+ 'week' => ':count viikko|:count viikkoa',
18
+ 'w' => ':count viikko|:count viikkoa',
19
+ 'day' => ':count päivä|:count päivää',
20
+ 'd' => ':count päivä|:count päivää',
21
+ 'hour' => ':count tunti|:count tuntia',
22
+ 'h' => ':count tunti|:count tuntia',
23
+ 'minute' => ':count minuutti|:count minuuttia',
24
+ 'min' => ':count minuutti|:count minuuttia',
25
+ 'second' => ':count sekunti|:count sekuntia',
26
+ 's' => ':count sekunti|:count sekuntia',
27
+ 'ago' => ':time sitten',
28
+ 'from_now' => ':time tästä hetkestä',
29
+ 'after' => ':time sen jälkeen',
30
+ 'before' => ':time ennen',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/fo.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count ár|:count ár',
14
+ 'y' => ':count ár|:count ár',
15
+ 'month' => ':count mánaður|:count mánaðir',
16
+ 'm' => ':count mánaður|:count mánaðir',
17
+ 'week' => ':count vika|:count vikur',
18
+ 'w' => ':count vika|:count vikur',
19
+ 'day' => ':count dag|:count dagar',
20
+ 'd' => ':count dag|:count dagar',
21
+ 'hour' => ':count tími|:count tímar',
22
+ 'h' => ':count tími|:count tímar',
23
+ 'minute' => ':count minutt|:count minuttir',
24
+ 'min' => ':count minutt|:count minuttir',
25
+ 'second' => ':count sekund|:count sekundir',
26
+ 's' => ':count sekund|:count sekundir',
27
+ 'ago' => ':time síðan',
28
+ 'from_now' => 'um :time',
29
+ 'after' => ':time aftaná',
30
+ 'before' => ':time áðrenn',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/fr.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count an|:count ans',
14
+ 'y' => ':count an|:count ans',
15
+ 'month' => ':count mois',
16
+ 'm' => ':count mois',
17
+ 'week' => ':count semaine|:count semaines',
18
+ 'w' => ':count sem.',
19
+ 'day' => ':count jour|:count jours',
20
+ 'd' => ':count j.',
21
+ 'hour' => ':count heure|:count heures',
22
+ 'h' => ':count h.',
23
+ 'minute' => ':count minute|:count minutes',
24
+ 'min' => ':count min.',
25
+ 'second' => ':count seconde|:count secondes',
26
+ 's' => ':count sec.',
27
+ 'ago' => 'il y a :time',
28
+ 'from_now' => 'dans :time',
29
+ 'after' => ':time après',
30
+ 'before' => ':time avant',
31
+ 'diff_now' => "à l'instant",
32
+ 'diff_yesterday' => 'hier',
33
+ 'diff_tomorrow' => 'demain',
34
+ 'diff_before_yesterday' => 'avant-hier',
35
+ 'diff_after_tomorrow' => 'après-demain',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/gl.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count ano|:count anos',
14
+ 'month' => ':count mes|:count meses',
15
+ 'week' => ':count semana|:count semanas',
16
+ 'day' => ':count día|:count días',
17
+ 'hour' => ':count hora|:count horas',
18
+ 'minute' => ':count minuto|:count minutos',
19
+ 'second' => ':count segundo|:count segundos',
20
+ 'ago' => 'fai :time',
21
+ 'from_now' => 'dentro de :time',
22
+ 'after' => ':time despois',
23
+ 'before' => ':time antes',
24
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/gu.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count વર્ષ|:count વર્ષો',
14
+ 'y' => ':countવર્ષ|:countવર્ષો',
15
+ 'month' => ':count મહિનો|:count મહિના',
16
+ 'm' => ':countમહિનો|:countમહિના',
17
+ 'week' => ':count અઠવાડિયું|:count અઠવાડિયા',
18
+ 'w' => ':countઅઠ.|:countઅઠ.',
19
+ 'day' => ':count દિવસ|:count દિવસો',
20
+ 'd' => ':countદિ.|:countદિ.',
21
+ 'hour' => ':count કલાક|:count કલાકો',
22
+ 'h' => ':countક.|:countક.',
23
+ 'minute' => ':count મિનિટ|:count મિનિટ',
24
+ 'min' => ':countમિ.|:countમિ.',
25
+ 'second' => ':count સેકેન્ડ|:count સેકેન્ડ',
26
+ 's' => ':countસે.|:countસે.',
27
+ 'ago' => ':time પહેલા',
28
+ 'from_now' => ':time અત્યારથી',
29
+ 'after' => ':time પછી',
30
+ 'before' => ':time પહેલા',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/he.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => 'שנה|{2}שנתיים|:count שנים',
14
+ 'y' => 'שנה|{2}שנתיים|:count שנים',
15
+ 'month' => 'חודש|{2}חודשיים|:count חודשים',
16
+ 'm' => 'חודש|{2}חודשיים|:count חודשים',
17
+ 'week' => 'שבוע|{2}שבועיים|:count שבועות',
18
+ 'w' => 'שבוע|{2}שבועיים|:count שבועות',
19
+ 'day' => 'יום|{2}יומיים|:count ימים',
20
+ 'd' => 'יום|{2}יומיים|:count ימים',
21
+ 'hour' => 'שעה|{2}שעתיים|:count שעות',
22
+ 'h' => 'שעה|{2}שעתיים|:count שעות',
23
+ 'minute' => 'דקה|{2}דקותיים|:count דקות',
24
+ 'min' => 'דקה|{2}דקותיים|:count דקות',
25
+ 'second' => 'שניה|:count שניות',
26
+ 's' => 'שניה|:count שניות',
27
+ 'ago' => 'לפני :time',
28
+ 'from_now' => 'בעוד :time',
29
+ 'after' => 'אחרי :time',
30
+ 'before' => 'לפני :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/hi.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '1 वर्ष|:count वर्षों',
14
+ 'y' => '1 वर्ष|:count वर्षों',
15
+ 'month' => '1 माह|:count महीने',
16
+ 'm' => '1 माह|:count महीने',
17
+ 'week' => '1 सप्ताह|:count सप्ताह',
18
+ 'w' => '1 सप्ताह|:count सप्ताह',
19
+ 'day' => '1 दिन|:count दिनों',
20
+ 'd' => '1 दिन|:count दिनों',
21
+ 'hour' => '1 घंटा|:count घंटे',
22
+ 'h' => '1 घंटा|:count घंटे',
23
+ 'minute' => '1 मिनट|:count मिनटों',
24
+ 'min' => '1 मिनट|:count मिनटों',
25
+ 'second' => '1 सेकंड|:count सेकंड',
26
+ 's' => '1 सेकंड|:count सेकंड',
27
+ 'ago' => ':time पूर्व',
28
+ 'from_now' => ':time से',
29
+ 'after' => ':time के बाद',
30
+ 'before' => ':time के पहले',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/hr.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count godinu|:count godine|:count godina',
14
+ 'y' => ':count godinu|:count godine|:count godina',
15
+ 'month' => ':count mjesec|:count mjeseca|:count mjeseci',
16
+ 'm' => ':count mjesec|:count mjeseca|:count mjeseci',
17
+ 'week' => ':count tjedan|:count tjedna|:count tjedana',
18
+ 'w' => ':count tjedan|:count tjedna|:count tjedana',
19
+ 'day' => ':count dan|:count dana|:count dana',
20
+ 'd' => ':count dan|:count dana|:count dana',
21
+ 'hour' => ':count sat|:count sata|:count sati',
22
+ 'h' => ':count sat|:count sata|:count sati',
23
+ 'minute' => ':count minutu|:count minute |:count minuta',
24
+ 'min' => ':count minutu|:count minute |:count minuta',
25
+ 'second' => ':count sekundu|:count sekunde|:count sekundi',
26
+ 's' => ':count sekundu|:count sekunde|:count sekundi',
27
+ 'ago' => 'prije :time',
28
+ 'from_now' => 'za :time',
29
+ 'after' => 'za :time',
30
+ 'before' => 'prije :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/hu.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count év',
14
+ 'y' => ':count év',
15
+ 'month' => ':count hónap',
16
+ 'm' => ':count hónap',
17
+ 'week' => ':count hét',
18
+ 'w' => ':count hét',
19
+ 'day' => ':count nap',
20
+ 'd' => ':count nap',
21
+ 'hour' => ':count óra',
22
+ 'h' => ':count óra',
23
+ 'minute' => ':count perc',
24
+ 'min' => ':count perc',
25
+ 'second' => ':count másodperc',
26
+ 's' => ':count másodperc',
27
+ 'ago' => ':time',
28
+ 'from_now' => ':time múlva',
29
+ 'after' => ':time később',
30
+ 'before' => ':time korábban',
31
+ 'year_ago' => ':count éve',
32
+ 'month_ago' => ':count hónapja',
33
+ 'week_ago' => ':count hete',
34
+ 'day_ago' => ':count napja',
35
+ 'hour_ago' => ':count órája',
36
+ 'minute_ago' => ':count perce',
37
+ 'second_ago' => ':count másodperce',
38
+ 'year_after' => ':count évvel',
39
+ 'month_after' => ':count hónappal',
40
+ 'week_after' => ':count héttel',
41
+ 'day_after' => ':count nappal',
42
+ 'hour_after' => ':count órával',
43
+ 'minute_after' => ':count perccel',
44
+ 'second_after' => ':count másodperccel',
45
+ 'year_before' => ':count évvel',
46
+ 'month_before' => ':count hónappal',
47
+ 'week_before' => ':count héttel',
48
+ 'day_before' => ':count nappal',
49
+ 'hour_before' => ':count órával',
50
+ 'minute_before' => ':count perccel',
51
+ 'second_before' => ':count másodperccel',
52
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/hy.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count տարի',
14
+ 'y' => ':countտ',
15
+ 'month' => ':count ամիս',
16
+ 'm' => ':countամ',
17
+ 'week' => ':count շաբաթ',
18
+ 'w' => ':countշ',
19
+ 'day' => ':count օր',
20
+ 'd' => ':countօր',
21
+ 'hour' => ':count ժամ',
22
+ 'h' => ':countժ',
23
+ 'minute' => ':count րոպե',
24
+ 'min' => ':countր',
25
+ 'second' => ':count վարկյան',
26
+ 's' => ':countվրկ',
27
+ 'ago' => ':time առաջ',
28
+ 'from_now' => ':time ներկա պահից',
29
+ 'after' => ':time հետո',
30
+ 'before' => ':time առաջ',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/id.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count tahun',
14
+ 'y' => ':count tahun',
15
+ 'month' => ':count bulan',
16
+ 'm' => ':count bulan',
17
+ 'week' => ':count minggu',
18
+ 'w' => ':count minggu',
19
+ 'day' => ':count hari',
20
+ 'd' => ':count hari',
21
+ 'hour' => ':count jam',
22
+ 'h' => ':count jam',
23
+ 'minute' => ':count menit',
24
+ 'min' => ':count menit',
25
+ 'second' => ':count detik',
26
+ 's' => ':count detik',
27
+ 'ago' => ':time yang lalu',
28
+ 'from_now' => ':time dari sekarang',
29
+ 'after' => ':time setelah',
30
+ 'before' => ':time sebelum',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/is.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '1 ár|:count ár',
14
+ 'y' => '1 ár|:count ár',
15
+ 'month' => '1 mánuður|:count mánuðir',
16
+ 'm' => '1 mánuður|:count mánuðir',
17
+ 'week' => '1 vika|:count vikur',
18
+ 'w' => '1 vika|:count vikur',
19
+ 'day' => '1 dagur|:count dagar',
20
+ 'd' => '1 dagur|:count dagar',
21
+ 'hour' => '1 klukkutími|:count klukkutímar',
22
+ 'h' => '1 klukkutími|:count klukkutímar',
23
+ 'minute' => '1 mínúta|:count mínútur',
24
+ 'min' => '1 mínúta|:count mínútur',
25
+ 'second' => '1 sekúnda|:count sekúndur',
26
+ 's' => '1 sekúnda|:count sekúndur',
27
+ 'ago' => ':time síðan',
28
+ 'from_now' => ':time síðan',
29
+ 'after' => ':time eftir',
30
+ 'before' => ':time fyrir',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/it.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count anno|:count anni',
14
+ 'y' => ':count anno|:count anni',
15
+ 'month' => ':count mese|:count mesi',
16
+ 'm' => ':count mese|:count mesi',
17
+ 'week' => ':count settimana|:count settimane',
18
+ 'w' => ':count settimana|:count settimane',
19
+ 'day' => ':count giorno|:count giorni',
20
+ 'd' => ':count giorno|:count giorni',
21
+ 'hour' => ':count ora|:count ore',
22
+ 'h' => ':count ora|:count ore',
23
+ 'minute' => ':count minuto|:count minuti',
24
+ 'min' => ':count minuto|:count minuti',
25
+ 'second' => ':count secondo|:count secondi',
26
+ 's' => ':count secondo|:count secondi',
27
+ 'ago' => ':time fa',
28
+ 'from_now' => 'tra :time',
29
+ 'after' => ':time dopo',
30
+ 'before' => ':time prima',
31
+ 'diff_now' => 'proprio ora',
32
+ 'diff_yesterday' => 'ieri',
33
+ 'diff_tomorrow' => 'domani',
34
+ 'diff_before_yesterday' => "l'altro ieri",
35
+ 'diff_after_tomorrow' => 'dopodomani',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ja.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count年',
14
+ 'y' => ':count年',
15
+ 'month' => ':countヶ月',
16
+ 'm' => ':countヶ月',
17
+ 'week' => ':count週間',
18
+ 'w' => ':count週間',
19
+ 'day' => ':count日',
20
+ 'd' => ':count日',
21
+ 'hour' => ':count時間',
22
+ 'h' => ':count時間',
23
+ 'minute' => ':count分',
24
+ 'min' => ':count分',
25
+ 'second' => ':count秒',
26
+ 's' => ':count秒',
27
+ 'ago' => ':time前',
28
+ 'from_now' => '今から:time',
29
+ 'after' => ':time後',
30
+ 'before' => ':time前',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ka.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count წლის',
14
+ 'y' => ':count წლის',
15
+ 'month' => ':count თვის',
16
+ 'm' => ':count თვის',
17
+ 'week' => ':count კვირის',
18
+ 'w' => ':count კვირის',
19
+ 'day' => ':count დღის',
20
+ 'd' => ':count დღის',
21
+ 'hour' => ':count საათის',
22
+ 'h' => ':count საათის',
23
+ 'minute' => ':count წუთის',
24
+ 'min' => ':count წუთის',
25
+ 'second' => ':count წამის',
26
+ 's' => ':count წამის',
27
+ 'ago' => ':time უკან',
28
+ 'from_now' => ':time შემდეგ',
29
+ 'after' => ':time შემდეგ',
30
+ 'before' => ':time უკან',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/kk.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the Carbon package.
4
+ *
5
+ * (c) Brian Nesbitt <brian@nesbot.com>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+ return array(
11
+ 'year' => ':count жыл',
12
+ 'y' => ':count жыл',
13
+ 'month' => ':count ай',
14
+ 'm' => ':count ай',
15
+ 'week' => ':count апта',
16
+ 'w' => ':count апта',
17
+ 'day' => ':count күн',
18
+ 'd' => ':count күн',
19
+ 'hour' => ':count сағат',
20
+ 'h' => ':count сағат',
21
+ 'minute' => ':count минут',
22
+ 'min' => ':count минут',
23
+ 'second' => ':count секунд',
24
+ 's' => ':count секунд',
25
+ 'ago' => ':time бұрын',
26
+ 'from_now' => ':time кейін',
27
+ 'after' => ':time кейін',
28
+ 'before' => ':time бұрын',
29
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/km.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count ឆ្នាំ',
14
+ 'y' => ':count ឆ្នាំ',
15
+ 'month' => ':count ខែ',
16
+ 'm' => ':count ខែ',
17
+ 'week' => ':count សប្ដាហ៍',
18
+ 'w' => ':count សប្ដាហ៍',
19
+ 'day' => ':count ថ្ងៃ',
20
+ 'd' => ':count ថ្ងៃ',
21
+ 'hour' => ':count ម៉ោង',
22
+ 'h' => ':count ម៉ោង',
23
+ 'minute' => ':count នាទី',
24
+ 'min' => ':count នាទី',
25
+ 'second' => ':count វិនាទី',
26
+ 's' => ':count វិនាទី',
27
+ 'ago' => ':timeមុន',
28
+ 'from_now' => ':timeពី​ឥឡូវ',
29
+ 'after' => 'នៅ​ក្រោយ :time',
30
+ 'before' => 'នៅ​មុន :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ko.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count 년',
14
+ 'y' => ':count 년',
15
+ 'month' => ':count 개월',
16
+ 'm' => ':count 개월',
17
+ 'week' => ':count 주일',
18
+ 'w' => ':count 주일',
19
+ 'day' => ':count 일',
20
+ 'd' => ':count 일',
21
+ 'hour' => ':count 시간',
22
+ 'h' => ':count 시간',
23
+ 'minute' => ':count 분',
24
+ 'min' => ':count 분',
25
+ 'second' => ':count 초',
26
+ 's' => ':count 초',
27
+ 'ago' => ':time 전',
28
+ 'from_now' => ':time 후',
29
+ 'after' => ':time 이후',
30
+ 'before' => ':time 이전',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/lt.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count metus|:count metus|:count metų',
14
+ 'y' => ':count metus|:count metus|:count metų',
15
+ 'month' => ':count mėnesį|:count mėnesius|:count mėnesių',
16
+ 'm' => ':count mėnesį|:count mėnesius|:count mėnesių',
17
+ 'week' => ':count savaitę|:count savaites|:count savaičių',
18
+ 'w' => ':count savaitę|:count savaites|:count savaičių',
19
+ 'day' => ':count dieną|:count dienas|:count dienų',
20
+ 'd' => ':count dieną|:count dienas|:count dienų',
21
+ 'hour' => ':count valandą|:count valandas|:count valandų',
22
+ 'h' => ':count valandą|:count valandas|:count valandų',
23
+ 'minute' => ':count minutę|:count minutes|:count minučių',
24
+ 'min' => ':count minutę|:count minutes|:count minučių',
25
+ 'second' => ':count sekundę|:count sekundes|:count sekundžių',
26
+ 's' => ':count sekundę|:count sekundes|:count sekundžių',
27
+ 'second_from_now' => ':count sekundės|:count sekundžių|:count sekundžių',
28
+ 'minute_from_now' => ':count minutės|:count minučių|:count minučių',
29
+ 'hour_from_now' => ':count valandos|:count valandų|:count valandų',
30
+ 'day_from_now' => ':count dienos|:count dienų|:count dienų',
31
+ 'week_from_now' => ':count savaitės|:count savaičių|:count savaičių',
32
+ 'month_from_now' => ':count mėnesio|:count mėnesių|:count mėnesių',
33
+ 'year_from_now' => ':count metų',
34
+ 'ago' => 'prieš :time',
35
+ 'from_now' => 'už :time',
36
+ 'after' => 'po :time',
37
+ 'before' => ':time nuo dabar',
38
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/lv.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '0 gadiem|:count gada|:count gadiem',
14
+ 'y' => '0 gadiem|:count gada|:count gadiem',
15
+ 'month' => '0 mēnešiem|:count mēneša|:count mēnešiem',
16
+ 'm' => '0 mēnešiem|:count mēneša|:count mēnešiem',
17
+ 'week' => '0 nedēļām|:count nedēļas|:count nedēļām',
18
+ 'w' => '0 nedēļām|:count nedēļas|:count nedēļām',
19
+ 'day' => '0 dienām|:count dienas|:count dienām',
20
+ 'd' => '0 dienām|:count dienas|:count dienām',
21
+ 'hour' => '0 stundām|:count stundas|:count stundām',
22
+ 'h' => '0 stundām|:count stundas|:count stundām',
23
+ 'minute' => '0 minūtēm|:count minūtes|:count minūtēm',
24
+ 'min' => '0 minūtēm|:count minūtes|:count minūtēm',
25
+ 'second' => '0 sekundēm|:count sekundes|:count sekundēm',
26
+ 's' => '0 sekundēm|:count sekundes|:count sekundēm',
27
+ 'ago' => 'pirms :time',
28
+ 'from_now' => 'pēc :time',
29
+ 'after' => ':time vēlāk',
30
+ 'before' => ':time pirms',
31
+
32
+ 'year_after' => '0 gadus|:count gadu|:count gadus',
33
+ 'month_after' => '0 mēnešus|:count mēnesi|:count mēnešus',
34
+ 'week_after' => '0 nedēļas|:count nedēļu|:count nedēļas',
35
+ 'day_after' => '0 dienas|:count dienu|:count dienas',
36
+ 'hour_after' => '0 stundas|:count stundu|:count stundas',
37
+ 'minute_after' => '0 minūtes|:count minūti|:count minūtes',
38
+ 'second_after' => '0 sekundes|:count sekundi|:count sekundes',
39
+
40
+ 'year_before' => '0 gadus|:count gadu|:count gadus',
41
+ 'month_before' => '0 mēnešus|:count mēnesi|:count mēnešus',
42
+ 'week_before' => '0 nedēļas|:count nedēļu|:count nedēļas',
43
+ 'day_before' => '0 dienas|:count dienu|:count dienas',
44
+ 'hour_before' => '0 stundas|:count stundu|:count stundas',
45
+ 'minute_before' => '0 minūtes|:count minūti|:count minūtes',
46
+ 'second_before' => '0 sekundes|:count sekundi|:count sekundes',
47
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/mk.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count година|:count години',
14
+ 'month' => ':count месец|:count месеци',
15
+ 'week' => ':count седмица|:count седмици',
16
+ 'day' => ':count ден|:count дена',
17
+ 'hour' => ':count час|:count часа',
18
+ 'minute' => ':count минута|:count минути',
19
+ 'second' => ':count секунда|:count секунди',
20
+ 'ago' => 'пред :time',
21
+ 'from_now' => ':time од сега',
22
+ 'after' => 'по :time',
23
+ 'before' => 'пред :time',
24
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/mn.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ *
12
+ * @translator Batmandakh Erdenebileg <batmandakh.e@icloud.com>
13
+ */
14
+
15
+ return array(
16
+ 'year' => ':count жил',
17
+ 'y' => ':count жил',
18
+ 'month' => ':count сар',
19
+ 'm' => ':count сар',
20
+ 'week' => ':count долоо хоног',
21
+ 'w' => ':count долоо хоног',
22
+ 'day' => ':count өдөр',
23
+ 'd' => ':count өдөр',
24
+ 'hour' => ':count цаг',
25
+ 'h' => ':countц',
26
+ 'minute' => ':count минут',
27
+ 'min' => ':countм',
28
+ 'second' => ':count секунд',
29
+ 's' => ':countс',
30
+
31
+ 'ago' => ':timeн өмнө',
32
+ 'year_ago' => ':count жилий',
33
+ 'month_ago' => ':count сары',
34
+ 'day_ago' => ':count хоногий',
35
+ 'hour_ago' => ':count цагий',
36
+ 'minute_ago' => ':count минуты',
37
+ 'second_ago' => ':count секунды',
38
+
39
+ 'from_now' => 'одоогоос :time',
40
+ 'year_from_now' => ':count жилийн дараа',
41
+ 'month_from_now' => ':count сарын дараа',
42
+ 'day_from_now' => ':count хоногийн дараа',
43
+ 'hour_from_now' => ':count цагийн дараа',
44
+ 'minute_from_now' => ':count минутын дараа',
45
+ 'second_from_now' => ':count секундын дараа',
46
+
47
+ // Does it required to make translation for before, after as follows? hmm, I think we've made it with ago and from now keywords already. Anyway, I've included it just in case of undesired action...
48
+ 'after' => ':timeн дараа',
49
+ 'year_after' => ':count жилий',
50
+ 'month_after' => ':count сары',
51
+ 'day_after' => ':count хоногий',
52
+ 'hour_after' => ':count цагий',
53
+ 'minute_after' => ':count минуты',
54
+ 'second_after' => ':count секунды',
55
+ 'before' => ':timeн өмнө',
56
+ 'year_before' => ':count жилий',
57
+ 'month_before' => ':count сары',
58
+ 'day_before' => ':count хоногий',
59
+ 'hour_before' => ':count цагий',
60
+ 'minute_before' => ':count минуты',
61
+ 'second_before' => ':count секунды',
62
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ms.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count tahun',
14
+ 'y' => ':count tahun',
15
+ 'month' => ':count bulan',
16
+ 'm' => ':count bulan',
17
+ 'week' => ':count minggu',
18
+ 'w' => ':count minggu',
19
+ 'day' => ':count hari',
20
+ 'd' => ':count hari',
21
+ 'hour' => ':count jam',
22
+ 'h' => ':count jam',
23
+ 'minute' => ':count minit',
24
+ 'min' => ':count minit',
25
+ 'second' => ':count saat',
26
+ 's' => ':count saat',
27
+ 'ago' => ':time yang lalu',
28
+ 'from_now' => ':time dari sekarang',
29
+ 'after' => ':time selepas',
30
+ 'before' => ':time sebelum',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ne.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count वर्ष',
14
+ 'y' => ':count वर्ष',
15
+ 'month' => ':count महिना',
16
+ 'm' => ':count महिना',
17
+ 'week' => ':count हप्ता',
18
+ 'w' => ':count हप्ता',
19
+ 'day' => ':count दिन',
20
+ 'd' => ':count दिन',
21
+ 'hour' => ':count घण्टा',
22
+ 'h' => ':count घण्टा',
23
+ 'minute' => ':count मिनेट',
24
+ 'min' => ':count मिनेट',
25
+ 'second' => ':count सेकेण्ड',
26
+ 's' => ':count सेकेण्ड',
27
+ 'ago' => ':time पहिले',
28
+ 'from_now' => ':time देखि',
29
+ 'after' => ':time पछि',
30
+ 'before' => ':time अघि',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/nl.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count jaar',
14
+ 'y' => ':count jaar',
15
+ 'month' => ':count maand|:count maanden',
16
+ 'm' => ':count maand|:count maanden',
17
+ 'week' => ':count week|:count weken',
18
+ 'w' => ':count week|:count weken',
19
+ 'day' => ':count dag|:count dagen',
20
+ 'd' => ':count dag|:count dagen',
21
+ 'hour' => ':count uur',
22
+ 'h' => ':count uur',
23
+ 'minute' => ':count minuut|:count minuten',
24
+ 'min' => ':count minuut|:count minuten',
25
+ 'second' => ':count seconde|:count seconden',
26
+ 's' => ':count seconde|:count seconden',
27
+ 'ago' => ':time geleden',
28
+ 'from_now' => 'over :time',
29
+ 'after' => ':time later',
30
+ 'before' => ':time eerder',
31
+ 'diff_now' => 'nu',
32
+ 'diff_yesterday' => 'gisteren',
33
+ 'diff_tomorrow' => 'morgen',
34
+ 'diff_after_tomorrow' => 'overmorgen',
35
+ 'diff_before_yesterday' => 'eergisteren',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/no.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count år|:count år',
14
+ 'y' => ':count år|:count år',
15
+ 'month' => ':count måned|:count måneder',
16
+ 'm' => ':count måned|:count måneder',
17
+ 'week' => ':count uke|:count uker',
18
+ 'w' => ':count uke|:count uker',
19
+ 'day' => ':count dag|:count dager',
20
+ 'd' => ':count dag|:count dager',
21
+ 'hour' => ':count time|:count timer',
22
+ 'h' => ':count time|:count timer',
23
+ 'minute' => ':count minutt|:count minutter',
24
+ 'min' => ':count minutt|:count minutter',
25
+ 'second' => ':count sekund|:count sekunder',
26
+ 's' => ':count sekund|:count sekunder',
27
+ 'ago' => ':time siden',
28
+ 'from_now' => 'om :time',
29
+ 'after' => ':time etter',
30
+ 'before' => ':time før',
31
+ 'diff_now' => 'akkurat nå',
32
+ 'diff_yesterday' => 'i går',
33
+ 'diff_tomorrow' => 'i morgen',
34
+ 'diff_before_yesterday' => 'i forgårs',
35
+ 'diff_after_tomorrow' => 'i overmorgen',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/oc.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ \Symfony\Component\Translation\PluralizationRules::set(function ($number) {
13
+ return $number == 1 ? 0 : 1;
14
+ }, 'oc');
15
+
16
+ return array(
17
+ 'year' => ':count an|:count ans',
18
+ 'y' => ':count an|:count ans',
19
+ 'month' => ':count mes|:count meses',
20
+ 'm' => ':count mes|:count meses',
21
+ 'week' => ':count setmana|:count setmanas',
22
+ 'w' => ':count setmana|:count setmanas',
23
+ 'day' => ':count jorn|:count jorns',
24
+ 'd' => ':count jorn|:count jorns',
25
+ 'hour' => ':count ora|:count oras',
26
+ 'h' => ':count ora|:count oras',
27
+ 'minute' => ':count minuta|:count minutas',
28
+ 'min' => ':count minuta|:count minutas',
29
+ 'second' => ':count segonda|:count segondas',
30
+ 's' => ':count segonda|:count segondas',
31
+ 'ago' => 'fa :time',
32
+ 'from_now' => 'dins :time',
33
+ 'after' => ':time aprèp',
34
+ 'before' => ':time abans',
35
+ 'diff_now' => 'ara meteis',
36
+ 'diff_yesterday' => 'ièr',
37
+ 'diff_tomorrow' => 'deman',
38
+ 'diff_before_yesterday' => 'ièr delà',
39
+ 'diff_after_tomorrow' => 'deman passat',
40
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/pl.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count rok|:count lata|:count lat',
14
+ 'y' => ':countr|:countl',
15
+ 'month' => ':count miesiąc|:count miesiące|:count miesięcy',
16
+ 'm' => ':countmies',
17
+ 'week' => ':count tydzień|:count tygodnie|:count tygodni',
18
+ 'w' => ':counttyg',
19
+ 'day' => ':count dzień|:count dni|:count dni',
20
+ 'd' => ':countd',
21
+ 'hour' => ':count godzina|:count godziny|:count godzin',
22
+ 'h' => ':countg',
23
+ 'minute' => ':count minuta|:count minuty|:count minut',
24
+ 'min' => ':countm',
25
+ 'second' => ':count sekunda|:count sekundy|:count sekund',
26
+ 's' => ':counts',
27
+ 'ago' => ':time temu',
28
+ 'from_now' => ':time od teraz',
29
+ 'after' => ':time po',
30
+ 'before' => ':time przed',
31
+ 'diff_now' => 'przed chwilą',
32
+ 'diff_yesterday' => 'wczoraj',
33
+ 'diff_tomorrow' => 'jutro',
34
+ 'diff_before_yesterday' => 'przedwczoraj',
35
+ 'diff_after_tomorrow' => 'pojutrze',
36
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ps.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count کال|:count کاله',
14
+ 'y' => ':countکال|:countکاله',
15
+ 'month' => ':count مياشت|:count مياشتي',
16
+ 'm' => ':countمياشت|:countمياشتي',
17
+ 'week' => ':count اونۍ|:count اونۍ',
18
+ 'w' => ':countاونۍ|:countاونۍ',
19
+ 'day' => ':count ورځ|:count ورځي',
20
+ 'd' => ':countورځ|:countورځي',
21
+ 'hour' => ':count ساعت|:count ساعته',
22
+ 'h' => ':countساعت|:countساعته',
23
+ 'minute' => ':count دقيقه|:count دقيقې',
24
+ 'min' => ':countدقيقه|:countدقيقې',
25
+ 'second' => ':count ثانيه|:count ثانيې',
26
+ 's' => ':countثانيه|:countثانيې',
27
+ 'ago' => ':time دمخه',
28
+ 'from_now' => ':time له اوس څخه',
29
+ 'after' => ':time وروسته',
30
+ 'before' => ':time دمخه',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/pt.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count ano|:count anos',
14
+ 'y' => ':count ano|:count anos',
15
+ 'month' => ':count mês|:count meses',
16
+ 'm' => ':count mês|:count meses',
17
+ 'week' => ':count semana|:count semanas',
18
+ 'w' => ':count semana|:count semanas',
19
+ 'day' => ':count dia|:count dias',
20
+ 'd' => ':count dia|:count dias',
21
+ 'hour' => ':count hora|:count horas',
22
+ 'h' => ':count hora|:count horas',
23
+ 'minute' => ':count minuto|:count minutos',
24
+ 'min' => ':count minuto|:count minutos',
25
+ 'second' => ':count segundo|:count segundos',
26
+ 's' => ':count segundo|:count segundos',
27
+ 'ago' => ':time atrás',
28
+ 'from_now' => 'em :time',
29
+ 'after' => ':time depois',
30
+ 'before' => ':time antes',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count ano|:count anos',
14
+ 'y' => ':count ano|:count anos',
15
+ 'month' => ':count mês|:count meses',
16
+ 'm' => ':count mês|:count meses',
17
+ 'week' => ':count semana|:count semanas',
18
+ 'w' => ':count semana|:count semanas',
19
+ 'day' => ':count dia|:count dias',
20
+ 'd' => ':count dia|:count dias',
21
+ 'hour' => ':count hora|:count horas',
22
+ 'h' => ':count hora|:count horas',
23
+ 'minute' => ':count minuto|:count minutos',
24
+ 'min' => ':count minuto|:count minutos',
25
+ 'second' => ':count segundo|:count segundos',
26
+ 's' => ':count segundo|:count segundos',
27
+ 'ago' => 'há :time',
28
+ 'from_now' => 'em :time',
29
+ 'after' => 'após :time',
30
+ 'before' => ':time atrás',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ro.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => 'un an|:count ani|:count ani',
14
+ 'y' => 'un an|:count ani|:count ani',
15
+ 'month' => 'o lună|:count luni|:count luni',
16
+ 'm' => 'o lună|:count luni|:count luni',
17
+ 'week' => 'o săptămână|:count săptămâni|:count săptămâni',
18
+ 'w' => 'o săptămână|:count săptămâni|:count săptămâni',
19
+ 'day' => 'o zi|:count zile|:count zile',
20
+ 'd' => 'o zi|:count zile|:count zile',
21
+ 'hour' => 'o oră|:count ore|:count ore',
22
+ 'h' => 'o oră|:count ore|:count ore',
23
+ 'minute' => 'un minut|:count minute|:count minute',
24
+ 'min' => 'un minut|:count minute|:count minute',
25
+ 'second' => 'o secundă|:count secunde|:count secunde',
26
+ 's' => 'o secundă|:count secunde|:count secunde',
27
+ 'ago' => 'acum :time',
28
+ 'from_now' => ':time de acum',
29
+ 'after' => 'peste :time',
30
+ 'before' => 'acum :time',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ru.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count год|:count года|:count лет',
14
+ 'y' => ':count год|:count года|:count лет',
15
+ 'month' => ':count месяц|:count месяца|:count месяцев',
16
+ 'm' => ':count месяц|:count месяца|:count месяцев',
17
+ 'week' => ':count неделю|:count недели|:count недель',
18
+ 'w' => ':count неделю|:count недели|:count недель',
19
+ 'day' => ':count день|:count дня|:count дней',
20
+ 'd' => ':count день|:count дня|:count дней',
21
+ 'hour' => ':count час|:count часа|:count часов',
22
+ 'h' => ':count час|:count часа|:count часов',
23
+ 'minute' => ':count минуту|:count минуты|:count минут',
24
+ 'min' => ':count минуту|:count минуты|:count минут',
25
+ 'second' => ':count секунду|:count секунды|:count секунд',
26
+ 's' => ':count секунду|:count секунды|:count секунд',
27
+ 'ago' => ':time назад',
28
+ 'from_now' => 'через :time',
29
+ 'after' => ':time после',
30
+ 'before' => ':time до',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sh.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count godina|:count godine|:count godina',
14
+ 'y' => ':count godina|:count godine|:count godina',
15
+ 'month' => ':count mesec|:count meseca|:count meseci',
16
+ 'm' => ':count mesec|:count meseca|:count meseci',
17
+ 'week' => ':count nedelja|:count nedelje|:count nedelja',
18
+ 'w' => ':count nedelja|:count nedelje|:count nedelja',
19
+ 'day' => ':count dan|:count dana|:count dana',
20
+ 'd' => ':count dan|:count dana|:count dana',
21
+ 'hour' => ':count čas|:count časa|:count časova',
22
+ 'h' => ':count čas|:count časa|:count časova',
23
+ 'minute' => ':count minut|:count minuta|:count minuta',
24
+ 'min' => ':count minut|:count minuta|:count minuta',
25
+ 'second' => ':count sekund|:count sekunda|:count sekundi',
26
+ 's' => ':count sekund|:count sekunda|:count sekundi',
27
+ 'ago' => 'pre :time',
28
+ 'from_now' => 'za :time',
29
+ 'after' => 'nakon :time',
30
+ 'before' => ':time raniјe',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sk.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => 'rok|:count roky|:count rokov',
14
+ 'y' => 'rok|:count roky|:count rokov',
15
+ 'month' => 'mesiac|:count mesiace|:count mesiacov',
16
+ 'm' => 'mesiac|:count mesiace|:count mesiacov',
17
+ 'week' => 'týždeň|:count týždne|:count týždňov',
18
+ 'w' => 'týždeň|:count týždne|:count týždňov',
19
+ 'day' => 'deň|:count dni|:count dní',
20
+ 'd' => 'deň|:count dni|:count dní',
21
+ 'hour' => 'hodinu|:count hodiny|:count hodín',
22
+ 'h' => 'hodinu|:count hodiny|:count hodín',
23
+ 'minute' => 'minútu|:count minúty|:count minút',
24
+ 'min' => 'minútu|:count minúty|:count minút',
25
+ 'second' => 'sekundu|:count sekundy|:count sekúnd',
26
+ 's' => 'sekundu|:count sekundy|:count sekúnd',
27
+ 'ago' => 'pred :time',
28
+ 'from_now' => 'za :time',
29
+ 'after' => 'o :time neskôr',
30
+ 'before' => ':time predtým',
31
+ 'year_ago' => 'rokom|:count rokmi|:count rokmi',
32
+ 'month_ago' => 'mesiacom|:count mesiacmi|:count mesiacmi',
33
+ 'week_ago' => 'týždňom|:count týždňami|:count týždňami',
34
+ 'day_ago' => 'dňom|:count dňami|:count dňami',
35
+ 'hour_ago' => 'hodinou|:count hodinami|:count hodinami',
36
+ 'minute_ago' => 'minútou|:count minútami|:count minútami',
37
+ 'second_ago' => 'sekundou|:count sekundami|:count sekundami',
38
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sl.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count leto|:count leti|:count leta|:count let',
14
+ 'y' => ':count leto|:count leti|:count leta|:count let',
15
+ 'month' => ':count mesec|:count meseca|:count mesece|:count mesecev',
16
+ 'm' => ':count mesec|:count meseca|:count mesece|:count mesecev',
17
+ 'week' => ':count teden|:count tedna|:count tedne|:count tednov',
18
+ 'w' => ':count teden|:count tedna|:count tedne|:count tednov',
19
+ 'day' => ':count dan|:count dni|:count dni|:count dni',
20
+ 'd' => ':count dan|:count dni|:count dni|:count dni',
21
+ 'hour' => ':count uro|:count uri|:count ure|:count ur',
22
+ 'h' => ':count uro|:count uri|:count ure|:count ur',
23
+ 'minute' => ':count minuto|:count minuti|:count minute|:count minut',
24
+ 'min' => ':count minuto|:count minuti|:count minute|:count minut',
25
+ 'second' => ':count sekundo|:count sekundi|:count sekunde|:count sekund',
26
+ 's' => ':count sekundo|:count sekundi|:count sekunde|:count sekund',
27
+ 'year_ago' => ':count letom|:count leti|:count leti|:count leti',
28
+ 'month_ago' => ':count mesecem|:count meseci|:count meseci|:count meseci',
29
+ 'week_ago' => ':count tednom|:count tednoma|:count tedni|:count tedni',
30
+ 'day_ago' => ':count dnem|:count dnevoma|:count dnevi|:count dnevi',
31
+ 'hour_ago' => ':count uro|:count urama|:count urami|:count urami',
32
+ 'minute_ago' => ':count minuto|:count minutama|:count minutami|:count minutami',
33
+ 'second_ago' => ':count sekundo|:count sekundama|:count sekundami|:count sekundami',
34
+ 'ago' => 'pred :time',
35
+ 'from_now' => 'čez :time',
36
+ 'after' => 'čez :time',
37
+ 'before' => 'pred :time',
38
+ 'diff_now' => 'ravnokar',
39
+ 'diff_yesterday' => 'včeraj',
40
+ 'diff_tomorrow' => 'jutri',
41
+ 'diff_before_yesterday' => 'predvčerajšnjim',
42
+ 'diff_after_tomorrow' => 'pojutrišnjem',
43
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sq.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count vit|:count vjet',
14
+ 'y' => ':count vit|:count vjet',
15
+ 'month' => ':count muaj|:count muaj',
16
+ 'm' => ':count muaj|:count muaj',
17
+ 'week' => ':count javë|:count javë',
18
+ 'w' => ':count javë|:count javë',
19
+ 'day' => ':count ditë|:count ditë',
20
+ 'd' => ':count ditë|:count ditë',
21
+ 'hour' => ':count orë|:count orë',
22
+ 'h' => ':count orë|:count orë',
23
+ 'minute' => ':count minutë|:count minuta',
24
+ 'min' => ':count minutë|:count minuta',
25
+ 'second' => ':count sekondë|:count sekonda',
26
+ 's' => ':count sekondë|:count sekonda',
27
+ 'ago' => ':time më parë',
28
+ 'from_now' => ':time nga tani',
29
+ 'after' => ':time pas',
30
+ 'before' => ':time para',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sr.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count godina|:count godine|:count godina',
14
+ 'y' => ':count godina|:count godine|:count godina',
15
+ 'month' => ':count mesec|:count meseca|:count meseci',
16
+ 'm' => ':count mesec|:count meseca|:count meseci',
17
+ 'week' => ':count nedelja|:count nedelje|:count nedelja',
18
+ 'w' => ':count nedelja|:count nedelje|:count nedelja',
19
+ 'day' => ':count dan|:count dana|:count dana',
20
+ 'd' => ':count dan|:count dana|:count dana',
21
+ 'hour' => ':count sat|:count sata|:count sati',
22
+ 'h' => ':count sat|:count sata|:count sati',
23
+ 'minute' => ':count minut|:count minuta |:count minuta',
24
+ 'min' => ':count minut|:count minuta |:count minuta',
25
+ 'second' => ':count sekund|:count sekunde|:count sekunde',
26
+ 's' => ':count sekund|:count sekunde|:count sekunde',
27
+ 'ago' => 'pre :time',
28
+ 'from_now' => ':time od sada',
29
+ 'after' => 'nakon :time',
30
+ 'before' => 'pre :time',
31
+
32
+ 'year_from_now' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
33
+ 'year_ago' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
34
+
35
+ 'week_from_now' => '{1} :count nedelju|{2,3,4} :count nedelje|[5,Inf[ :count nedelja',
36
+ 'week_ago' => '{1} :count nedelju|{2,3,4} :count nedelje|[5,Inf[ :count nedelja',
37
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Nikola Zeravcic <office@bytenet.rs>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count године|[0,Inf[ :count година',
14
+ 'y' => ':count г.',
15
+ 'month' => '{1} :count месец|{2,3,4}:count месеца|[5,Inf[ :count месеци',
16
+ 'm' => ':count м.',
17
+ 'week' => '{1} :count недеља|{2,3,4}:count недеље|[5,Inf[ :count недеља',
18
+ 'w' => ':count нед.',
19
+ 'day' => '{1,21,31} :count дан|[2,Inf[ :count дана',
20
+ 'd' => ':count д.',
21
+ 'hour' => '{1,21} :count сат|{2,3,4,22,23,24}:count сата|[5,Inf[ :count сати',
22
+ 'h' => ':count ч.',
23
+ 'minute' => '{1,21,31,41,51} :count минут|[2,Inf[ :count минута',
24
+ 'min' => ':count мин.',
25
+ 'second' => '{1,21,31,41,51} :count секунд|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count секунде|[5,Inf[:count секунди',
26
+ 's' => ':count сек.',
27
+ 'ago' => 'пре :time',
28
+ 'from_now' => 'за :time',
29
+ 'after' => ':time након',
30
+ 'before' => ':time пре',
31
+
32
+ 'year_from_now' => '{1,21,31,41,51} :count годину|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count године|[5,Inf[ :count година',
33
+ 'year_ago' => '{1,21,31,41,51} :count годину|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count године|[5,Inf[ :count година',
34
+
35
+ 'week_from_now' => '{1} :count недељу|{2,3,4} :count недеље|[5,Inf[ :count недеља',
36
+ 'week_ago' => '{1} :count недељу|{2,3,4} :count недеље|[5,Inf[ :count недеља',
37
+
38
+ 'diff_now' => 'управо сада',
39
+ 'diff_yesterday' => 'јуче',
40
+ 'diff_tomorrow' => 'сутра',
41
+ 'diff_before_yesterday' => 'прекјуче',
42
+ 'diff_after_tomorrow' => 'прекосутра',
43
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sr_Cyrl_ME.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count године|[0,Inf[ :count година',
14
+ 'y' => ':count г.',
15
+ 'month' => '{1} :count мјесец|{2,3,4}:count мјесеца|[5,Inf[ :count мјесеци',
16
+ 'm' => ':count мј.',
17
+ 'week' => '{1} :count недјеља|{2,3,4}:count недјеље|[5,Inf[ :count недјеља',
18
+ 'w' => ':count нед.',
19
+ 'day' => '{1,21,31} :count дан|[2,Inf[ :count дана',
20
+ 'd' => ':count д.',
21
+ 'hour' => '{1,21} :count сат|{2,3,4,22,23,24}:count сата|[5,Inf[ :count сати',
22
+ 'h' => ':count ч.',
23
+ 'minute' => '{1,21,31,41,51} :count минут|[2,Inf[ :count минута',
24
+ 'min' => ':count мин.',
25
+ 'second' => '{1,21,31,41,51} :count секунд|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count секунде|[5,Inf[:count секунди',
26
+ 's' => ':count сек.',
27
+ 'ago' => 'прије :time',
28
+ 'from_now' => 'за :time',
29
+ 'after' => ':time након',
30
+ 'before' => ':time прије',
31
+
32
+ 'year_from_now' => '{1,21,31,41,51} :count годину|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count године|[5,Inf[ :count година',
33
+ 'year_ago' => '{1,21,31,41,51} :count годину|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count године|[5,Inf[ :count година',
34
+
35
+ 'week_from_now' => '{1} :count недјељу|{2,3,4} :count недјеље|[5,Inf[ :count недјеља',
36
+ 'week_ago' => '{1} :count недјељу|{2,3,4} :count недјеље|[5,Inf[ :count недјеља',
37
+
38
+ 'diff_now' => 'управо сада',
39
+ 'diff_yesterday' => 'јуче',
40
+ 'diff_tomorrow' => 'сутра',
41
+ 'diff_before_yesterday' => 'прекјуче',
42
+ 'diff_after_tomorrow' => 'прекосјутра',
43
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sr_Latn_ME.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => '{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count godine|[0,Inf[ :count godina',
14
+ 'y' => ':count g.',
15
+ 'month' => '{1} :count mjesec|{2,3,4}:count mjeseca|[5,Inf[ :count mjeseci',
16
+ 'm' => ':count mj.',
17
+ 'week' => '{1} :count nedjelja|{2,3,4}:count nedjelje|[5,Inf[ :count nedjelja',
18
+ 'w' => ':count ned.',
19
+ 'day' => '{1,21,31} :count dan|[2,Inf[ :count dana',
20
+ 'd' => ':count d.',
21
+ 'hour' => '{1,21} :count sat|{2,3,4,22,23,24}:count sata|[5,Inf[ :count sati',
22
+ 'h' => ':count č.',
23
+ 'minute' => '{1,21,31,41,51} :count minut|[2,Inf[ :count minuta',
24
+ 'min' => ':count min.',
25
+ 'second' => '{1,21,31,41,51} :count sekund|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54}:count sekunde|[5,Inf[:count sekundi',
26
+ 's' => ':count sek.',
27
+ 'ago' => 'prije :time',
28
+ 'from_now' => 'za :time',
29
+ 'after' => ':time nakon',
30
+ 'before' => ':time prije',
31
+
32
+ 'year_from_now' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
33
+ 'year_ago' => '{1,21,31,41,51} :count godinu|{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54} :count godine|[5,Inf[ :count godina',
34
+
35
+ 'week_from_now' => '{1} :count nedjelju|{2,3,4} :count nedjelje|[5,Inf[ :count nedjelja',
36
+ 'week_ago' => '{1} :count nedjelju|{2,3,4} :count nedjelje|[5,Inf[ :count nedjelja',
37
+
38
+ 'diff_now' => 'upravo sada',
39
+ 'diff_yesterday' => 'juče',
40
+ 'diff_tomorrow' => 'sutra',
41
+ 'diff_before_yesterday' => 'prekjuče',
42
+ 'diff_after_tomorrow' => 'preksutra',
43
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sr_ME.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return require __DIR__.'/sr_Latn_ME.php';
app/vendor/nesbot/carbon/src/Carbon/Lang/sv.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count år|:count år',
14
+ 'y' => ':count år|:count år',
15
+ 'month' => ':count månad|:count månader',
16
+ 'm' => ':count månad|:count månader',
17
+ 'week' => ':count vecka|:count veckor',
18
+ 'w' => ':count vecka|:count veckor',
19
+ 'day' => ':count dag|:count dagar',
20
+ 'd' => ':count dag|:count dagar',
21
+ 'hour' => ':count timme|:count timmar',
22
+ 'h' => ':count timme|:count timmar',
23
+ 'minute' => ':count minut|:count minuter',
24
+ 'min' => ':count minut|:count minuter',
25
+ 'second' => ':count sekund|:count sekunder',
26
+ 's' => ':count sekund|:count sekunder',
27
+ 'ago' => ':time sedan',
28
+ 'from_now' => 'om :time',
29
+ 'after' => ':time efter',
30
+ 'before' => ':time före',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/sw.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => 'mwaka 1|miaka :count',
14
+ 'y' => 'mwaka 1|miaka :count',
15
+ 'month' => 'mwezi 1|miezi :count',
16
+ 'm' => 'mwezi 1|miezi :count',
17
+ 'week' => 'wiki 1|wiki :count',
18
+ 'w' => 'wiki 1|wiki :count',
19
+ 'day' => 'siku 1|siku :count',
20
+ 'd' => 'siku 1|siku :count',
21
+ 'hour' => 'saa 1|masaa :count',
22
+ 'h' => 'saa 1|masaa :count',
23
+ 'minute' => 'dakika 1|dakika :count',
24
+ 'min' => 'dakika 1|dakika :count',
25
+ 'second' => 'sekunde 1|sekunde :count',
26
+ 's' => 'sekunde 1|sekunde :count',
27
+ 'ago' => ':time ziliyopita',
28
+ 'from_now' => ':time kwanzia sasa',
29
+ 'after' => ':time baada',
30
+ 'before' => ':time kabla',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/th.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count ปี',
14
+ 'y' => ':count ปี',
15
+ 'month' => ':count เดือน',
16
+ 'm' => ':count เดือน',
17
+ 'week' => ':count สัปดาห์',
18
+ 'w' => ':count สัปดาห์',
19
+ 'day' => ':count วัน',
20
+ 'd' => ':count วัน',
21
+ 'hour' => ':count ชั่วโมง',
22
+ 'h' => ':count ชั่วโมง',
23
+ 'minute' => ':count นาที',
24
+ 'min' => ':count นาที',
25
+ 'second' => ':count วินาที',
26
+ 's' => ':count วินาที',
27
+ 'ago' => ':timeที่แล้ว',
28
+ 'from_now' => ':timeต่อจากนี้',
29
+ 'after' => ':timeหลังจากนี้',
30
+ 'before' => ':timeก่อน',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/tr.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count yıl',
14
+ 'y' => ':count yıl',
15
+ 'month' => ':count ay',
16
+ 'm' => ':count ay',
17
+ 'week' => ':count hafta',
18
+ 'w' => ':count hafta',
19
+ 'day' => ':count gün',
20
+ 'd' => ':count gün',
21
+ 'hour' => ':count saat',
22
+ 'h' => ':count saat',
23
+ 'minute' => ':count dakika',
24
+ 'min' => ':count dakika',
25
+ 'second' => ':count saniye',
26
+ 's' => ':count saniye',
27
+ 'ago' => ':time önce',
28
+ 'from_now' => ':time sonra',
29
+ 'after' => ':time sonra',
30
+ 'before' => ':time önce',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/uk.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count рік|:count роки|:count років',
14
+ 'y' => ':count рік|:count роки|:count років',
15
+ 'month' => ':count місяць|:count місяці|:count місяців',
16
+ 'm' => ':count місяць|:count місяці|:count місяців',
17
+ 'week' => ':count тиждень|:count тижні|:count тижнів',
18
+ 'w' => ':count тиждень|:count тижні|:count тижнів',
19
+ 'day' => ':count день|:count дні|:count днів',
20
+ 'd' => ':count день|:count дні|:count днів',
21
+ 'hour' => ':count година|:count години|:count годин',
22
+ 'h' => ':count година|:count години|:count годин',
23
+ 'minute' => ':count хвилину|:count хвилини|:count хвилин',
24
+ 'min' => ':count хвилину|:count хвилини|:count хвилин',
25
+ 'second' => ':count секунду|:count секунди|:count секунд',
26
+ 's' => ':count секунду|:count секунди|:count секунд',
27
+ 'ago' => ':time тому',
28
+ 'from_now' => 'через :time',
29
+ 'after' => ':time після',
30
+ 'before' => ':time до',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/ur.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count سال',
14
+ 'month' => ':count ماه',
15
+ 'week' => ':count ہفتے',
16
+ 'day' => ':count روز',
17
+ 'hour' => ':count گھنٹے',
18
+ 'minute' => ':count منٹ',
19
+ 'second' => ':count سیکنڈ',
20
+ 'ago' => ':time پہلے',
21
+ 'from_now' => ':time بعد',
22
+ 'after' => ':time بعد',
23
+ 'before' => ':time پہلے',
24
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/uz.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count yil',
14
+ 'y' => ':count yil',
15
+ 'month' => ':count oy',
16
+ 'm' => ':count oy',
17
+ 'week' => ':count hafta',
18
+ 'w' => ':count hafta',
19
+ 'day' => ':count kun',
20
+ 'd' => ':count kun',
21
+ 'hour' => ':count soat',
22
+ 'h' => ':count soat',
23
+ 'minute' => ':count daqiqa',
24
+ 'min' => ':count daq',
25
+ 'second' => ':count soniya',
26
+ 's' => ':count s',
27
+ 'ago' => ':time avval',
28
+ 'from_now' => ':time dan keyin',
29
+ 'after' => ':time keyin',
30
+ 'before' => ':time oldin',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/vi.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count năm',
14
+ 'y' => ':count năm',
15
+ 'month' => ':count tháng',
16
+ 'm' => ':count tháng',
17
+ 'week' => ':count tuần',
18
+ 'w' => ':count tuần',
19
+ 'day' => ':count ngày',
20
+ 'd' => ':count ngày',
21
+ 'hour' => ':count giờ',
22
+ 'h' => ':count giờ',
23
+ 'minute' => ':count phút',
24
+ 'min' => ':count phút',
25
+ 'second' => ':count giây',
26
+ 's' => ':count giây',
27
+ 'ago' => ':time trước',
28
+ 'from_now' => ':time từ bây giờ',
29
+ 'after' => ':time sau',
30
+ 'before' => ':time trước',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/zh.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count年',
14
+ 'y' => ':count年',
15
+ 'month' => ':count个月',
16
+ 'm' => ':count个月',
17
+ 'week' => ':count周',
18
+ 'w' => ':count周',
19
+ 'day' => ':count天',
20
+ 'd' => ':count天',
21
+ 'hour' => ':count小时',
22
+ 'h' => ':count小时',
23
+ 'minute' => ':count分钟',
24
+ 'min' => ':count分钟',
25
+ 'second' => ':count秒',
26
+ 's' => ':count秒',
27
+ 'ago' => ':time前',
28
+ 'from_now' => '距现在:time',
29
+ 'after' => ':time后',
30
+ 'before' => ':time前',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Lang/zh_TW.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Carbon package.
5
+ *
6
+ * (c) Brian Nesbitt <brian@nesbot.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ return array(
13
+ 'year' => ':count年',
14
+ 'y' => ':count年',
15
+ 'month' => ':count月',
16
+ 'm' => ':count月',
17
+ 'week' => ':count週',
18
+ 'w' => ':count週',
19
+ 'day' => ':count天',
20
+ 'd' => ':count天',
21
+ 'hour' => ':count小時',
22
+ 'h' => ':count小時',
23
+ 'minute' => ':count分鐘',
24
+ 'min' => ':count分鐘',
25
+ 'second' => ':count秒',
26
+ 's' => ':count秒',
27
+ 'ago' => ':time前',
28
+ 'from_now' => '距現在:time',
29
+ 'after' => ':time後',
30
+ 'before' => ':time前',
31
+ );
app/vendor/nesbot/carbon/src/Carbon/Translator.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Carbon;
4
+
5
+ use Symfony\Component\Translation;
6
+
7
+ class Translator extends Translation\Translator
8
+ {
9
+ /**
10
+ * Singleton for Translator.
11
+ *
12
+ * @var static
13
+ */
14
+ protected static $singleton;
15
+
16
+ /**
17
+ * List of custom localized messages.
18
+ *
19
+ * @var array
20
+ */
21
+ protected static $messages = array();
22
+
23
+ /**
24
+ * Return a singleton instance of Translator.
25
+ *
26
+ * @param string|null $locale optional initial locale ("en" - english by default)
27
+ *
28
+ * @return static
29
+ */
30
+ public static function get($locale = null)
31
+ {
32
+ if (static::$singleton === null) {
33
+ static::$singleton = new static($locale ?: 'en');
34
+ }
35
+
36
+ return static::$singleton;
37
+ }
38
+
39
+ public function __construct($locale, Translation\Formatter\MessageFormatterInterface $formatter = null, $cacheDir = null, $debug = false)
40
+ {
41
+ $this->addLoader('array', new Translation\Loader\ArrayLoader());
42
+ parent::__construct($locale, $formatter, $cacheDir, $debug);
43
+ }
44
+
45
+ /**
46
+ * Reset messages of a locale (all locale if no locale passed).
47
+ * Remove custom messages and reload initial messages from matching
48
+ * file in Lang directory.
49
+ *
50
+ * @param string|null $locale
51
+ *
52
+ * @return bool
53
+ */
54
+ public function resetMessages($locale = null)
55
+ {
56
+ if ($locale === null) {
57
+ static::$messages = array();
58
+
59
+ return true;
60
+ }
61
+
62
+ if (file_exists($filename = __DIR__.'/Lang/'.$locale.'.php')) {
63
+ static::$messages[$locale] = require $filename;
64
+ $this->addResource('array', static::$messages[$locale], $locale);
65
+
66
+ return true;
67
+ }
68
+
69
+ return false;
70
+ }
71
+
72
+ /**
73
+ * Init messages language from matching file in Lang directory.
74
+ *
75
+ * @param string $locale
76
+ *
77
+ * @return bool
78
+ */
79
+ protected function loadMessagesFromFile($locale)
80
+ {
81
+ if (isset(static::$messages[$locale])) {
82
+ return true;
83
+ }
84
+
85
+ return $this->resetMessages($locale);
86
+ }
87
+
88
+ /**
89
+ * Set messages of a locale and take file first if present.
90
+ *
91
+ * @param string $locale
92
+ * @param array $messages
93
+ *
94
+ * @return $this
95
+ */
96
+ public function setMessages($locale, $messages)
97
+ {
98
+ $this->loadMessagesFromFile($locale);
99
+ $this->addResource('array', $messages, $locale);
100
+ static::$messages[$locale] = array_merge(
101
+ isset(static::$messages[$locale]) ? static::$messages[$locale] : array(),
102
+ $messages
103
+ );
104
+
105
+ return $this;
106
+ }
107
+
108
+ /**
109
+ * Get messages of a locale, if none given, return all the
110
+ * languages.
111
+ *
112
+ * @param string|null $locale
113
+ *
114
+ * @return array
115
+ */
116
+ public function getMessages($locale = null)
117
+ {
118
+ return $locale === null ? static::$messages : static::$messages[$locale];
119
+ }
120
+
121
+ /**
122
+ * Set the current translator locale and indicate if the source locale file exists
123
+ *
124
+ * @param string $locale locale ex. en
125
+ *
126
+ * @return bool
127
+ */
128
+ public function setLocale($locale)
129
+ {
130
+ $locale = preg_replace_callback('/[-_]([a-z]{2,})/', function ($matches) {
131
+ // _2-letters is a region, _3+-letters is a variant
132
+ return '_'.call_user_func(strlen($matches[1]) > 2 ? 'ucfirst' : 'strtoupper', $matches[1]);
133
+ }, strtolower($locale));
134
+
135
+ if ($this->loadMessagesFromFile($locale)) {
136
+ parent::setLocale($locale);
137
+
138
+ return true;
139
+ }
140
+
141
+ return false;
142
+ }
143
+ }
app/vendor/nesbot/carbon/src/JsonSerializable.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ interface JsonSerializable
4
+ {
5
+ /**
6
+ * Specify data which should be serialized to JSON.
7
+ *
8
+ * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
9
+ *
10
+ * @return mixed data which can be serialized by <b>json_encode</b>,
11
+ * which is a value of any type other than a resource.
12
+ *
13
+ * @since 5.4.0
14
+ */
15
+ public function jsonSerialize();
16
+ }
app/vendor/symfony/polyfill-mbstring/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2015-2018 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
app/vendor/symfony/polyfill-mbstring/Mbstring.php ADDED
@@ -0,0 +1,791 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Polyfill\Mbstring;
13
+
14
+ /**
15
+ * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
16
+ *
17
+ * Implemented:
18
+ * - mb_chr - Returns a specific character from its Unicode code point
19
+ * - mb_convert_encoding - Convert character encoding
20
+ * - mb_convert_variables - Convert character code in variable(s)
21
+ * - mb_decode_mimeheader - Decode string in MIME header field
22
+ * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
23
+ * - mb_decode_numericentity - Decode HTML numeric string reference to character
24
+ * - mb_encode_numericentity - Encode character to HTML numeric string reference
25
+ * - mb_convert_case - Perform case folding on a string
26
+ * - mb_detect_encoding - Detect character encoding
27
+ * - mb_get_info - Get internal settings of mbstring
28
+ * - mb_http_input - Detect HTTP input character encoding
29
+ * - mb_http_output - Set/Get HTTP output character encoding
30
+ * - mb_internal_encoding - Set/Get internal character encoding
31
+ * - mb_list_encodings - Returns an array of all supported encodings
32
+ * - mb_ord - Returns the Unicode code point of a character
33
+ * - mb_output_handler - Callback function converts character encoding in output buffer
34
+ * - mb_scrub - Replaces ill-formed byte sequences with substitute characters
35
+ * - mb_strlen - Get string length
36
+ * - mb_strpos - Find position of first occurrence of string in a string
37
+ * - mb_strrpos - Find position of last occurrence of a string in a string
38
+ * - mb_strtolower - Make a string lowercase
39
+ * - mb_strtoupper - Make a string uppercase
40
+ * - mb_substitute_character - Set/Get substitution character
41
+ * - mb_substr - Get part of string
42
+ * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive
43
+ * - mb_stristr - Finds first occurrence of a string within another, case insensitive
44
+ * - mb_strrchr - Finds the last occurrence of a character in a string within another
45
+ * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive
46
+ * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive
47
+ * - mb_strstr - Finds first occurrence of a string within anothers
48
+ * - mb_strwidth - Return width of string
49
+ * - mb_substr_count - Count the number of substring occurrences
50
+ *
51
+ * Not implemented:
52
+ * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
53
+ * - mb_ereg_* - Regular expression with multibyte support
54
+ * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable
55
+ * - mb_preferred_mime_name - Get MIME charset string
56
+ * - mb_regex_encoding - Returns current encoding for multibyte regex as string
57
+ * - mb_regex_set_options - Set/Get the default options for mbregex functions
58
+ * - mb_send_mail - Send encoded mail
59
+ * - mb_split - Split multibyte string using regular expression
60
+ * - mb_strcut - Get part of string
61
+ * - mb_strimwidth - Get truncated string with specified width
62
+ *
63
+ * @author Nicolas Grekas <p@tchwork.com>
64
+ *
65
+ * @internal
66
+ */
67
+ final class Mbstring
68
+ {
69
+ const MB_CASE_FOLD = PHP_INT_MAX;
70
+
71
+ private static $encodingList = array('ASCII', 'UTF-8');
72
+ private static $language = 'neutral';
73
+ private static $internalEncoding = 'UTF-8';
74
+ private static $caseFold = array(
75
+ array('µ','ſ',"\xCD\x85",'ς',"\xCF\x90","\xCF\x91","\xCF\x95","\xCF\x96","\xCF\xB0","\xCF\xB1","\xCF\xB5","\xE1\xBA\x9B","\xE1\xBE\xBE"),
76
+ array('μ','s','ι', 'σ','β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1",'ι'),
77
+ );
78
+
79
+ public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
80
+ {
81
+ if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
82
+ $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
83
+ } else {
84
+ $fromEncoding = self::getEncoding($fromEncoding);
85
+ }
86
+
87
+ $toEncoding = self::getEncoding($toEncoding);
88
+
89
+ if ('BASE64' === $fromEncoding) {
90
+ $s = base64_decode($s);
91
+ $fromEncoding = $toEncoding;
92
+ }
93
+
94
+ if ('BASE64' === $toEncoding) {
95
+ return base64_encode($s);
96
+ }
97
+
98
+ if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
99
+ if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
100
+ $fromEncoding = 'Windows-1252';
101
+ }
102
+ if ('UTF-8' !== $fromEncoding) {
103
+ $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
104
+ }
105
+
106
+ return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
107
+ }
108
+
109
+ if ('HTML-ENTITIES' === $fromEncoding) {
110
+ $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
111
+ $fromEncoding = 'UTF-8';
112
+ }
113
+
114
+ return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
115
+ }
116
+
117
+ public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
118
+ {
119
+ $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
120
+
121
+ $ok = true;
122
+ array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
123
+ if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
124
+ $ok = false;
125
+ }
126
+ });
127
+
128
+ return $ok ? $fromEncoding : false;
129
+ }
130
+
131
+ public static function mb_decode_mimeheader($s)
132
+ {
133
+ return iconv_mime_decode($s, 2, self::$internalEncoding);
134
+ }
135
+
136
+ public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
137
+ {
138
+ trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
139
+ }
140
+
141
+ public static function mb_decode_numericentity($s, $convmap, $encoding = null)
142
+ {
143
+ if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
144
+ trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.gettype($s).' given', E_USER_WARNING);
145
+ return null;
146
+ }
147
+
148
+ if (!\is_array($convmap) || !$convmap) {
149
+ return false;
150
+ }
151
+
152
+ if (null !== $encoding && !\is_scalar($encoding)) {
153
+ trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.gettype($s).' given', E_USER_WARNING);
154
+ return ''; // Instead of null (cf. mb_encode_numericentity).
155
+ }
156
+
157
+ $s = (string) $s;
158
+ if ('' === $s) {
159
+ return '';
160
+ }
161
+
162
+ $encoding = self::getEncoding($encoding);
163
+
164
+ if ('UTF-8' === $encoding) {
165
+ $encoding = null;
166
+ if (!preg_match('//u', $s)) {
167
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
168
+ }
169
+ } else {
170
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
171
+ }
172
+
173
+ $cnt = floor(\count($convmap) / 4) * 4;
174
+
175
+ for ($i = 0; $i < $cnt; $i += 4) {
176
+ // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
177
+ $convmap[$i] += $convmap[$i + 2];
178
+ $convmap[$i + 1] += $convmap[$i + 2];
179
+ }
180
+
181
+ $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
182
+ $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
183
+ for ($i = 0; $i < $cnt; $i += 4) {
184
+ if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
185
+ return Mbstring::mb_chr($c - $convmap[$i + 2]);
186
+ }
187
+ }
188
+ return $m[0];
189
+ }, $s);
190
+
191
+ if (null === $encoding) {
192
+ return $s;
193
+ }
194
+
195
+ return iconv('UTF-8', $encoding.'//IGNORE', $s);
196
+ }
197
+
198
+ public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
199
+ {
200
+ if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
201
+ trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.gettype($s).' given', E_USER_WARNING);
202
+ return null;
203
+ }
204
+
205
+ if (!\is_array($convmap) || !$convmap) {
206
+ return false;
207
+ }
208
+
209
+ if (null !== $encoding && !\is_scalar($encoding)) {
210
+ trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.gettype($s).' given', E_USER_WARNING);
211
+ return null; // Instead of '' (cf. mb_decode_numericentity).
212
+ }
213
+
214
+ if (null !== $is_hex && !\is_scalar($is_hex)) {
215
+ trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.gettype($s).' given', E_USER_WARNING);
216
+ return null;
217
+ }
218
+
219
+ $s = (string) $s;
220
+ if ('' === $s) {
221
+ return '';
222
+ }
223
+
224
+ $encoding = self::getEncoding($encoding);
225
+
226
+ if ('UTF-8' === $encoding) {
227
+ $encoding = null;
228
+ if (!preg_match('//u', $s)) {
229
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
230
+ }
231
+ } else {
232
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
233
+ }
234
+
235
+ static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
236
+
237
+ $cnt = floor(\count($convmap) / 4) * 4;
238
+ $i = 0;
239
+ $len = \strlen($s);
240
+ $result = '';
241
+
242
+ while ($i < $len) {
243
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
244
+ $uchr = substr($s, $i, $ulen);
245
+ $i += $ulen;
246
+ $c = self::mb_ord($uchr);
247
+
248
+ for ($j = 0; $j < $cnt; $j += 4) {
249
+ if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
250
+ $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
251
+ $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
252
+ continue 2;
253
+ }
254
+ }
255
+ $result .= $uchr;
256
+ }
257
+
258
+ if (null === $encoding) {
259
+ return $result;
260
+ }
261
+
262
+ return iconv('UTF-8', $encoding.'//IGNORE', $result);
263
+ }
264
+
265
+ public static function mb_convert_case($s, $mode, $encoding = null)
266
+ {
267
+ $s = (string) $s;
268
+ if ('' === $s) {
269
+ return '';
270
+ }
271
+
272
+ $encoding = self::getEncoding($encoding);
273
+
274
+ if ('UTF-8' === $encoding) {
275
+ $encoding = null;
276
+ if (!preg_match('//u', $s)) {
277
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
278
+ }
279
+ } else {
280
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
281
+ }
282
+
283
+ if (MB_CASE_TITLE == $mode) {
284
+ $s = preg_replace_callback('/\b\p{Ll}/u', array(__CLASS__, 'title_case_upper'), $s);
285
+ $s = preg_replace_callback('/\B[\p{Lu}\p{Lt}]+/u', array(__CLASS__, 'title_case_lower'), $s);
286
+ } else {
287
+ if (MB_CASE_UPPER == $mode) {
288
+ static $upper = null;
289
+ if (null === $upper) {
290
+ $upper = self::getData('upperCase');
291
+ }
292
+ $map = $upper;
293
+ } else {
294
+ if (self::MB_CASE_FOLD === $mode) {
295
+ $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
296
+ }
297
+
298
+ static $lower = null;
299
+ if (null === $lower) {
300
+ $lower = self::getData('lowerCase');
301
+ }
302
+ $map = $lower;
303
+ }
304
+
305
+ static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
306
+
307
+ $i = 0;
308
+ $len = \strlen($s);
309
+
310
+ while ($i < $len) {
311
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
312
+ $uchr = substr($s, $i, $ulen);
313
+ $i += $ulen;
314
+
315
+ if (isset($map[$uchr])) {
316
+ $uchr = $map[$uchr];
317
+ $nlen = \strlen($uchr);
318
+
319
+ if ($nlen == $ulen) {
320
+ $nlen = $i;
321
+ do {
322
+ $s[--$nlen] = $uchr[--$ulen];
323
+ } while ($ulen);
324
+ } else {
325
+ $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
326
+ $len += $nlen - $ulen;
327
+ $i += $nlen - $ulen;
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ if (null === $encoding) {
334
+ return $s;
335
+ }
336
+
337
+ return iconv('UTF-8', $encoding.'//IGNORE', $s);
338
+ }
339
+
340
+ public static function mb_internal_encoding($encoding = null)
341
+ {
342
+ if (null === $encoding) {
343
+ return self::$internalEncoding;
344
+ }
345
+
346
+ $encoding = self::getEncoding($encoding);
347
+
348
+ if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
349
+ self::$internalEncoding = $encoding;
350
+
351
+ return true;
352
+ }
353
+
354
+ return false;
355
+ }
356
+
357
+ public static function mb_language($lang = null)
358
+ {
359
+ if (null === $lang) {
360
+ return self::$language;
361
+ }
362
+
363
+ switch ($lang = strtolower($lang)) {
364
+ case 'uni':
365
+ case 'neutral':
366
+ self::$language = $lang;
367
+
368
+ return true;
369
+ }
370
+
371
+ return false;
372
+ }
373
+
374
+ public static function mb_list_encodings()
375
+ {
376
+ return array('UTF-8');
377
+ }
378
+
379
+ public static function mb_encoding_aliases($encoding)
380
+ {
381
+ switch (strtoupper($encoding)) {
382
+ case 'UTF8':
383
+ case 'UTF-8':
384
+ return array('utf8');
385
+ }
386
+
387
+ return false;
388
+ }
389
+
390
+ public static function mb_check_encoding($var = null, $encoding = null)
391
+ {
392
+ if (null === $encoding) {
393
+ if (null === $var) {
394
+ return false;
395
+ }
396
+ $encoding = self::$internalEncoding;
397
+ }
398
+
399
+ return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
400
+ }
401
+
402
+ public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
403
+ {
404
+ if (null === $encodingList) {
405
+ $encodingList = self::$encodingList;
406
+ } else {
407
+ if (!\is_array($encodingList)) {
408
+ $encodingList = array_map('trim', explode(',', $encodingList));
409
+ }
410
+ $encodingList = array_map('strtoupper', $encodingList);
411
+ }
412
+
413
+ foreach ($encodingList as $enc) {
414
+ switch ($enc) {
415
+ case 'ASCII':
416
+ if (!preg_match('/[\x80-\xFF]/', $str)) {
417
+ return $enc;
418
+ }
419
+ break;
420
+
421
+ case 'UTF8':
422
+ case 'UTF-8':
423
+ if (preg_match('//u', $str)) {
424
+ return 'UTF-8';
425
+ }
426
+ break;
427
+
428
+ default:
429
+ if (0 === strncmp($enc, 'ISO-8859-', 9)) {
430
+ return $enc;
431
+ }
432
+ }
433
+ }
434
+
435
+ return false;
436
+ }
437
+
438
+ public static function mb_detect_order($encodingList = null)
439
+ {
440
+ if (null === $encodingList) {
441
+ return self::$encodingList;
442
+ }
443
+
444
+ if (!\is_array($encodingList)) {
445
+ $encodingList = array_map('trim', explode(',', $encodingList));
446
+ }
447
+ $encodingList = array_map('strtoupper', $encodingList);
448
+
449
+ foreach ($encodingList as $enc) {
450
+ switch ($enc) {
451
+ default:
452
+ if (strncmp($enc, 'ISO-8859-', 9)) {
453
+ return false;
454
+ }
455
+ case 'ASCII':
456
+ case 'UTF8':
457
+ case 'UTF-8':
458
+ }
459
+ }
460
+
461
+ self::$encodingList = $encodingList;
462
+
463
+ return true;
464
+ }
465
+
466
+ public static function mb_strlen($s, $encoding = null)
467
+ {
468
+ $encoding = self::getEncoding($encoding);
469
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
470
+ return \strlen($s);
471
+ }
472
+
473
+ return @iconv_strlen($s, $encoding);
474
+ }
475
+
476
+ public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
477
+ {
478
+ $encoding = self::getEncoding($encoding);
479
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
480
+ return strpos($haystack, $needle, $offset);
481
+ }
482
+
483
+ $needle = (string) $needle;
484
+ if ('' === $needle) {
485
+ trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
486
+
487
+ return false;
488
+ }
489
+
490
+ return iconv_strpos($haystack, $needle, $offset, $encoding);
491
+ }
492
+
493
+ public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
494
+ {
495
+ $encoding = self::getEncoding($encoding);
496
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
497
+ return strrpos($haystack, $needle, $offset);
498
+ }
499
+
500
+ if ($offset != (int) $offset) {
501
+ $offset = 0;
502
+ } elseif ($offset = (int) $offset) {
503
+ if ($offset < 0) {
504
+ $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
505
+ $offset = 0;
506
+ } else {
507
+ $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
508
+ }
509
+ }
510
+
511
+ $pos = iconv_strrpos($haystack, $needle, $encoding);
512
+
513
+ return false !== $pos ? $offset + $pos : false;
514
+ }
515
+
516
+ public static function mb_strtolower($s, $encoding = null)
517
+ {
518
+ return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
519
+ }
520
+
521
+ public static function mb_strtoupper($s, $encoding = null)
522
+ {
523
+ return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
524
+ }
525
+
526
+ public static function mb_substitute_character($c = null)
527
+ {
528
+ if (0 === strcasecmp($c, 'none')) {
529
+ return true;
530
+ }
531
+
532
+ return null !== $c ? false : 'none';
533
+ }
534
+
535
+ public static function mb_substr($s, $start, $length = null, $encoding = null)
536
+ {
537
+ $encoding = self::getEncoding($encoding);
538
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
539
+ return substr($s, $start, null === $length ? 2147483647 : $length);
540
+ }
541
+
542
+ if ($start < 0) {
543
+ $start = iconv_strlen($s, $encoding) + $start;
544
+ if ($start < 0) {
545
+ $start = 0;
546
+ }
547
+ }
548
+
549
+ if (null === $length) {
550
+ $length = 2147483647;
551
+ } elseif ($length < 0) {
552
+ $length = iconv_strlen($s, $encoding) + $length - $start;
553
+ if ($length < 0) {
554
+ return '';
555
+ }
556
+ }
557
+
558
+ return (string) iconv_substr($s, $start, $length, $encoding);
559
+ }
560
+
561
+ public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
562
+ {
563
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
564
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
565
+
566
+ return self::mb_strpos($haystack, $needle, $offset, $encoding);
567
+ }
568
+
569
+ public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
570
+ {
571
+ $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
572
+
573
+ return self::getSubpart($pos, $part, $haystack, $encoding);
574
+ }
575
+
576
+ public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
577
+ {
578
+ $encoding = self::getEncoding($encoding);
579
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
580
+ return strrchr($haystack, $needle, $part);
581
+ }
582
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
583
+ $pos = iconv_strrpos($haystack, $needle, $encoding);
584
+
585
+ return self::getSubpart($pos, $part, $haystack, $encoding);
586
+ }
587
+
588
+ public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
589
+ {
590
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
591
+ $pos = self::mb_strripos($haystack, $needle, $encoding);
592
+
593
+ return self::getSubpart($pos, $part, $haystack, $encoding);
594
+ }
595
+
596
+ public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
597
+ {
598
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
599
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
600
+
601
+ return self::mb_strrpos($haystack, $needle, $offset, $encoding);
602
+ }
603
+
604
+ public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
605
+ {
606
+ $pos = strpos($haystack, $needle);
607
+ if (false === $pos) {
608
+ return false;
609
+ }
610
+ if ($part) {
611
+ return substr($haystack, 0, $pos);
612
+ }
613
+
614
+ return substr($haystack, $pos);
615
+ }
616
+
617
+ public static function mb_get_info($type = 'all')
618
+ {
619
+ $info = array(
620
+ 'internal_encoding' => self::$internalEncoding,
621
+ 'http_output' => 'pass',
622
+ 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
623
+ 'func_overload' => 0,
624
+ 'func_overload_list' => 'no overload',
625
+ 'mail_charset' => 'UTF-8',
626
+ 'mail_header_encoding' => 'BASE64',
627
+ 'mail_body_encoding' => 'BASE64',
628
+ 'illegal_chars' => 0,
629
+ 'encoding_translation' => 'Off',
630
+ 'language' => self::$language,
631
+ 'detect_order' => self::$encodingList,
632
+ 'substitute_character' => 'none',
633
+ 'strict_detection' => 'Off',
634
+ );
635
+
636
+ if ('all' === $type) {
637
+ return $info;
638
+ }
639
+ if (isset($info[$type])) {
640
+ return $info[$type];
641
+ }
642
+
643
+ return false;
644
+ }
645
+
646
+ public static function mb_http_input($type = '')
647
+ {
648
+ return false;
649
+ }
650
+
651
+ public static function mb_http_output($encoding = null)
652
+ {
653
+ return null !== $encoding ? 'pass' === $encoding : 'pass';
654
+ }
655
+
656
+ public static function mb_strwidth($s, $encoding = null)
657
+ {
658
+ $encoding = self::getEncoding($encoding);
659
+
660
+ if ('UTF-8' !== $encoding) {
661
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
662
+ }
663
+
664
+ $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
665
+
666
+ return ($wide << 1) + iconv_strlen($s, 'UTF-8');
667
+ }
668
+
669
+ public static function mb_substr_count($haystack, $needle, $encoding = null)
670
+ {
671
+ return substr_count($haystack, $needle);
672
+ }
673
+
674
+ public static function mb_output_handler($contents, $status)
675
+ {
676
+ return $contents;
677
+ }
678
+
679
+ public static function mb_chr($code, $encoding = null)
680
+ {
681
+ if (0x80 > $code %= 0x200000) {
682
+ $s = \chr($code);
683
+ } elseif (0x800 > $code) {
684
+ $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
685
+ } elseif (0x10000 > $code) {
686
+ $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
687
+ } else {
688
+ $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
689
+ }
690
+
691
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
692
+ $s = mb_convert_encoding($s, $encoding, 'UTF-8');
693
+ }
694
+
695
+ return $s;
696
+ }
697
+
698
+ public static function mb_ord($s, $encoding = null)
699
+ {
700
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
701
+ $s = mb_convert_encoding($s, 'UTF-8', $encoding);
702
+ }
703
+
704
+ $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
705
+ if (0xF0 <= $code) {
706
+ return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
707
+ }
708
+ if (0xE0 <= $code) {
709
+ return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
710
+ }
711
+ if (0xC0 <= $code) {
712
+ return (($code - 0xC0) << 6) + $s[2] - 0x80;
713
+ }
714
+
715
+ return $code;
716
+ }
717
+
718
+ private static function getSubpart($pos, $part, $haystack, $encoding)
719
+ {
720
+ if (false === $pos) {
721
+ return false;
722
+ }
723
+ if ($part) {
724
+ return self::mb_substr($haystack, 0, $pos, $encoding);
725
+ }
726
+
727
+ return self::mb_substr($haystack, $pos, null, $encoding);
728
+ }
729
+
730
+ private static function html_encoding_callback(array $m)
731
+ {
732
+ $i = 1;
733
+ $entities = '';
734
+ $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
735
+
736
+ while (isset($m[$i])) {
737
+ if (0x80 > $m[$i]) {
738
+ $entities .= \chr($m[$i++]);
739
+ continue;
740
+ }
741
+ if (0xF0 <= $m[$i]) {
742
+ $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
743
+ } elseif (0xE0 <= $m[$i]) {
744
+ $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
745
+ } else {
746
+ $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
747
+ }
748
+
749
+ $entities .= '&#'.$c.';';
750
+ }
751
+
752
+ return $entities;
753
+ }
754
+
755
+ private static function title_case_lower(array $s)
756
+ {
757
+ return self::mb_convert_case($s[0], MB_CASE_LOWER, 'UTF-8');
758
+ }
759
+
760
+ private static function title_case_upper(array $s)
761
+ {
762
+ return self::mb_convert_case($s[0], MB_CASE_UPPER, 'UTF-8');
763
+ }
764
+
765
+ private static function getData($file)
766
+ {
767
+ if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
768
+ return require $file;
769
+ }
770
+
771
+ return false;
772
+ }
773
+
774
+ private static function getEncoding($encoding)
775
+ {
776
+ if (null === $encoding) {
777
+ return self::$internalEncoding;
778
+ }
779
+
780
+ $encoding = strtoupper($encoding);
781
+
782
+ if ('8BIT' === $encoding || 'BINARY' === $encoding) {
783
+ return 'CP850';
784
+ }
785
+ if ('UTF8' === $encoding) {
786
+ return 'UTF-8';
787
+ }
788
+
789
+ return $encoding;
790
+ }
791
+ }
app/vendor/symfony/polyfill-mbstring/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Symfony Polyfill / Mbstring
2
+ ===========================
3
+
4
+ This component provides a partial, native PHP implementation for the
5
+ [Mbstring](http://php.net/mbstring) extension.
6
+
7
+ More information can be found in the
8
+ [main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
9
+
10
+ License
11
+ =======
12
+
13
+ This library is released under the [MIT license](LICENSE).
app/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php ADDED
@@ -0,0 +1,1101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ static $data = array (
4
+ 'A' => 'a',
5
+ 'B' => 'b',
6
+ 'C' => 'c',
7
+ 'D' => 'd',
8
+ 'E' => 'e',
9
+ 'F' => 'f',
10
+ 'G' => 'g',
11
+ 'H' => 'h',
12
+ 'I' => 'i',
13
+ 'J' => 'j',
14
+ 'K' => 'k',
15
+ 'L' => 'l',
16
+ 'M' => 'm',
17
+ 'N' => 'n',
18
+ 'O' => 'o',
19
+ 'P' => 'p',
20
+ 'Q' => 'q',
21
+ 'R' => 'r',
22
+ 'S' => 's',
23
+ 'T' => 't',
24
+ 'U' => 'u',
25
+ 'V' => 'v',
26
+ 'W' => 'w',
27
+ 'X' => 'x',
28
+ 'Y' => 'y',
29
+ 'Z' => 'z',
30
+ 'À' => 'à',
31
+ 'Á' => 'á',
32
+ 'Â' => 'â',
33
+ 'Ã' => 'ã',
34
+ 'Ä' => 'ä',
35
+ 'Å' => 'å',
36
+ 'Æ' => 'æ',
37
+ 'Ç' => 'ç',
38
+ 'È' => 'è',
39
+ 'É' => 'é',
40
+ 'Ê' => 'ê',
41
+ 'Ë' => 'ë',
42
+ 'Ì' => 'ì',
43
+ 'Í' => 'í',
44
+ 'Î' => 'î',
45
+ 'Ï' => 'ï',
46
+ 'Ð' => 'ð',
47
+ 'Ñ' => 'ñ',
48
+ 'Ò' => 'ò',
49
+ 'Ó' => 'ó',
50
+ 'Ô' => 'ô',
51
+ 'Õ' => 'õ',
52
+ 'Ö' => 'ö',
53
+ 'Ø' => 'ø',
54
+ 'Ù' => 'ù',
55
+ 'Ú' => 'ú',
56
+ 'Û' => 'û',
57
+ 'Ü' => 'ü',
58
+ 'Ý' => 'ý',
59
+ 'Þ' => 'þ',
60
+ 'Ā' => 'ā',
61
+ 'Ă' => 'ă',
62
+ 'Ą' => 'ą',
63
+ 'Ć' => 'ć',
64
+ 'Ĉ' => 'ĉ',
65
+ 'Ċ' => 'ċ',
66
+ 'Č' => 'č',
67
+ 'Ď' => 'ď',
68
+ 'Đ' => 'đ',
69
+ 'Ē' => 'ē',
70
+ 'Ĕ' => 'ĕ',
71
+ 'Ė' => 'ė',
72
+ 'Ę' => 'ę',
73
+ 'Ě' => 'ě',
74
+ 'Ĝ' => 'ĝ',
75
+ 'Ğ' => 'ğ',
76
+ 'Ġ' => 'ġ',
77
+ 'Ģ' => 'ģ',
78
+ 'Ĥ' => 'ĥ',
79
+ 'Ħ' => 'ħ',
80
+ 'Ĩ' => 'ĩ',
81
+ 'Ī' => 'ī',
82
+ 'Ĭ' => 'ĭ',
83
+ 'Į' => 'į',
84
+ 'İ' => 'i',
85
+ 'IJ' => 'ij',
86
+ 'Ĵ' => 'ĵ',
87
+ 'Ķ' => 'ķ',
88
+ 'Ĺ' => 'ĺ',
89
+ 'Ļ' => 'ļ',
90
+ 'Ľ' => 'ľ',
91
+ 'Ŀ' => 'ŀ',
92
+ 'Ł' => 'ł',
93
+ 'Ń' => 'ń',
94
+ 'Ņ' => 'ņ',
95
+ 'Ň' => 'ň',
96
+ 'Ŋ' => 'ŋ',
97
+ 'Ō' => 'ō',
98
+ 'Ŏ' => 'ŏ',
99
+ 'Ő' => 'ő',
100
+ 'Œ' => 'œ',
101
+ 'Ŕ' => 'ŕ',
102
+ 'Ŗ' => 'ŗ',
103
+ 'Ř' => 'ř',
104
+ 'Ś' => 'ś',
105
+ 'Ŝ' => 'ŝ',
106
+ 'Ş' => 'ş',
107
+ 'Š' => 'š',
108
+ 'Ţ' => 'ţ',
109
+ 'Ť' => 'ť',
110
+ 'Ŧ' => 'ŧ',
111
+ 'Ũ' => 'ũ',
112
+ 'Ū' => 'ū',
113
+ 'Ŭ' => 'ŭ',
114
+ 'Ů' => 'ů',
115
+ 'Ű' => 'ű',
116
+ 'Ų' => 'ų',
117
+ 'Ŵ' => 'ŵ',
118
+ 'Ŷ' => 'ŷ',
119
+ 'Ÿ' => 'ÿ',
120
+ 'Ź' => 'ź',
121
+ 'Ż' => 'ż',
122
+ 'Ž' => 'ž',
123
+ 'Ɓ' => 'ɓ',
124
+ 'Ƃ' => 'ƃ',
125
+ 'Ƅ' => 'ƅ',
126
+ 'Ɔ' => 'ɔ',
127
+ 'Ƈ' => 'ƈ',
128
+ 'Ɖ' => 'ɖ',
129
+ 'Ɗ' => 'ɗ',
130
+ 'Ƌ' => 'ƌ',
131
+ 'Ǝ' => 'ǝ',
132
+ 'Ə' => 'ə',
133
+ 'Ɛ' => 'ɛ',
134
+ 'Ƒ' => 'ƒ',
135
+ 'Ɠ' => 'ɠ',
136
+ 'Ɣ' => 'ɣ',
137
+ 'Ɩ' => 'ɩ',
138
+ 'Ɨ' => 'ɨ',
139
+ 'Ƙ' => 'ƙ',
140
+ 'Ɯ' => 'ɯ',
141
+ 'Ɲ' => 'ɲ',
142
+ 'Ɵ' => 'ɵ',
143
+ 'Ơ' => 'ơ',
144
+ 'Ƣ' => 'ƣ',
145
+ 'Ƥ' => 'ƥ',
146
+ 'Ʀ' => 'ʀ',
147
+ 'Ƨ' => 'ƨ',
148
+ 'Ʃ' => 'ʃ',
149
+ 'Ƭ' => 'ƭ',
150
+ 'Ʈ' => 'ʈ',
151
+ 'Ư' => 'ư',
152
+ 'Ʊ' => 'ʊ',
153
+ 'Ʋ' => 'ʋ',
154
+ 'Ƴ' => 'ƴ',
155
+ 'Ƶ' => 'ƶ',
156
+ 'Ʒ' => 'ʒ',
157
+ 'Ƹ' => 'ƹ',
158
+ 'Ƽ' => 'ƽ',
159
+ 'DŽ' => 'dž',
160
+ 'Dž' => 'dž',
161
+ 'LJ' => 'lj',
162
+ 'Lj' => 'lj',
163
+ 'NJ' => 'nj',
164
+ 'Nj' => 'nj',
165
+ 'Ǎ' => 'ǎ',
166
+ 'Ǐ' => 'ǐ',
167
+ 'Ǒ' => 'ǒ',
168
+ 'Ǔ' => 'ǔ',
169
+ 'Ǖ' => 'ǖ',
170
+ 'Ǘ' => 'ǘ',
171
+ 'Ǚ' => 'ǚ',
172
+ 'Ǜ' => 'ǜ',
173
+ 'Ǟ' => 'ǟ',
174
+ 'Ǡ' => 'ǡ',
175
+ 'Ǣ' => 'ǣ',
176
+ 'Ǥ' => 'ǥ',
177
+ 'Ǧ' => 'ǧ',
178
+ 'Ǩ' => 'ǩ',
179
+ 'Ǫ' => 'ǫ',
180
+ 'Ǭ' => 'ǭ',
181
+ 'Ǯ' => 'ǯ',
182
+ 'DZ' => 'dz',
183
+ 'Dz' => 'dz',
184
+ 'Ǵ' => 'ǵ',
185
+ 'Ƕ' => 'ƕ',
186
+ 'Ƿ' => 'ƿ',
187
+ 'Ǹ' => 'ǹ',
188
+ 'Ǻ' => 'ǻ',
189
+ 'Ǽ' => 'ǽ',
190
+ 'Ǿ' => 'ǿ',
191
+ 'Ȁ' => 'ȁ',
192
+ 'Ȃ' => 'ȃ',
193
+ 'Ȅ' => 'ȅ',
194
+ 'Ȇ' => 'ȇ',
195
+ 'Ȉ' => 'ȉ',
196
+ 'Ȋ' => 'ȋ',
197
+ 'Ȍ' => 'ȍ',
198
+ 'Ȏ' => 'ȏ',
199
+ 'Ȑ' => 'ȑ',
200
+ 'Ȓ' => 'ȓ',
201
+ 'Ȕ' => 'ȕ',
202
+ 'Ȗ' => 'ȗ',
203
+ 'Ș' => 'ș',
204
+ 'Ț' => 'ț',
205
+ 'Ȝ' => 'ȝ',
206
+ 'Ȟ' => 'ȟ',
207
+ 'Ƞ' => 'ƞ',
208
+ 'Ȣ' => 'ȣ',
209
+ 'Ȥ' => 'ȥ',
210
+ 'Ȧ' => 'ȧ',
211
+ 'Ȩ' => 'ȩ',
212
+ 'Ȫ' => 'ȫ',
213
+ 'Ȭ' => 'ȭ',
214
+ 'Ȯ' => 'ȯ',
215
+ 'Ȱ' => 'ȱ',
216
+ 'Ȳ' => 'ȳ',
217
+ 'Ⱥ' => 'ⱥ',
218
+ 'Ȼ' => 'ȼ',
219
+ 'Ƚ' => 'ƚ',
220
+ 'Ⱦ' => 'ⱦ',
221
+ 'Ɂ' => 'ɂ',
222
+ 'Ƀ' => 'ƀ',
223
+ 'Ʉ' => 'ʉ',
224
+ 'Ʌ' => 'ʌ',
225
+ 'Ɇ' => 'ɇ',
226
+ 'Ɉ' => 'ɉ',
227
+ 'Ɋ' => 'ɋ',
228
+ 'Ɍ' => 'ɍ',
229
+ 'Ɏ' => 'ɏ',
230
+ 'Ͱ' => 'ͱ',
231
+ 'Ͳ' => 'ͳ',
232
+ 'Ͷ' => 'ͷ',
233
+ 'Ϳ' => 'ϳ',
234
+ 'Ά' => 'ά',
235
+ 'Έ' => 'έ',
236
+ 'Ή' => 'ή',
237
+ 'Ί' => 'ί',
238
+ 'Ό' => 'ό',
239
+ 'Ύ' => 'ύ',
240
+ 'Ώ' => 'ώ',
241
+ 'Α' => 'α',
242
+ 'Β' => 'β',
243
+ 'Γ' => 'γ',
244
+ 'Δ' => 'δ',
245
+ 'Ε' => 'ε',
246
+ 'Ζ' => 'ζ',
247
+ 'Η' => 'η',
248
+ 'Θ' => 'θ',
249
+ 'Ι' => 'ι',
250
+ 'Κ' => 'κ',
251
+ 'Λ' => 'λ',
252
+ 'Μ' => 'μ',
253
+ 'Ν' => 'ν',
254
+ 'Ξ' => 'ξ',
255
+ 'Ο' => 'ο',
256
+ 'Π' => 'π',
257
+ 'Ρ' => 'ρ',
258
+ 'Σ' => 'σ',
259
+ 'Τ' => 'τ',
260
+ 'Υ' => 'υ',
261
+ 'Φ' => 'φ',
262
+ 'Χ' => 'χ',
263
+ 'Ψ' => 'ψ',
264
+ 'Ω' => 'ω',
265
+ 'Ϊ' => 'ϊ',
266
+ 'Ϋ' => 'ϋ',
267
+ 'Ϗ' => 'ϗ',
268
+ 'Ϙ' => 'ϙ',
269
+ 'Ϛ' => 'ϛ',
270
+ 'Ϝ' => 'ϝ',
271
+ 'Ϟ' => 'ϟ',
272
+ 'Ϡ' => 'ϡ',
273
+ 'Ϣ' => 'ϣ',
274
+ 'Ϥ' => 'ϥ',
275
+ 'Ϧ' => 'ϧ',
276
+ 'Ϩ' => 'ϩ',
277
+ 'Ϫ' => 'ϫ',
278
+ 'Ϭ' => 'ϭ',
279
+ 'Ϯ' => 'ϯ',
280
+ 'ϴ' => 'θ',
281
+ 'Ϸ' => 'ϸ',
282
+ 'Ϲ' => 'ϲ',
283
+ 'Ϻ' => 'ϻ',
284
+ 'Ͻ' => 'ͻ',
285
+ 'Ͼ' => 'ͼ',
286
+ 'Ͽ' => 'ͽ',
287
+ 'Ѐ' => 'ѐ',
288
+ 'Ё' => 'ё',
289
+ 'Ђ' => 'ђ',
290
+ 'Ѓ' => 'ѓ',
291
+ 'Є' => 'є',
292
+ 'Ѕ' => 'ѕ',
293
+ 'І' => 'і',
294
+ 'Ї' => 'ї',
295
+ 'Ј' => 'ј',
296
+ 'Љ' => 'љ',
297
+ 'Њ' => 'њ',
298
+ 'Ћ' => 'ћ',
299
+ 'Ќ' => 'ќ',
300
+ 'Ѝ' => 'ѝ',
301
+ 'Ў' => 'ў',
302
+ 'Џ' => 'џ',
303
+ 'А' => 'а',
304
+ 'Б' => 'б',
305
+ 'В' => 'в',
306
+ 'Г' => 'г',
307
+ 'Д' => 'д',
308
+ 'Е' => 'е',
309
+ 'Ж' => 'ж',
310
+ 'З' => 'з',
311
+ 'И' => 'и',
312
+ 'Й' => 'й',
313
+ 'К' => 'к',
314
+ 'Л' => 'л',
315
+ 'М' => 'м',
316
+ 'Н' => 'н',
317
+ 'О' => 'о',
318
+ 'П' => 'п',
319
+ 'Р' => 'р',
320
+ 'С' => 'с',
321
+ 'Т' => 'т',
322
+ 'У' => 'у',
323
+ 'Ф' => 'ф',
324
+ 'Х' => 'х',
325
+ 'Ц' => 'ц',
326
+ 'Ч' => 'ч',
327
+ 'Ш' => 'ш',
328
+ 'Щ' => 'щ',
329
+ 'Ъ' => 'ъ',
330
+ 'Ы' => 'ы',
331
+ 'Ь' => 'ь',
332
+ 'Э' => 'э',
333
+ 'Ю' => 'ю',
334
+ 'Я' => 'я',
335
+ 'Ѡ' => 'ѡ',
336
+ 'Ѣ' => 'ѣ',
337
+ 'Ѥ' => 'ѥ',
338
+ 'Ѧ' => 'ѧ',
339
+ 'Ѩ' => 'ѩ',
340
+ 'Ѫ' => 'ѫ',
341
+ 'Ѭ' => 'ѭ',
342
+ 'Ѯ' => 'ѯ',
343
+ 'Ѱ' => 'ѱ',
344
+ 'Ѳ' => 'ѳ',
345
+ 'Ѵ' => 'ѵ',
346
+ 'Ѷ' => 'ѷ',
347
+ 'Ѹ' => 'ѹ',
348
+ 'Ѻ' => 'ѻ',
349
+ 'Ѽ' => 'ѽ',
350
+ 'Ѿ' => 'ѿ',
351
+ 'Ҁ' => 'ҁ',
352
+ 'Ҋ' => 'ҋ',
353
+ 'Ҍ' => 'ҍ',
354
+ 'Ҏ' => 'ҏ',
355
+ 'Ґ' => 'ґ',
356
+ 'Ғ' => 'ғ',
357
+ 'Ҕ' => 'ҕ',
358
+ 'Җ' => 'җ',
359
+ 'Ҙ' => 'ҙ',
360
+ 'Қ' => 'қ',
361
+ 'Ҝ' => 'ҝ',
362
+ 'Ҟ' => 'ҟ',
363
+ 'Ҡ' => 'ҡ',
364
+ 'Ң' => 'ң',
365
+ 'Ҥ' => 'ҥ',
366
+ 'Ҧ' => 'ҧ',
367
+ 'Ҩ' => 'ҩ',
368
+ 'Ҫ' => 'ҫ',
369
+ 'Ҭ' => 'ҭ',
370
+ 'Ү' => 'ү',
371
+ 'Ұ' => 'ұ',
372
+ 'Ҳ' => 'ҳ',
373
+ 'Ҵ' => 'ҵ',
374
+ 'Ҷ' => 'ҷ',
375
+ 'Ҹ' => 'ҹ',
376
+ 'Һ' => 'һ',
377
+ 'Ҽ' => 'ҽ',
378
+ 'Ҿ' => 'ҿ',
379
+ 'Ӏ' => 'ӏ',
380
+ 'Ӂ' => 'ӂ',
381
+ 'Ӄ' => 'ӄ',
382
+ 'Ӆ' => 'ӆ',
383
+ 'Ӈ' => 'ӈ',
384
+ 'Ӊ' => 'ӊ',
385
+ 'Ӌ' => 'ӌ',
386
+ 'Ӎ' => 'ӎ',
387
+ 'Ӑ' => 'ӑ',
388
+ 'Ӓ' => 'ӓ',
389
+ 'Ӕ' => 'ӕ',
390
+ 'Ӗ' => 'ӗ',
391
+ 'Ә' => 'ә',
392
+ 'Ӛ' => 'ӛ',
393
+ 'Ӝ' => 'ӝ',
394
+ 'Ӟ' => 'ӟ',
395
+ 'Ӡ' => 'ӡ',
396
+ 'Ӣ' => 'ӣ',
397
+ 'Ӥ' => 'ӥ',
398
+ 'Ӧ' => 'ӧ',
399
+ 'Ө' => 'ө',
400
+ 'Ӫ' => 'ӫ',
401
+ 'Ӭ' => 'ӭ',
402
+ 'Ӯ' => 'ӯ',
403
+ 'Ӱ' => 'ӱ',
404
+ 'Ӳ' => 'ӳ',
405
+ 'Ӵ' => 'ӵ',
406
+ 'Ӷ' => 'ӷ',
407
+ 'Ӹ' => 'ӹ',
408
+ 'Ӻ' => 'ӻ',
409
+ 'Ӽ' => 'ӽ',
410
+ 'Ӿ' => 'ӿ',
411
+ 'Ԁ' => 'ԁ',
412
+ 'Ԃ' => 'ԃ',
413
+ 'Ԅ' => 'ԅ',
414
+ 'Ԇ' => 'ԇ',
415
+ 'Ԉ' => 'ԉ',
416
+ 'Ԋ' => 'ԋ',
417
+ 'Ԍ' => 'ԍ',
418
+ 'Ԏ' => 'ԏ',
419
+ 'Ԑ' => 'ԑ',
420
+ 'Ԓ' => 'ԓ',
421
+ 'Ԕ' => 'ԕ',
422
+ 'Ԗ' => 'ԗ',
423
+ 'Ԙ' => 'ԙ',
424
+ 'Ԛ' => 'ԛ',
425
+ 'Ԝ' => 'ԝ',
426
+ 'Ԟ' => 'ԟ',
427
+ 'Ԡ' => 'ԡ',
428
+ 'Ԣ' => 'ԣ',
429
+ 'Ԥ' => 'ԥ',
430
+ 'Ԧ' => 'ԧ',
431
+ 'Ԩ' => 'ԩ',
432
+ 'Ԫ' => 'ԫ',
433
+ 'Ԭ' => 'ԭ',
434
+ 'Ԯ' => 'ԯ',
435
+ 'Ա' => 'ա',
436
+ 'Բ' => 'բ',
437
+ 'Գ' => 'գ',
438
+ 'Դ' => 'դ',
439
+ 'Ե' => 'ե',
440
+ 'Զ' => 'զ',
441
+ 'Է' => 'է',
442
+ 'Ը' => 'ը',
443
+ 'Թ' => 'թ',
444
+ 'Ժ' => 'ժ',
445
+ 'Ի' => 'ի',
446
+ 'Լ' => 'լ',
447
+ 'Խ' => 'խ',
448
+ 'Ծ' => 'ծ',
449
+ 'Կ' => 'կ',
450
+ 'Հ' => 'հ',
451
+ 'Ձ' => 'ձ',
452
+ 'Ղ' => 'ղ',
453
+ 'Ճ' => 'ճ',
454
+ 'Մ' => 'մ',
455
+ 'Յ' => 'յ',
456
+ 'Ն' => 'ն',
457
+ 'Շ' => 'շ',
458
+ 'Ո' => 'ո',
459
+ 'Չ' => 'չ',
460
+ 'Պ' => 'պ',
461
+ 'Ջ' => 'ջ',
462
+ 'Ռ' => 'ռ',
463
+ 'Ս' => 'ս',
464
+ 'Վ' => 'վ',
465
+ 'Տ' => 'տ',
466
+ 'Ր' => 'ր',
467
+ 'Ց' => 'ց',
468
+ 'Ւ' => 'ւ',
469
+ 'Փ' => 'փ',
470
+ 'Ք' => 'ք',
471
+ 'Օ' => 'օ',
472
+ 'Ֆ' => 'ֆ',
473
+ 'Ⴀ' => 'ⴀ',
474
+ 'Ⴁ' => 'ⴁ',
475
+ 'Ⴂ' => 'ⴂ',
476
+ 'Ⴃ' => 'ⴃ',
477
+ 'Ⴄ' => 'ⴄ',
478
+ 'Ⴅ' => 'ⴅ',
479
+ 'Ⴆ' => 'ⴆ',
480
+ 'Ⴇ' => 'ⴇ',
481
+ 'Ⴈ' => 'ⴈ',
482
+ 'Ⴉ' => 'ⴉ',
483
+ 'Ⴊ' => 'ⴊ',
484
+ 'Ⴋ' => 'ⴋ',
485
+ 'Ⴌ' => 'ⴌ',
486
+ 'Ⴍ' => 'ⴍ',
487
+ 'Ⴎ' => 'ⴎ',
488
+ 'Ⴏ' => 'ⴏ',
489
+ 'Ⴐ' => 'ⴐ',
490
+ 'Ⴑ' => 'ⴑ',
491
+ 'Ⴒ' => 'ⴒ',
492
+ 'Ⴓ' => 'ⴓ',
493
+ 'Ⴔ' => 'ⴔ',
494
+ 'Ⴕ' => 'ⴕ',
495
+ 'Ⴖ' => 'ⴖ',
496
+ 'Ⴗ' => 'ⴗ',
497
+ 'Ⴘ' => 'ⴘ',
498
+ 'Ⴙ' => 'ⴙ',
499
+ 'Ⴚ' => 'ⴚ',
500
+ 'Ⴛ' => 'ⴛ',
501
+ 'Ⴜ' => 'ⴜ',
502
+ 'Ⴝ' => 'ⴝ',
503
+ 'Ⴞ' => 'ⴞ',
504
+ 'Ⴟ' => 'ⴟ',
505
+ 'Ⴠ' => 'ⴠ',
506
+ 'Ⴡ' => 'ⴡ',
507
+ 'Ⴢ' => 'ⴢ',
508
+ 'Ⴣ' => 'ⴣ',
509
+ 'Ⴤ' => 'ⴤ',
510
+ 'Ⴥ' => 'ⴥ',
511
+ 'Ⴧ' => 'ⴧ',
512
+ 'Ⴭ' => 'ⴭ',
513
+ 'Ḁ' => 'ḁ',
514
+ 'Ḃ' => 'ḃ',
515
+ 'Ḅ' => 'ḅ',
516
+ 'Ḇ' => 'ḇ',
517
+ 'Ḉ' => 'ḉ',
518
+ 'Ḋ' => 'ḋ',
519
+ 'Ḍ' => 'ḍ',
520
+ 'Ḏ' => 'ḏ',
521
+ 'Ḑ' => 'ḑ',
522
+ 'Ḓ' => 'ḓ',
523
+ 'Ḕ' => 'ḕ',
524
+ 'Ḗ' => 'ḗ',
525
+ 'Ḙ' => 'ḙ',
526
+ 'Ḛ' => 'ḛ',
527
+ 'Ḝ' => 'ḝ',
528
+ 'Ḟ' => 'ḟ',
529
+ 'Ḡ' => 'ḡ',
530
+ 'Ḣ' => 'ḣ',
531
+ 'Ḥ' => 'ḥ',
532
+ 'Ḧ' => 'ḧ',
533
+ 'Ḩ' => 'ḩ',
534
+ 'Ḫ' => 'ḫ',
535
+ 'Ḭ' => 'ḭ',
536
+ 'Ḯ' => 'ḯ',
537
+ 'Ḱ' => 'ḱ',
538
+ 'Ḳ' => 'ḳ',
539
+ 'Ḵ' => 'ḵ',
540
+ 'Ḷ' => 'ḷ',
541
+ 'Ḹ' => 'ḹ',
542
+ 'Ḻ' => 'ḻ',
543
+ 'Ḽ' => 'ḽ',
544
+ 'Ḿ' => 'ḿ',
545
+ 'Ṁ' => 'ṁ',
546
+ 'Ṃ' => 'ṃ',
547
+ 'Ṅ' => 'ṅ',
548
+ 'Ṇ' => 'ṇ',
549
+ 'Ṉ' => 'ṉ',
550
+ 'Ṋ' => 'ṋ',
551
+ 'Ṍ' => 'ṍ',
552
+ 'Ṏ' => 'ṏ',
553
+ 'Ṑ' => 'ṑ',
554
+ 'Ṓ' => 'ṓ',
555
+ 'Ṕ' => 'ṕ',
556
+ 'Ṗ' => 'ṗ',
557
+ 'Ṙ' => 'ṙ',
558
+ 'Ṛ' => 'ṛ',
559
+ 'Ṝ' => 'ṝ',
560
+ 'Ṟ' => 'ṟ',
561
+ 'Ṡ' => 'ṡ',
562
+ 'Ṣ' => 'ṣ',
563
+ 'Ṥ' => 'ṥ',
564
+ 'Ṧ' => 'ṧ',
565
+ 'Ṩ' => 'ṩ',
566
+ 'Ṫ' => 'ṫ',
567
+ 'Ṭ' => 'ṭ',
568
+ 'Ṯ' => 'ṯ',
569
+ 'Ṱ' => 'ṱ',
570
+ 'Ṳ' => 'ṳ',
571
+ 'Ṵ' => 'ṵ',
572
+ 'Ṷ' => 'ṷ',
573
+ 'Ṹ' => 'ṹ',
574
+ 'Ṻ' => 'ṻ',
575
+ 'Ṽ' => 'ṽ',
576
+ 'Ṿ' => 'ṿ',
577
+ 'Ẁ' => 'ẁ',
578
+ 'Ẃ' => 'ẃ',
579
+ 'Ẅ' => 'ẅ',
580
+ 'Ẇ' => 'ẇ',
581
+ 'Ẉ' => 'ẉ',
582
+ 'Ẋ' => 'ẋ',
583
+ 'Ẍ' => 'ẍ',
584
+ 'Ẏ' => 'ẏ',
585
+ 'Ẑ' => 'ẑ',
586
+ 'Ẓ' => 'ẓ',
587
+ 'Ẕ' => 'ẕ',
588
+ 'ẞ' => 'ß',
589
+ 'Ạ' => 'ạ',
590
+ 'Ả' => 'ả',
591
+ 'Ấ' => 'ấ',
592
+ 'Ầ' => 'ầ',
593
+ 'Ẩ' => 'ẩ',
594
+ 'Ẫ' => 'ẫ',
595
+ 'Ậ' => 'ậ',
596
+ 'Ắ' => 'ắ',
597
+ 'Ằ' => 'ằ',
598
+ 'Ẳ' => 'ẳ',
599
+ 'Ẵ' => 'ẵ',
600
+ 'Ặ' => 'ặ',
601
+ 'Ẹ' => 'ẹ',
602
+ 'Ẻ' => 'ẻ',
603
+ 'Ẽ' => 'ẽ',
604
+ 'Ế' => 'ế',
605
+ 'Ề' => 'ề',
606
+ 'Ể' => 'ể',
607
+ 'Ễ' => 'ễ',
608
+ 'Ệ' => 'ệ',
609
+ 'Ỉ' => 'ỉ',
610
+ 'Ị' => 'ị',
611
+ 'Ọ' => 'ọ',
612
+ 'Ỏ' => 'ỏ',
613
+ 'Ố' => 'ố',
614
+ 'Ồ' => 'ồ',
615
+ 'Ổ' => 'ổ',
616
+ 'Ỗ' => 'ỗ',
617
+ 'Ộ' => 'ộ',
618
+ 'Ớ' => 'ớ',
619
+ 'Ờ' => 'ờ',
620
+ 'Ở' => 'ở',
621
+ 'Ỡ' => 'ỡ',
622
+ 'Ợ' => 'ợ',
623
+ 'Ụ' => 'ụ',
624
+ 'Ủ' => 'ủ',
625
+ 'Ứ' => 'ứ',
626
+ 'Ừ' => 'ừ',
627
+ 'Ử' => 'ử',
628
+ 'Ữ' => 'ữ',
629
+ 'Ự' => 'ự',
630
+ 'Ỳ' => 'ỳ',
631
+ 'Ỵ' => 'ỵ',
632
+ 'Ỷ' => 'ỷ',
633
+ 'Ỹ' => 'ỹ',
634
+ 'Ỻ' => 'ỻ',
635
+ 'Ỽ' => 'ỽ',
636
+ 'Ỿ' => 'ỿ',
637
+ 'Ἀ' => 'ἀ',
638
+ 'Ἁ' => 'ἁ',
639
+ 'Ἂ' => 'ἂ',
640
+ 'Ἃ' => 'ἃ',
641
+ 'Ἄ' => 'ἄ',
642
+ 'Ἅ' => 'ἅ',
643
+ 'Ἆ' => 'ἆ',
644
+ 'Ἇ' => 'ἇ',
645
+ 'Ἐ' => 'ἐ',
646
+ 'Ἑ' => 'ἑ',
647
+ 'Ἒ' => 'ἒ',
648
+ 'Ἓ' => 'ἓ',
649
+ 'Ἔ' => 'ἔ',
650
+ 'Ἕ' => 'ἕ',
651
+ 'Ἠ' => 'ἠ',
652
+ 'Ἡ' => 'ἡ',
653
+ 'Ἢ' => 'ἢ',
654
+ 'Ἣ' => 'ἣ',
655
+ 'Ἤ' => 'ἤ',
656
+ 'Ἥ' => 'ἥ',
657
+ 'Ἦ' => 'ἦ',
658
+ 'Ἧ' => 'ἧ',
659
+ 'Ἰ' => 'ἰ',
660
+ 'Ἱ' => 'ἱ',
661
+ 'Ἲ' => 'ἲ',
662
+ 'Ἳ' => 'ἳ',
663
+ 'Ἴ' => 'ἴ',
664
+ 'Ἵ' => 'ἵ',
665
+ 'Ἶ' => 'ἶ',
666
+ 'Ἷ' => 'ἷ',
667
+ 'Ὀ' => 'ὀ',
668
+ 'Ὁ' => 'ὁ',
669
+ 'Ὂ' => 'ὂ',
670
+ 'Ὃ' => 'ὃ',
671
+ 'Ὄ' => 'ὄ',
672
+ 'Ὅ' => 'ὅ',
673
+ 'Ὑ' => 'ὑ',
674
+ 'Ὓ' => 'ὓ',
675
+ 'Ὕ' => 'ὕ',
676
+ 'Ὗ' => 'ὗ',
677
+ 'Ὠ' => 'ὠ',
678
+ 'Ὡ' => 'ὡ',
679
+ 'Ὢ' => 'ὢ',
680
+ 'Ὣ' => 'ὣ',
681
+ 'Ὤ' => 'ὤ',
682
+ 'Ὥ' => 'ὥ',
683
+ 'Ὦ' => 'ὦ',
684
+ 'Ὧ' => 'ὧ',
685
+ 'ᾈ' => 'ᾀ',
686
+ 'ᾉ' => 'ᾁ',
687
+ 'ᾊ' => 'ᾂ',
688
+ 'ᾋ' => 'ᾃ',
689
+ 'ᾌ' => 'ᾄ',
690
+ 'ᾍ' => 'ᾅ',
691
+ 'ᾎ' => 'ᾆ',
692
+ 'ᾏ' => 'ᾇ',
693
+ 'ᾘ' => 'ᾐ',
694
+ 'ᾙ' => 'ᾑ',
695
+ 'ᾚ' => 'ᾒ',
696
+ 'ᾛ' => 'ᾓ',
697
+ 'ᾜ' => 'ᾔ',
698
+ 'ᾝ' => 'ᾕ',
699
+ 'ᾞ' => 'ᾖ',
700
+ 'ᾟ' => 'ᾗ',
701
+ 'ᾨ' => 'ᾠ',
702
+ 'ᾩ' => 'ᾡ',
703
+ 'ᾪ' => 'ᾢ',
704
+ 'ᾫ' => 'ᾣ',
705
+ 'ᾬ' => 'ᾤ',
706
+ 'ᾭ' => 'ᾥ',
707
+ 'ᾮ' => 'ᾦ',
708
+ 'ᾯ' => 'ᾧ',
709
+ 'Ᾰ' => 'ᾰ',
710
+ 'Ᾱ' => 'ᾱ',
711
+ 'Ὰ' => 'ὰ',
712
+ 'Ά' => 'ά',
713
+ 'ᾼ' => 'ᾳ',
714
+ 'Ὲ' => 'ὲ',
715
+ 'Έ' => 'έ',
716
+ 'Ὴ' => 'ὴ',
717
+ 'Ή' => 'ή',
718
+ 'ῌ' => 'ῃ',
719
+ 'Ῐ' => 'ῐ',
720
+ 'Ῑ' => 'ῑ',
721
+ 'Ὶ' => 'ὶ',
722
+ 'Ί' => 'ί',
723
+ 'Ῠ' => 'ῠ',
724
+ 'Ῡ' => 'ῡ',
725
+ 'Ὺ' => 'ὺ',
726
+ 'Ύ' => 'ύ',
727
+ 'Ῥ' => 'ῥ',
728
+ 'Ὸ' => 'ὸ',
729
+ 'Ό' => 'ό',
730
+ 'Ὼ' => 'ὼ',
731
+ 'Ώ' => 'ώ',
732
+ 'ῼ' => 'ῳ',
733
+ 'Ω' => 'ω',
734
+ 'K' => 'k',
735
+ 'Å' => 'å',
736
+ 'Ⅎ' => 'ⅎ',
737
+ 'Ⅰ' => 'ⅰ',
738
+ 'Ⅱ' => 'ⅱ',
739
+ 'Ⅲ' => 'ⅲ',
740
+ 'Ⅳ' => 'ⅳ',
741
+ 'Ⅴ' => 'ⅴ',
742
+ 'Ⅵ' => 'ⅵ',
743
+ 'Ⅶ' => 'ⅶ',
744
+ 'Ⅷ' => 'ⅷ',
745
+ 'Ⅸ' => 'ⅸ',
746
+ 'Ⅹ' => 'ⅹ',
747
+ 'Ⅺ' => 'ⅺ',
748
+ 'Ⅻ' => 'ⅻ',
749
+ 'Ⅼ' => 'ⅼ',
750
+ 'Ⅽ' => 'ⅽ',
751
+ 'Ⅾ' => 'ⅾ',
752
+ 'Ⅿ' => 'ⅿ',
753
+ 'Ↄ' => 'ↄ',
754
+ 'Ⓐ' => 'ⓐ',
755
+ 'Ⓑ' => 'ⓑ',
756
+ 'Ⓒ' => 'ⓒ',
757
+ 'Ⓓ' => 'ⓓ',
758
+ 'Ⓔ' => 'ⓔ',
759
+ 'Ⓕ' => 'ⓕ',
760
+ 'Ⓖ' => 'ⓖ',
761
+ 'Ⓗ' => 'ⓗ',
762
+ 'Ⓘ' => 'ⓘ',
763
+ 'Ⓙ' => 'ⓙ',
764
+ 'Ⓚ' => 'ⓚ',
765
+ 'Ⓛ' => 'ⓛ',
766
+ 'Ⓜ' => 'ⓜ',
767
+ 'Ⓝ' => 'ⓝ',
768
+ 'Ⓞ' => 'ⓞ',
769
+ 'Ⓟ' => 'ⓟ',
770
+ 'Ⓠ' => 'ⓠ',
771
+ 'Ⓡ' => 'ⓡ',
772
+ 'Ⓢ' => 'ⓢ',
773
+ 'Ⓣ' => 'ⓣ',
774
+ 'Ⓤ' => 'ⓤ',
775
+ 'Ⓥ' => 'ⓥ',
776
+ 'Ⓦ' => 'ⓦ',
777
+ 'Ⓧ' => 'ⓧ',
778
+ 'Ⓨ' => 'ⓨ',
779
+ 'Ⓩ' => 'ⓩ',
780
+ 'Ⰰ' => 'ⰰ',
781
+ 'Ⰱ' => 'ⰱ',
782
+ 'Ⰲ' => 'ⰲ',
783
+ 'Ⰳ' => 'ⰳ',
784
+ 'Ⰴ' => 'ⰴ',
785
+ 'Ⰵ' => 'ⰵ',
786
+ 'Ⰶ' => 'ⰶ',
787
+ 'Ⰷ' => 'ⰷ',
788
+ 'Ⰸ' => 'ⰸ',
789
+ 'Ⰹ' => 'ⰹ',
790
+ 'Ⰺ' => 'ⰺ',
791
+ 'Ⰻ' => 'ⰻ',
792
+ 'Ⰼ' => 'ⰼ',
793
+ 'Ⰽ' => 'ⰽ',
794
+ 'Ⰾ' => 'ⰾ',
795
+ 'Ⰿ' => 'ⰿ',
796
+ 'Ⱀ' => 'ⱀ',
797
+ 'Ⱁ' => 'ⱁ',
798
+ 'Ⱂ' => 'ⱂ',
799
+ 'Ⱃ' => 'ⱃ',
800
+ 'Ⱄ' => 'ⱄ',
801
+ 'Ⱅ' => 'ⱅ',
802
+ 'Ⱆ' => 'ⱆ',
803
+ 'Ⱇ' => 'ⱇ',
804
+ 'Ⱈ' => 'ⱈ',
805
+ 'Ⱉ' => 'ⱉ',
806
+ 'Ⱊ' => 'ⱊ',
807
+ 'Ⱋ' => 'ⱋ',
808
+ 'Ⱌ' => 'ⱌ',
809
+ 'Ⱍ' => 'ⱍ',
810
+ 'Ⱎ' => 'ⱎ',
811
+ 'Ⱏ' => 'ⱏ',
812
+ 'Ⱐ' => 'ⱐ',
813
+ 'Ⱑ' => 'ⱑ',
814
+ 'Ⱒ' => 'ⱒ',
815
+ 'Ⱓ' => 'ⱓ',
816
+ 'Ⱔ' => 'ⱔ',
817
+ 'Ⱕ' => 'ⱕ',
818
+ 'Ⱖ' => 'ⱖ',
819
+ 'Ⱗ' => 'ⱗ',
820
+ 'Ⱘ' => 'ⱘ',
821
+ 'Ⱙ' => 'ⱙ',
822
+ 'Ⱚ' => 'ⱚ',
823
+ 'Ⱛ' => 'ⱛ',
824
+ 'Ⱜ' => 'ⱜ',
825
+ 'Ⱝ' => 'ⱝ',
826
+ 'Ⱞ' => 'ⱞ',
827
+ 'Ⱡ' => 'ⱡ',
828
+ 'Ɫ' => 'ɫ',
829
+ 'Ᵽ' => 'ᵽ',
830
+ 'Ɽ' => 'ɽ',
831
+ 'Ⱨ' => 'ⱨ',
832
+ 'Ⱪ' => 'ⱪ',
833
+ 'Ⱬ' => 'ⱬ',
834
+ 'Ɑ' => 'ɑ',
835
+ 'Ɱ' => 'ɱ',
836
+ 'Ɐ' => 'ɐ',
837
+ 'Ɒ' => 'ɒ',
838
+ 'Ⱳ' => 'ⱳ',
839
+ 'Ⱶ' => 'ⱶ',
840
+ 'Ȿ' => 'ȿ',
841
+ 'Ɀ' => 'ɀ',
842
+ 'Ⲁ' => 'ⲁ',
843
+ 'Ⲃ' => 'ⲃ',
844
+ 'Ⲅ' => 'ⲅ',
845
+ 'Ⲇ' => 'ⲇ',
846
+ 'Ⲉ' => 'ⲉ',
847
+ 'Ⲋ' => 'ⲋ',
848
+ 'Ⲍ' => 'ⲍ',
849
+ 'Ⲏ' => 'ⲏ',
850
+ 'Ⲑ' => 'ⲑ',
851
+ 'Ⲓ' => 'ⲓ',
852
+ 'Ⲕ' => 'ⲕ',
853
+ 'Ⲗ' => 'ⲗ',
854
+ 'Ⲙ' => 'ⲙ',
855
+ 'Ⲛ' => 'ⲛ',
856
+ 'Ⲝ' => 'ⲝ',
857
+ 'Ⲟ' => 'ⲟ',
858
+ 'Ⲡ' => 'ⲡ',
859
+ 'Ⲣ' => 'ⲣ',
860
+ 'Ⲥ' => 'ⲥ',
861
+ 'Ⲧ' => 'ⲧ',
862
+ 'Ⲩ' => 'ⲩ',
863
+ 'Ⲫ' => 'ⲫ',
864
+ 'Ⲭ' => 'ⲭ',
865
+ 'Ⲯ' => 'ⲯ',
866
+ 'Ⲱ' => 'ⲱ',
867
+ 'Ⲳ' => 'ⲳ',
868
+ 'Ⲵ' => 'ⲵ',
869
+ 'Ⲷ' => 'ⲷ',
870
+ 'Ⲹ' => 'ⲹ',
871
+ 'Ⲻ' => 'ⲻ',
872
+ 'Ⲽ' => 'ⲽ',
873
+ 'Ⲿ' => 'ⲿ',
874
+ 'Ⳁ' => 'ⳁ',
875
+ 'Ⳃ' => 'ⳃ',
876
+ 'Ⳅ' => 'ⳅ',
877
+ 'Ⳇ' => 'ⳇ',
878
+ 'Ⳉ' => 'ⳉ',
879
+ 'Ⳋ' => 'ⳋ',
880
+ 'Ⳍ' => 'ⳍ',
881
+ 'Ⳏ' => 'ⳏ',
882
+ 'Ⳑ' => 'ⳑ',
883
+ 'Ⳓ' => 'ⳓ',
884
+ 'Ⳕ' => 'ⳕ',
885
+ 'Ⳗ' => 'ⳗ',
886
+ 'Ⳙ' => 'ⳙ',
887
+ 'Ⳛ' => 'ⳛ',
888
+ 'Ⳝ' => 'ⳝ',
889
+ 'Ⳟ' => 'ⳟ',
890
+ 'Ⳡ' => 'ⳡ',
891
+ 'Ⳣ' => 'ⳣ',
892
+ 'Ⳬ' => 'ⳬ',
893
+ 'Ⳮ' => 'ⳮ',
894
+ 'Ⳳ' => 'ⳳ',
895
+ 'Ꙁ' => 'ꙁ',
896
+ 'Ꙃ' => 'ꙃ',
897
+ 'Ꙅ' => 'ꙅ',
898
+ 'Ꙇ' => 'ꙇ',
899
+ 'Ꙉ' => 'ꙉ',
900
+ 'Ꙋ' => 'ꙋ',
901
+ 'Ꙍ' => 'ꙍ',
902
+ 'Ꙏ' => 'ꙏ',
903
+ 'Ꙑ' => 'ꙑ',
904
+ 'Ꙓ' => 'ꙓ',
905
+ 'Ꙕ' => 'ꙕ',
906
+ 'Ꙗ' => 'ꙗ',
907
+ 'Ꙙ' => 'ꙙ',
908
+ 'Ꙛ' => 'ꙛ',
909
+ 'Ꙝ' => 'ꙝ',
910
+ 'Ꙟ' => 'ꙟ',
911
+ 'Ꙡ' => 'ꙡ',
912
+ 'Ꙣ' => 'ꙣ',
913
+ 'Ꙥ' => 'ꙥ',
914
+ 'Ꙧ' => 'ꙧ',
915
+ 'Ꙩ' => 'ꙩ',
916
+ 'Ꙫ' => 'ꙫ',
917
+ 'Ꙭ' => 'ꙭ',
918
+ 'Ꚁ' => 'ꚁ',
919
+ 'Ꚃ' => 'ꚃ',
920
+ 'Ꚅ' => 'ꚅ',
921
+ 'Ꚇ' => 'ꚇ',
922
+ 'Ꚉ' => 'ꚉ',
923
+ 'Ꚋ' => 'ꚋ',
924
+ 'Ꚍ' => 'ꚍ',
925
+ 'Ꚏ' => 'ꚏ',
926
+ 'Ꚑ' => 'ꚑ',
927
+ 'Ꚓ' => 'ꚓ',
928
+ 'Ꚕ' => 'ꚕ',
929
+ 'Ꚗ' => 'ꚗ',
930
+ 'Ꚙ' => 'ꚙ',
931
+ 'Ꚛ' => 'ꚛ',
932
+ 'Ꜣ' => 'ꜣ',
933
+ 'Ꜥ' => 'ꜥ',
934
+ 'Ꜧ' => 'ꜧ',
935
+ 'Ꜩ' => 'ꜩ',
936
+ 'Ꜫ' => 'ꜫ',
937
+ 'Ꜭ' => 'ꜭ',
938
+ 'Ꜯ' => 'ꜯ',
939
+ 'Ꜳ' => 'ꜳ',
940
+ 'Ꜵ' => 'ꜵ',
941
+ 'Ꜷ' => 'ꜷ',
942
+ 'Ꜹ' => 'ꜹ',
943
+ 'Ꜻ' => 'ꜻ',
944
+ 'Ꜽ' => 'ꜽ',
945
+ 'Ꜿ' => 'ꜿ',
946
+ 'Ꝁ' => 'ꝁ',
947
+ 'Ꝃ' => 'ꝃ',
948
+ 'Ꝅ' => 'ꝅ',
949
+ 'Ꝇ' => 'ꝇ',
950
+ 'Ꝉ' => 'ꝉ',
951
+ 'Ꝋ' => 'ꝋ',
952
+ 'Ꝍ' => 'ꝍ',
953
+ 'Ꝏ' => 'ꝏ',
954
+ 'Ꝑ' => 'ꝑ',
955
+ 'Ꝓ' => 'ꝓ',
956
+ 'Ꝕ' => 'ꝕ',
957
+ 'Ꝗ' => 'ꝗ',
958
+ 'Ꝙ' => 'ꝙ',
959
+ 'Ꝛ' => 'ꝛ',
960
+ 'Ꝝ' => 'ꝝ',
961
+ 'Ꝟ' => 'ꝟ',
962
+ 'Ꝡ' => 'ꝡ',
963
+ 'Ꝣ' => 'ꝣ',
964
+ 'Ꝥ' => 'ꝥ',
965
+ 'Ꝧ' => 'ꝧ',
966
+ 'Ꝩ' => 'ꝩ',
967
+ 'Ꝫ' => 'ꝫ',
968
+ 'Ꝭ' => 'ꝭ',
969
+ 'Ꝯ' => 'ꝯ',
970
+ 'Ꝺ' => 'ꝺ',
971
+ 'Ꝼ' => 'ꝼ',
972
+ 'Ᵹ' => 'ᵹ',
973
+ 'Ꝿ' => 'ꝿ',
974
+ 'Ꞁ' => 'ꞁ',
975
+ 'Ꞃ' => 'ꞃ',
976
+ 'Ꞅ' => 'ꞅ',
977
+ 'Ꞇ' => 'ꞇ',
978
+ 'Ꞌ' => 'ꞌ',
979
+ 'Ɥ' => 'ɥ',
980
+ 'Ꞑ' => 'ꞑ',
981
+ 'Ꞓ' => 'ꞓ',
982
+ 'Ꞗ' => 'ꞗ',
983
+ 'Ꞙ' => 'ꞙ',
984
+ 'Ꞛ' => 'ꞛ',
985
+ 'Ꞝ' => 'ꞝ',
986
+ 'Ꞟ' => 'ꞟ',
987
+ 'Ꞡ' => 'ꞡ',
988
+ 'Ꞣ' => 'ꞣ',
989
+ 'Ꞥ' => 'ꞥ',
990
+ 'Ꞧ' => 'ꞧ',
991
+ 'Ꞩ' => 'ꞩ',
992
+ 'Ɦ' => 'ɦ',
993
+ 'Ɜ' => 'ɜ',
994
+ 'Ɡ' => 'ɡ',
995
+ 'Ɬ' => 'ɬ',
996
+ 'Ʞ' => 'ʞ',
997
+ 'Ʇ' => 'ʇ',
998
+ 'A' => 'a',
999
+ 'B' => 'b',
1000
+ 'C' => 'c',
1001
+ 'D' => 'd',
1002
+ 'E' => 'e',
1003
+ 'F' => 'f',
1004
+ 'G' => 'g',
1005
+ 'H' => 'h',
1006
+ 'I' => 'i',
1007
+ 'J' => 'j',
1008
+ 'K' => 'k',
1009
+ 'L' => 'l',
1010
+ 'M' => 'm',
1011
+ 'N' => 'n',
1012
+ 'O' => 'o',
1013
+ 'P' => 'p',
1014
+ 'Q' => 'q',
1015
+ 'R' => 'r',
1016
+ 'S' => 's',
1017
+ 'T' => 't',
1018
+ 'U' => 'u',
1019
+ 'V' => 'v',
1020
+ 'W' => 'w',
1021
+ 'X' => 'x',
1022
+ 'Y' => 'y',
1023
+ 'Z' => 'z',
1024
+ '𐐀' => '𐐨',
1025
+ '𐐁' => '𐐩',
1026
+ '𐐂' => '𐐪',
1027
+ '𐐃' => '𐐫',
1028
+ '𐐄' => '𐐬',
1029
+ '𐐅' => '𐐭',
1030
+ '𐐆' => '𐐮',
1031
+ '𐐇' => '𐐯',
1032
+ '𐐈' => '𐐰',
1033
+ '𐐉' => '𐐱',
1034
+ '𐐊' => '𐐲',
1035
+ '𐐋' => '𐐳',
1036
+ '𐐌' => '𐐴',
1037
+ '𐐍' => '𐐵',
1038
+ '𐐎' => '𐐶',
1039
+ '𐐏' => '𐐷',
1040
+ '𐐐' => '𐐸',
1041
+ '𐐑' => '𐐹',
1042
+ '𐐒' => '𐐺',
1043
+ '𐐓' => '𐐻',
1044
+ '𐐔' => '𐐼',
1045
+ '𐐕' => '𐐽',
1046
+ '𐐖' => '𐐾',
1047
+ '𐐗' => '𐐿',
1048
+ '𐐘' => '𐑀',
1049
+ '𐐙' => '𐑁',
1050
+ '𐐚' => '𐑂',
1051
+ '𐐛' => '𐑃',
1052
+ '𐐜' => '𐑄',
1053
+ '𐐝' => '𐑅',
1054
+ '𐐞' => '𐑆',
1055
+ '𐐟' => '𐑇',
1056
+ '𐐠' => '𐑈',
1057
+ '𐐡' => '𐑉',
1058
+ '𐐢' => '𐑊',
1059
+ '𐐣' => '𐑋',
1060
+ '𐐤' => '𐑌',
1061
+ '𐐥' => '𐑍',
1062
+ '𐐦' => '𐑎',
1063
+ '𐐧' => '𐑏',
1064
+ '𑢠' => '𑣀',
1065
+ '𑢡' => '𑣁',
1066
+ '𑢢' => '𑣂',
1067
+ '𑢣' => '𑣃',
1068
+ '𑢤' => '𑣄',
1069
+ '𑢥' => '𑣅',
1070
+ '𑢦' => '𑣆',
1071
+ '𑢧' => '𑣇',
1072
+ '𑢨' => '𑣈',
1073
+ '𑢩' => '𑣉',
1074
+ '𑢪' => '𑣊',
1075
+ '𑢫' => '𑣋',
1076
+ '𑢬' => '𑣌',
1077
+ '𑢭' => '𑣍',
1078
+ '𑢮' => '𑣎',
1079
+ '𑢯' => '𑣏',
1080
+ '𑢰' => '𑣐',
1081
+ '𑢱' => '𑣑',
1082
+ '𑢲' => '𑣒',
1083
+ '𑢳' => '𑣓',
1084
+ '𑢴' => '𑣔',
1085
+ '𑢵' => '𑣕',
1086
+ '𑢶' => '𑣖',
1087
+ '𑢷' => '𑣗',
1088
+ '𑢸' => '𑣘',
1089
+ '𑢹' => '𑣙',
1090
+ '𑢺' => '𑣚',
1091
+ '𑢻' => '𑣛',
1092
+ '𑢼' => '𑣜',
1093
+ '𑢽' => '𑣝',
1094
+ '𑢾' => '𑣞',
1095
+ '𑢿' => '𑣟',
1096
+ );
1097
+
1098
+ $result =& $data;
1099
+ unset($data);
1100
+
1101
+ return $result;
app/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php ADDED
@@ -0,0 +1,1109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ static $data = array (
4
+ 'a' => 'A',
5
+ 'b' => 'B',
6
+ 'c' => 'C',
7
+ 'd' => 'D',
8
+ 'e' => 'E',
9
+ 'f' => 'F',
10
+ 'g' => 'G',
11
+ 'h' => 'H',
12
+ 'i' => 'I',
13
+ 'j' => 'J',
14
+ 'k' => 'K',
15
+ 'l' => 'L',
16
+ 'm' => 'M',
17
+ 'n' => 'N',
18
+ 'o' => 'O',
19
+ 'p' => 'P',
20
+ 'q' => 'Q',
21
+ 'r' => 'R',
22
+ 's' => 'S',
23
+ 't' => 'T',
24
+ 'u' => 'U',
25
+ 'v' => 'V',
26
+ 'w' => 'W',
27
+ 'x' => 'X',
28
+ 'y' => 'Y',
29
+ 'z' => 'Z',
30
+ 'µ' => 'Μ',
31
+ 'à' => 'À',
32
+ 'á' => 'Á',
33
+ 'â' => 'Â',
34
+ 'ã' => 'Ã',
35
+ 'ä' => 'Ä',
36
+ 'å' => 'Å',
37
+ 'æ' => 'Æ',
38
+ 'ç' => 'Ç',
39
+ 'è' => 'È',
40
+ 'é' => 'É',
41
+ 'ê' => 'Ê',
42
+ 'ë' => 'Ë',
43
+ 'ì' => 'Ì',
44
+ 'í' => 'Í',
45
+ 'î' => 'Î',
46
+ 'ï' => 'Ï',
47
+ 'ð' => 'Ð',
48
+ 'ñ' => 'Ñ',
49
+ 'ò' => 'Ò',
50
+ 'ó' => 'Ó',
51
+ 'ô' => 'Ô',
52
+ 'õ' => 'Õ',
53
+ 'ö' => 'Ö',
54
+ 'ø' => 'Ø',
55
+ 'ù' => 'Ù',
56
+ 'ú' => 'Ú',
57
+ 'û' => 'Û',
58
+ 'ü' => 'Ü',
59
+ 'ý' => 'Ý',
60
+ 'þ' => 'Þ',
61
+ 'ÿ' => 'Ÿ',
62
+ 'ā' => 'Ā',
63
+ 'ă' => 'Ă',
64
+ 'ą' => 'Ą',
65
+ 'ć' => 'Ć',
66
+ 'ĉ' => 'Ĉ',
67
+ 'ċ' => 'Ċ',
68
+ 'č' => 'Č',
69
+ 'ď' => 'Ď',
70
+ 'đ' => 'Đ',
71
+ 'ē' => 'Ē',
72
+ 'ĕ' => 'Ĕ',
73
+ 'ė' => 'Ė',
74
+ 'ę' => 'Ę',
75
+ 'ě' => 'Ě',
76
+ 'ĝ' => 'Ĝ',
77
+ 'ğ' => 'Ğ',
78
+ 'ġ' => 'Ġ',
79
+ 'ģ' => 'Ģ',
80
+ 'ĥ' => 'Ĥ',
81
+ 'ħ' => 'Ħ',
82
+ 'ĩ' => 'Ĩ',
83
+ 'ī' => 'Ī',
84
+ 'ĭ' => 'Ĭ',
85
+ 'į' => 'Į',
86
+ 'ı' => 'I',
87
+ 'ij' => 'IJ',
88
+ 'ĵ' => 'Ĵ',
89
+ 'ķ' => 'Ķ',
90
+ 'ĺ' => 'Ĺ',
91
+ 'ļ' => 'Ļ',
92
+ 'ľ' => 'Ľ',
93
+ 'ŀ' => 'Ŀ',
94
+ 'ł' => 'Ł',
95
+ 'ń' => 'Ń',
96
+ 'ņ' => 'Ņ',
97
+ 'ň' => 'Ň',
98
+ 'ŋ' => 'Ŋ',
99
+ 'ō' => 'Ō',
100
+ 'ŏ' => 'Ŏ',
101
+ 'ő' => 'Ő',
102
+ 'œ' => 'Œ',
103
+ 'ŕ' => 'Ŕ',
104
+ 'ŗ' => 'Ŗ',
105
+ 'ř' => 'Ř',
106
+ 'ś' => 'Ś',
107
+ 'ŝ' => 'Ŝ',
108
+ 'ş' => 'Ş',
109
+ 'š' => 'Š',
110
+ 'ţ' => 'Ţ',
111
+ 'ť' => 'Ť',
112
+ 'ŧ' => 'Ŧ',
113
+ 'ũ' => 'Ũ',
114
+ 'ū' => 'Ū',
115
+ 'ŭ' => 'Ŭ',
116
+ 'ů' => 'Ů',
117
+ 'ű' => 'Ű',
118
+ 'ų' => 'Ų',
119
+ 'ŵ' => 'Ŵ',
120
+ 'ŷ' => 'Ŷ',
121
+ 'ź' => 'Ź',
122
+ 'ż' => 'Ż',
123
+ 'ž' => 'Ž',
124
+ 'ſ' => 'S',
125
+ 'ƀ' => 'Ƀ',
126
+ 'ƃ' => 'Ƃ',
127
+ 'ƅ' => 'Ƅ',
128
+ 'ƈ' => 'Ƈ',
129
+ 'ƌ' => 'Ƌ',
130
+ 'ƒ' => 'Ƒ',
131
+ 'ƕ' => 'Ƕ',
132
+ 'ƙ' => 'Ƙ',
133
+ 'ƚ' => 'Ƚ',
134
+ 'ƞ' => 'Ƞ',
135
+ 'ơ' => 'Ơ',
136
+ 'ƣ' => 'Ƣ',
137
+ 'ƥ' => 'Ƥ',
138
+ 'ƨ' => 'Ƨ',
139
+ 'ƭ' => 'Ƭ',
140
+ 'ư' => 'Ư',
141
+ 'ƴ' => 'Ƴ',
142
+ 'ƶ' => 'Ƶ',
143
+ 'ƹ' => 'Ƹ',
144
+ 'ƽ' => 'Ƽ',
145
+ 'ƿ' => 'Ƿ',
146
+ 'Dž' => 'DŽ',
147
+ 'dž' => 'DŽ',
148
+ 'Lj' => 'LJ',
149
+ 'lj' => 'LJ',
150
+ 'Nj' => 'NJ',
151
+ 'nj' => 'NJ',
152
+ 'ǎ' => 'Ǎ',
153
+ 'ǐ' => 'Ǐ',
154
+ 'ǒ' => 'Ǒ',
155
+ 'ǔ' => 'Ǔ',
156
+ 'ǖ' => 'Ǖ',
157
+ 'ǘ' => 'Ǘ',
158
+ 'ǚ' => 'Ǚ',
159
+ 'ǜ' => 'Ǜ',
160
+ 'ǝ' => 'Ǝ',
161
+ 'ǟ' => 'Ǟ',
162
+ 'ǡ' => 'Ǡ',
163
+ 'ǣ' => 'Ǣ',
164
+ 'ǥ' => 'Ǥ',
165
+ 'ǧ' => 'Ǧ',
166
+ 'ǩ' => 'Ǩ',
167
+ 'ǫ' => 'Ǫ',
168
+ 'ǭ' => 'Ǭ',
169
+ 'ǯ' => 'Ǯ',
170
+ 'Dz' => 'DZ',
171
+ 'dz' => 'DZ',
172
+ 'ǵ' => 'Ǵ',
173
+ 'ǹ' => 'Ǹ',
174
+ 'ǻ' => 'Ǻ',
175
+ 'ǽ' => 'Ǽ',
176
+ 'ǿ' => 'Ǿ',
177
+ 'ȁ' => 'Ȁ',
178
+ 'ȃ' => 'Ȃ',
179
+ 'ȅ' => 'Ȅ',
180
+ 'ȇ' => 'Ȇ',
181
+ 'ȉ' => 'Ȉ',
182
+ 'ȋ' => 'Ȋ',
183
+ 'ȍ' => 'Ȍ',
184
+ 'ȏ' => 'Ȏ',
185
+ 'ȑ' => 'Ȑ',
186
+ 'ȓ' => 'Ȓ',
187
+ 'ȕ' => 'Ȕ',
188
+ 'ȗ' => 'Ȗ',
189
+ 'ș' => 'Ș',
190
+ 'ț' => 'Ț',
191
+ 'ȝ' => 'Ȝ',
192
+ 'ȟ' => 'Ȟ',
193
+ 'ȣ' => 'Ȣ',
194
+ 'ȥ' => 'Ȥ',
195
+ 'ȧ' => 'Ȧ',
196
+ 'ȩ' => 'Ȩ',
197
+ 'ȫ' => 'Ȫ',
198
+ 'ȭ' => 'Ȭ',
199
+ 'ȯ' => 'Ȯ',
200
+ 'ȱ' => 'Ȱ',
201
+ 'ȳ' => 'Ȳ',
202
+ 'ȼ' => 'Ȼ',
203
+ 'ȿ' => 'Ȿ',
204
+ 'ɀ' => 'Ɀ',
205
+ 'ɂ' => 'Ɂ',
206
+ 'ɇ' => 'Ɇ',
207
+ 'ɉ' => 'Ɉ',
208
+ 'ɋ' => 'Ɋ',
209
+ 'ɍ' => 'Ɍ',
210
+ 'ɏ' => 'Ɏ',
211
+ 'ɐ' => 'Ɐ',
212
+ 'ɑ' => 'Ɑ',
213
+ 'ɒ' => 'Ɒ',
214
+ 'ɓ' => 'Ɓ',
215
+ 'ɔ' => 'Ɔ',
216
+ 'ɖ' => 'Ɖ',
217
+ 'ɗ' => 'Ɗ',
218
+ 'ə' => 'Ə',
219
+ 'ɛ' => 'Ɛ',
220
+ 'ɜ' => 'Ɜ',
221
+ 'ɠ' => 'Ɠ',
222
+ 'ɡ' => 'Ɡ',
223
+ 'ɣ' => 'Ɣ',
224
+ 'ɥ' => 'Ɥ',
225
+ 'ɦ' => 'Ɦ',
226
+ 'ɨ' => 'Ɨ',
227
+ 'ɩ' => 'Ɩ',
228
+ 'ɫ' => 'Ɫ',
229
+ 'ɬ' => 'Ɬ',
230
+ 'ɯ' => 'Ɯ',
231
+ 'ɱ' => 'Ɱ',
232
+ 'ɲ' => 'Ɲ',
233
+ 'ɵ' => 'Ɵ',
234
+ 'ɽ' => 'Ɽ',
235
+ 'ʀ' => 'Ʀ',
236
+ 'ʃ' => 'Ʃ',
237
+ 'ʇ' => 'Ʇ',
238
+ 'ʈ' => 'Ʈ',
239
+ 'ʉ' => 'Ʉ',
240
+ 'ʊ' => 'Ʊ',
241
+ 'ʋ' => 'Ʋ',
242
+ 'ʌ' => 'Ʌ',
243
+ 'ʒ' => 'Ʒ',
244
+ 'ʞ' => 'Ʞ',
245
+ 'ͅ' => 'Ι',
246
+ 'ͱ' => 'Ͱ',
247
+ 'ͳ' => 'Ͳ',
248
+ 'ͷ' => 'Ͷ',
249
+ 'ͻ' => 'Ͻ',
250
+ 'ͼ' => 'Ͼ',
251
+ 'ͽ' => 'Ͽ',
252
+ 'ά' => 'Ά',
253
+ 'έ' => 'Έ',
254
+ 'ή' => 'Ή',
255
+ 'ί' => 'Ί',
256
+ 'α' => 'Α',
257
+ 'β' => 'Β',
258
+ 'γ' => 'Γ',
259
+ 'δ' => 'Δ',
260
+ 'ε' => 'Ε',
261
+ 'ζ' => 'Ζ',
262
+ 'η' => 'Η',
263
+ 'θ' => 'Θ',
264
+ 'ι' => 'Ι',
265
+ 'κ' => 'Κ',
266
+ 'λ' => 'Λ',
267
+ 'μ' => 'Μ',
268
+ 'ν' => 'Ν',
269
+ 'ξ' => 'Ξ',
270
+ 'ο' => 'Ο',
271
+ 'π' => 'Π',
272
+ 'ρ' => 'Ρ',
273
+ 'ς' => 'Σ',
274
+ 'σ' => 'Σ',
275
+ 'τ' => 'Τ',
276
+ 'υ' => 'Υ',
277
+ 'φ' => 'Φ',
278
+ 'χ' => 'Χ',
279
+ 'ψ' => 'Ψ',
280
+ 'ω' => 'Ω',
281
+ 'ϊ' => 'Ϊ',
282
+ 'ϋ' => 'Ϋ',
283
+ 'ό' => 'Ό',
284
+ 'ύ' => 'Ύ',
285
+ 'ώ' => 'Ώ',
286
+ 'ϐ' => 'Β',
287
+ 'ϑ' => 'Θ',
288
+ 'ϕ' => 'Φ',
289
+ 'ϖ' => 'Π',
290
+ 'ϗ' => 'Ϗ',
291
+ 'ϙ' => 'Ϙ',
292
+ 'ϛ' => 'Ϛ',
293
+ 'ϝ' => 'Ϝ',
294
+ 'ϟ' => 'Ϟ',
295
+ 'ϡ' => 'Ϡ',
296
+ 'ϣ' => 'Ϣ',
297
+ 'ϥ' => 'Ϥ',
298
+ 'ϧ' => 'Ϧ',
299
+ 'ϩ' => 'Ϩ',
300
+ 'ϫ' => 'Ϫ',
301
+ 'ϭ' => 'Ϭ',
302
+ 'ϯ' => 'Ϯ',
303
+ 'ϰ' => 'Κ',
304
+ 'ϱ' => 'Ρ',
305
+ 'ϲ' => 'Ϲ',
306
+ 'ϳ' => 'Ϳ',
307
+ 'ϵ' => 'Ε',
308
+ 'ϸ' => 'Ϸ',
309
+ 'ϻ' => 'Ϻ',
310
+ 'а' => 'А',
311
+ 'б' => 'Б',
312
+ 'в' => 'В',
313
+ 'г' => 'Г',
314
+ 'д' => 'Д',
315
+ 'е' => 'Е',
316
+ 'ж' => 'Ж',
317
+ 'з' => 'З',
318
+ 'и' => 'И',
319
+ 'й' => 'Й',
320
+ 'к' => 'К',
321
+ 'л' => 'Л',
322
+ 'м' => 'М',
323
+ 'н' => 'Н',
324
+ 'о' => 'О',
325
+ 'п' => 'П',
326
+ 'р' => 'Р',
327
+ 'с' => 'С',
328
+ 'т' => 'Т',
329
+ 'у' => 'У',
330
+ 'ф' => 'Ф',
331
+ 'х' => 'Х',
332
+ 'ц' => 'Ц',
333
+ 'ч' => 'Ч',
334
+ 'ш' => 'Ш',
335
+ 'щ' => 'Щ',
336
+ 'ъ' => 'Ъ',
337
+ 'ы' => 'Ы',
338
+ 'ь' => 'Ь',
339
+ 'э' => 'Э',
340
+ 'ю' => 'Ю',
341
+ 'я' => 'Я',
342
+ 'ѐ' => 'Ѐ',
343
+ 'ё' => 'Ё',
344
+ 'ђ' => 'Ђ',
345
+ 'ѓ' => 'Ѓ',
346
+ 'є' => 'Є',
347
+ 'ѕ' => 'Ѕ',
348
+ 'і' => 'І',
349
+ 'ї' => 'Ї',
350
+ 'ј' => 'Ј',
351
+ 'љ' => 'Љ',
352
+ 'њ' => 'Њ',
353
+ 'ћ' => 'Ћ',
354
+ 'ќ' => 'Ќ',
355
+ 'ѝ' => 'Ѝ',
356
+ 'ў' => 'Ў',
357
+ 'џ' => 'Џ',
358
+ 'ѡ' => 'Ѡ',
359
+ 'ѣ' => 'Ѣ',
360
+ 'ѥ' => 'Ѥ',
361
+ 'ѧ' => 'Ѧ',
362
+ 'ѩ' => 'Ѩ',
363
+ 'ѫ' => 'Ѫ',
364
+ 'ѭ' => 'Ѭ',
365
+ 'ѯ' => 'Ѯ',
366
+ 'ѱ' => 'Ѱ',
367
+ 'ѳ' => 'Ѳ',
368
+ 'ѵ' => 'Ѵ',
369
+ 'ѷ' => 'Ѷ',
370
+ 'ѹ' => 'Ѹ',
371
+ 'ѻ' => 'Ѻ',
372
+ 'ѽ' => 'Ѽ',
373
+ 'ѿ' => 'Ѿ',
374
+ 'ҁ' => 'Ҁ',
375
+ 'ҋ' => 'Ҋ',
376
+ 'ҍ' => 'Ҍ',
377
+ 'ҏ' => 'Ҏ',
378
+ 'ґ' => 'Ґ',
379
+ 'ғ' => 'Ғ',
380
+ 'ҕ' => 'Ҕ',
381
+ 'җ' => 'Җ',
382
+ 'ҙ' => 'Ҙ',
383
+ 'қ' => 'Қ',
384
+ 'ҝ' => 'Ҝ',
385
+ 'ҟ' => 'Ҟ',
386
+ 'ҡ' => 'Ҡ',
387
+ 'ң' => 'Ң',
388
+ 'ҥ' => 'Ҥ',
389
+ 'ҧ' => 'Ҧ',
390
+ 'ҩ' => 'Ҩ',
391
+ 'ҫ' => 'Ҫ',
392
+ 'ҭ' => 'Ҭ',
393
+ 'ү' => 'Ү',
394
+ 'ұ' => 'Ұ',
395
+ 'ҳ' => 'Ҳ',
396
+ 'ҵ' => 'Ҵ',
397
+ 'ҷ' => 'Ҷ',
398
+ 'ҹ' => 'Ҹ',
399
+ 'һ' => 'Һ',
400
+ 'ҽ' => 'Ҽ',
401
+ 'ҿ' => 'Ҿ',
402
+ 'ӂ' => 'Ӂ',
403
+ 'ӄ' => 'Ӄ',
404
+ 'ӆ' => 'Ӆ',
405
+ 'ӈ' => 'Ӈ',
406
+ 'ӊ' => 'Ӊ',
407
+ 'ӌ' => 'Ӌ',
408
+ 'ӎ' => 'Ӎ',
409
+ 'ӏ' => 'Ӏ',
410
+ 'ӑ' => 'Ӑ',
411
+ 'ӓ' => 'Ӓ',
412
+ 'ӕ' => 'Ӕ',
413
+ 'ӗ' => 'Ӗ',
414
+ 'ә' => 'Ә',
415
+ 'ӛ' => 'Ӛ',
416
+ 'ӝ' => 'Ӝ',
417
+ 'ӟ' => 'Ӟ',
418
+ 'ӡ' => 'Ӡ',
419
+ 'ӣ' => 'Ӣ',
420
+ 'ӥ' => 'Ӥ',
421
+ 'ӧ' => 'Ӧ',
422
+ 'ө' => 'Ө',
423
+ 'ӫ' => 'Ӫ',
424
+ 'ӭ' => 'Ӭ',
425
+ 'ӯ' => 'Ӯ',
426
+ 'ӱ' => 'Ӱ',
427
+ 'ӳ' => 'Ӳ',
428
+ 'ӵ' => 'Ӵ',
429
+ 'ӷ' => 'Ӷ',
430
+ 'ӹ' => 'Ӹ',
431
+ 'ӻ' => 'Ӻ',
432
+ 'ӽ' => 'Ӽ',
433
+ 'ӿ' => 'Ӿ',
434
+ 'ԁ' => 'Ԁ',
435
+ 'ԃ' => 'Ԃ',
436
+ 'ԅ' => 'Ԅ',
437
+ 'ԇ' => 'Ԇ',
438
+ 'ԉ' => 'Ԉ',
439
+ 'ԋ' => 'Ԋ',
440
+ 'ԍ' => 'Ԍ',
441
+ 'ԏ' => 'Ԏ',
442
+ 'ԑ' => 'Ԑ',
443
+ 'ԓ' => 'Ԓ',
444
+ 'ԕ' => 'Ԕ',
445
+ 'ԗ' => 'Ԗ',
446
+ 'ԙ' => 'Ԙ',
447
+ 'ԛ' => 'Ԛ',
448
+ 'ԝ' => 'Ԝ',
449
+ 'ԟ' => 'Ԟ',
450
+ 'ԡ' => 'Ԡ',
451
+ 'ԣ' => 'Ԣ',
452
+ 'ԥ' => 'Ԥ',
453
+ 'ԧ' => 'Ԧ',
454
+ 'ԩ' => 'Ԩ',
455
+ 'ԫ' => 'Ԫ',
456
+ 'ԭ' => 'Ԭ',
457
+ 'ԯ' => 'Ԯ',
458
+ 'ա' => 'Ա',
459
+ 'բ' => 'Բ',
460
+ 'գ' => 'Գ',
461
+ 'դ' => 'Դ',
462
+ 'ե' => 'Ե',
463
+ 'զ' => 'Զ',
464
+ 'է' => 'Է',
465
+ 'ը' => 'Ը',
466
+ 'թ' => 'Թ',
467
+ 'ժ' => 'Ժ',
468
+ 'ի' => 'Ի',
469
+ 'լ' => 'Լ',
470
+ 'խ' => 'Խ',
471
+ 'ծ' => 'Ծ',
472
+ 'կ' => 'Կ',
473
+ 'հ' => 'Հ',
474
+ 'ձ' => 'Ձ',
475
+ 'ղ' => 'Ղ',
476
+ 'ճ' => 'Ճ',
477
+ 'մ' => 'Մ',
478
+ 'յ' => 'Յ',
479
+ 'ն' => 'Ն',
480
+ 'շ' => 'Շ',
481
+ 'ո' => 'Ո',
482
+ 'չ' => 'Չ',
483
+ 'պ' => 'Պ',
484
+ 'ջ' => 'Ջ',
485
+ 'ռ' => 'Ռ',
486
+ 'ս' => 'Ս',
487
+ 'վ' => 'Վ',
488
+ 'տ' => 'Տ',
489
+ 'ր' => 'Ր',
490
+ 'ց' => 'Ց',
491
+ 'ւ' => 'Ւ',
492
+ 'փ' => 'Փ',
493
+ 'ք' => 'Ք',
494
+ 'օ' => 'Օ',
495
+ 'ֆ' => 'Ֆ',
496
+ 'ᵹ' => 'Ᵹ',
497
+ 'ᵽ' => 'Ᵽ',
498
+ 'ḁ' => 'Ḁ',
499
+ 'ḃ' => 'Ḃ',
500
+ 'ḅ' => 'Ḅ',
501
+ 'ḇ' => 'Ḇ',
502
+ 'ḉ' => 'Ḉ',
503
+ 'ḋ' => 'Ḋ',
504
+ 'ḍ' => 'Ḍ',
505
+ 'ḏ' => 'Ḏ',
506
+ 'ḑ' => 'Ḑ',
507
+ 'ḓ' => 'Ḓ',
508
+ 'ḕ' => 'Ḕ',
509
+ 'ḗ' => 'Ḗ',
510
+ 'ḙ' => 'Ḙ',
511
+ 'ḛ' => 'Ḛ',
512
+ 'ḝ' => 'Ḝ',
513
+ 'ḟ' => 'Ḟ',
514
+ 'ḡ' => 'Ḡ',
515
+ 'ḣ' => 'Ḣ',
516
+ 'ḥ' => 'Ḥ',
517
+ 'ḧ' => 'Ḧ',
518
+ 'ḩ' => 'Ḩ',
519
+ 'ḫ' => 'Ḫ',
520
+ 'ḭ' => 'Ḭ',
521
+ 'ḯ' => 'Ḯ',
522
+ 'ḱ' => 'Ḱ',
523
+ 'ḳ' => 'Ḳ',
524
+ 'ḵ' => 'Ḵ',
525
+ 'ḷ' => 'Ḷ',
526
+ 'ḹ' => 'Ḹ',
527
+ 'ḻ' => 'Ḻ',
528
+ 'ḽ' => 'Ḽ',
529
+ 'ḿ' => 'Ḿ',
530
+ 'ṁ' => 'Ṁ',
531
+ 'ṃ' => 'Ṃ',
532
+ 'ṅ' => 'Ṅ',
533
+ 'ṇ' => 'Ṇ',
534
+ 'ṉ' => 'Ṉ',
535
+ 'ṋ' => 'Ṋ',
536
+ 'ṍ' => 'Ṍ',
537
+ 'ṏ' => 'Ṏ',
538
+ 'ṑ' => 'Ṑ',
539
+ 'ṓ' => 'Ṓ',
540
+ 'ṕ' => 'Ṕ',
541
+ 'ṗ' => 'Ṗ',
542
+ 'ṙ' => 'Ṙ',
543
+ 'ṛ' => 'Ṛ',
544
+ 'ṝ' => 'Ṝ',
545
+ 'ṟ' => 'Ṟ',
546
+ 'ṡ' => 'Ṡ',
547
+ 'ṣ' => 'Ṣ',
548
+ 'ṥ' => 'Ṥ',
549
+ 'ṧ' => 'Ṧ',
550
+ 'ṩ' => 'Ṩ',
551
+ 'ṫ' => 'Ṫ',
552
+ 'ṭ' => 'Ṭ',
553
+ 'ṯ' => 'Ṯ',
554
+ 'ṱ' => 'Ṱ',
555
+ 'ṳ' => 'Ṳ',
556
+ 'ṵ' => 'Ṵ',
557
+ 'ṷ' => 'Ṷ',
558
+ 'ṹ' => 'Ṹ',
559
+ 'ṻ' => 'Ṻ',
560
+ 'ṽ' => 'Ṽ',
561
+ 'ṿ' => 'Ṿ',
562
+ 'ẁ' => 'Ẁ',
563
+ 'ẃ' => 'Ẃ',
564
+ 'ẅ' => 'Ẅ',
565
+ 'ẇ' => 'Ẇ',
566
+ 'ẉ' => 'Ẉ',
567
+ 'ẋ' => 'Ẋ',
568
+ 'ẍ' => 'Ẍ',
569
+ 'ẏ' => 'Ẏ',
570
+ 'ẑ' => 'Ẑ',
571
+ 'ẓ' => 'Ẓ',
572
+ 'ẕ' => 'Ẕ',
573
+ 'ẛ' => 'Ṡ',
574
+ 'ạ' => 'Ạ',
575
+ 'ả' => 'Ả',
576
+ 'ấ' => 'Ấ',
577
+ 'ầ' => 'Ầ',
578
+ 'ẩ' => 'Ẩ',
579
+ 'ẫ' => 'Ẫ',
580
+ 'ậ' => 'Ậ',
581
+ 'ắ' => 'Ắ',
582
+ 'ằ' => 'Ằ',
583
+ 'ẳ' => 'Ẳ',
584
+ 'ẵ' => 'Ẵ',
585
+ 'ặ' => 'Ặ',
586
+ 'ẹ' => 'Ẹ',
587
+ 'ẻ' => 'Ẻ',
588
+ 'ẽ' => 'Ẽ',
589
+ 'ế' => 'Ế',
590
+ 'ề' => 'Ề',
591
+ 'ể' => 'Ể',
592
+ 'ễ' => 'Ễ',
593
+ 'ệ' => 'Ệ',
594
+ 'ỉ' => 'Ỉ',
595
+ 'ị' => 'Ị',
596
+ 'ọ' => 'Ọ',
597
+ 'ỏ' => 'Ỏ',
598
+ 'ố' => 'Ố',
599
+ 'ồ' => 'Ồ',
600
+ 'ổ' => 'Ổ',
601
+ 'ỗ' => 'Ỗ',
602
+ 'ộ' => 'Ộ',
603
+ 'ớ' => 'Ớ',
604
+ 'ờ' => 'Ờ',
605
+ 'ở' => 'Ở',
606
+ 'ỡ' => 'Ỡ',
607
+ 'ợ' => 'Ợ',
608
+ 'ụ' => 'Ụ',
609
+ 'ủ' => 'Ủ',
610
+ 'ứ' => 'Ứ',
611
+ 'ừ' => 'Ừ',
612
+ 'ử' => 'Ử',
613
+ 'ữ' => 'Ữ',
614
+ 'ự' => 'Ự',
615
+ 'ỳ' => 'Ỳ',
616
+ 'ỵ' => 'Ỵ',
617
+ 'ỷ' => 'Ỷ',
618
+ 'ỹ' => 'Ỹ',
619
+ 'ỻ' => 'Ỻ',
620
+ 'ỽ' => 'Ỽ',
621
+ 'ỿ' => 'Ỿ',
622
+ 'ἀ' => 'Ἀ',
623
+ 'ἁ' => 'Ἁ',
624
+ 'ἂ' => 'Ἂ',
625
+ 'ἃ' => 'Ἃ',
626
+ 'ἄ' => 'Ἄ',
627
+ 'ἅ' => 'Ἅ',
628
+ 'ἆ' => 'Ἆ',
629
+ 'ἇ' => 'Ἇ',
630
+ 'ἐ' => 'Ἐ',
631
+ 'ἑ' => 'Ἑ',
632
+ 'ἒ' => 'Ἒ',
633
+ 'ἓ' => 'Ἓ',
634
+ 'ἔ' => 'Ἔ',
635
+ 'ἕ' => 'Ἕ',
636
+ 'ἠ' => 'Ἠ',
637
+ 'ἡ' => 'Ἡ',
638
+ 'ἢ' => 'Ἢ',
639
+ 'ἣ' => 'Ἣ',
640
+ 'ἤ' => 'Ἤ',
641
+ 'ἥ' => 'Ἥ',
642
+ 'ἦ' => 'Ἦ',
643
+ 'ἧ' => 'Ἧ',
644
+ 'ἰ' => 'Ἰ',
645
+ 'ἱ' => 'Ἱ',
646
+ 'ἲ' => 'Ἲ',
647
+ 'ἳ' => 'Ἳ',
648
+ 'ἴ' => 'Ἴ',
649
+ 'ἵ' => 'Ἵ',
650
+ 'ἶ' => 'Ἶ',
651
+ 'ἷ' => 'Ἷ',
652
+ 'ὀ' => 'Ὀ',
653
+ 'ὁ' => 'Ὁ',
654
+ 'ὂ' => 'Ὂ',
655
+ 'ὃ' => 'Ὃ',
656
+ 'ὄ' => 'Ὄ',
657
+ 'ὅ' => 'Ὅ',
658
+ 'ὑ' => 'Ὑ',
659
+ 'ὓ' => 'Ὓ',
660
+ 'ὕ' => 'Ὕ',
661
+ 'ὗ' => 'Ὗ',
662
+ 'ὠ' => 'Ὠ',
663
+ 'ὡ' => 'Ὡ',
664
+ 'ὢ' => 'Ὢ',
665
+ 'ὣ' => 'Ὣ',
666
+ 'ὤ' => 'Ὤ',
667
+ 'ὥ' => 'Ὥ',
668
+ 'ὦ' => 'Ὦ',
669
+ 'ὧ' => 'Ὧ',
670
+ 'ὰ' => 'Ὰ',
671
+ 'ά' => 'Ά',
672
+ 'ὲ' => 'Ὲ',
673
+ 'έ' => 'Έ',
674
+ 'ὴ' => 'Ὴ',
675
+ 'ή' => 'Ή',
676
+ 'ὶ' => 'Ὶ',
677
+ 'ί' => 'Ί',
678
+ 'ὸ' => 'Ὸ',
679
+ 'ό' => 'Ό',
680
+ 'ὺ' => 'Ὺ',
681
+ 'ύ' => 'Ύ',
682
+ 'ὼ' => 'Ὼ',
683
+ 'ώ' => 'Ώ',
684
+ 'ᾀ' => 'ᾈ',
685
+ 'ᾁ' => 'ᾉ',
686
+ 'ᾂ' => 'ᾊ',
687
+ 'ᾃ' => 'ᾋ',
688
+ 'ᾄ' => 'ᾌ',
689
+ 'ᾅ' => 'ᾍ',
690
+ 'ᾆ' => 'ᾎ',
691
+ 'ᾇ' => 'ᾏ',
692
+ 'ᾐ' => 'ᾘ',
693
+ 'ᾑ' => 'ᾙ',
694
+ 'ᾒ' => 'ᾚ',
695
+ 'ᾓ' => 'ᾛ',
696
+ 'ᾔ' => 'ᾜ',
697
+ 'ᾕ' => 'ᾝ',
698
+ 'ᾖ' => 'ᾞ',
699
+ 'ᾗ' => 'ᾟ',
700
+ 'ᾠ' => 'ᾨ',
701
+ 'ᾡ' => 'ᾩ',
702
+ 'ᾢ' => 'ᾪ',
703
+ 'ᾣ' => 'ᾫ',
704
+ 'ᾤ' => 'ᾬ',
705
+ 'ᾥ' => 'ᾭ',
706
+ 'ᾦ' => 'ᾮ',
707
+ 'ᾧ' => 'ᾯ',
708
+ 'ᾰ' => 'Ᾰ',
709
+ 'ᾱ' => 'Ᾱ',
710
+ 'ᾳ' => 'ᾼ',
711
+ 'ι' => 'Ι',
712
+ 'ῃ' => 'ῌ',
713
+ 'ῐ' => 'Ῐ',
714
+ 'ῑ' => 'Ῑ',
715
+ 'ῠ' => 'Ῠ',
716
+ 'ῡ' => 'Ῡ',
717
+ 'ῥ' => 'Ῥ',
718
+ 'ῳ' => 'ῼ',
719
+ 'ⅎ' => 'Ⅎ',
720
+ 'ⅰ' => 'Ⅰ',
721
+ 'ⅱ' => 'Ⅱ',
722
+ 'ⅲ' => 'Ⅲ',
723
+ 'ⅳ' => 'Ⅳ',
724
+ 'ⅴ' => 'Ⅴ',
725
+ 'ⅵ' => 'Ⅵ',
726
+ 'ⅶ' => 'Ⅶ',
727
+ 'ⅷ' => 'Ⅷ',
728
+ 'ⅸ' => 'Ⅸ',
729
+ 'ⅹ' => 'Ⅹ',
730
+ 'ⅺ' => 'Ⅺ',
731
+ 'ⅻ' => 'Ⅻ',
732
+ 'ⅼ' => 'Ⅼ',
733
+ 'ⅽ' => 'Ⅽ',
734
+ 'ⅾ' => 'Ⅾ',
735
+ 'ⅿ' => 'Ⅿ',
736
+ 'ↄ' => 'Ↄ',
737
+ 'ⓐ' => 'Ⓐ',
738
+ 'ⓑ' => 'Ⓑ',
739
+ 'ⓒ' => 'Ⓒ',
740
+ 'ⓓ' => 'Ⓓ',
741
+ 'ⓔ' => 'Ⓔ',
742
+ 'ⓕ' => 'Ⓕ',
743
+ 'ⓖ' => 'Ⓖ',
744
+ 'ⓗ' => 'Ⓗ',
745
+ 'ⓘ' => 'Ⓘ',
746
+ 'ⓙ' => 'Ⓙ',
747
+ 'ⓚ' => 'Ⓚ',
748
+ 'ⓛ' => 'Ⓛ',
749
+ 'ⓜ' => 'Ⓜ',
750
+ 'ⓝ' => 'Ⓝ',
751
+ 'ⓞ' => 'Ⓞ',
752
+ 'ⓟ' => 'Ⓟ',
753
+ 'ⓠ' => 'Ⓠ',
754
+ 'ⓡ' => 'Ⓡ',
755
+ 'ⓢ' => 'Ⓢ',
756
+ 'ⓣ' => 'Ⓣ',
757
+ 'ⓤ' => 'Ⓤ',
758
+ 'ⓥ' => 'Ⓥ',
759
+ 'ⓦ' => 'Ⓦ',
760
+ 'ⓧ' => 'Ⓧ',
761
+ 'ⓨ' => 'Ⓨ',
762
+ 'ⓩ' => 'Ⓩ',
763
+ 'ⰰ' => 'Ⰰ',
764
+ 'ⰱ' => 'Ⰱ',
765
+ 'ⰲ' => 'Ⰲ',
766
+ 'ⰳ' => 'Ⰳ',
767
+ 'ⰴ' => 'Ⰴ',
768
+ 'ⰵ' => 'Ⰵ',
769
+ 'ⰶ' => 'Ⰶ',
770
+ 'ⰷ' => 'Ⰷ',
771
+ 'ⰸ' => 'Ⰸ',
772
+ 'ⰹ' => 'Ⰹ',
773
+ 'ⰺ' => 'Ⰺ',
774
+ 'ⰻ' => 'Ⰻ',
775
+ 'ⰼ' => 'Ⰼ',
776
+ 'ⰽ' => 'Ⰽ',
777
+ 'ⰾ' => 'Ⰾ',
778
+ 'ⰿ' => 'Ⰿ',
779
+ 'ⱀ' => 'Ⱀ',
780
+ 'ⱁ' => 'Ⱁ',
781
+ 'ⱂ' => 'Ⱂ',
782
+ 'ⱃ' => 'Ⱃ',
783
+ 'ⱄ' => 'Ⱄ',
784
+ 'ⱅ' => 'Ⱅ',
785
+ 'ⱆ' => 'Ⱆ',
786
+ 'ⱇ' => 'Ⱇ',
787
+ 'ⱈ' => 'Ⱈ',
788
+ 'ⱉ' => 'Ⱉ',
789
+ 'ⱊ' => 'Ⱊ',
790
+ 'ⱋ' => 'Ⱋ',
791
+ 'ⱌ' => 'Ⱌ',
792
+ 'ⱍ' => 'Ⱍ',
793
+ 'ⱎ' => 'Ⱎ',
794
+ 'ⱏ' => 'Ⱏ',
795
+ 'ⱐ' => 'Ⱐ',
796
+ 'ⱑ' => 'Ⱑ',
797
+ 'ⱒ' => 'Ⱒ',
798
+ 'ⱓ' => 'Ⱓ',
799
+ 'ⱔ' => 'Ⱔ',
800
+ 'ⱕ' => 'Ⱕ',
801
+ 'ⱖ' => 'Ⱖ',
802
+ 'ⱗ' => 'Ⱗ',
803
+ 'ⱘ' => 'Ⱘ',
804
+ 'ⱙ' => 'Ⱙ',
805
+ 'ⱚ' => 'Ⱚ',
806
+ 'ⱛ' => 'Ⱛ',
807
+ 'ⱜ' => 'Ⱜ',
808
+ 'ⱝ' => 'Ⱝ',
809
+ 'ⱞ' => 'Ⱞ',
810
+ 'ⱡ' => 'Ⱡ',
811
+ 'ⱥ' => 'Ⱥ',
812
+ 'ⱦ' => 'Ⱦ',
813
+ 'ⱨ' => 'Ⱨ',
814
+ 'ⱪ' => 'Ⱪ',
815
+ 'ⱬ' => 'Ⱬ',
816
+ 'ⱳ' => 'Ⱳ',
817
+ 'ⱶ' => 'Ⱶ',
818
+ 'ⲁ' => 'Ⲁ',
819
+ 'ⲃ' => 'Ⲃ',
820
+ 'ⲅ' => 'Ⲅ',
821
+ 'ⲇ' => 'Ⲇ',
822
+ 'ⲉ' => 'Ⲉ',
823
+ 'ⲋ' => 'Ⲋ',
824
+ 'ⲍ' => 'Ⲍ',
825
+ 'ⲏ' => 'Ⲏ',
826
+ 'ⲑ' => 'Ⲑ',
827
+ 'ⲓ' => 'Ⲓ',
828
+ 'ⲕ' => 'Ⲕ',
829
+ 'ⲗ' => 'Ⲗ',
830
+ 'ⲙ' => 'Ⲙ',
831
+ 'ⲛ' => 'Ⲛ',
832
+ 'ⲝ' => 'Ⲝ',
833
+ 'ⲟ' => 'Ⲟ',
834
+ 'ⲡ' => 'Ⲡ',
835
+ 'ⲣ' => 'Ⲣ',
836
+ 'ⲥ' => 'Ⲥ',
837
+ 'ⲧ' => 'Ⲧ',
838
+ 'ⲩ' => 'Ⲩ',
839
+ 'ⲫ' => 'Ⲫ',
840
+ 'ⲭ' => 'Ⲭ',
841
+ 'ⲯ' => 'Ⲯ',
842
+ 'ⲱ' => 'Ⲱ',
843
+ 'ⲳ' => 'Ⲳ',
844
+ 'ⲵ' => 'Ⲵ',
845
+ 'ⲷ' => 'Ⲷ',
846
+ 'ⲹ' => 'Ⲹ',
847
+ 'ⲻ' => 'Ⲻ',
848
+ 'ⲽ' => 'Ⲽ',
849
+ 'ⲿ' => 'Ⲿ',
850
+ 'ⳁ' => 'Ⳁ',
851
+ 'ⳃ' => 'Ⳃ',
852
+ 'ⳅ' => 'Ⳅ',
853
+ 'ⳇ' => 'Ⳇ',
854
+ 'ⳉ' => 'Ⳉ',
855
+ 'ⳋ' => 'Ⳋ',
856
+ 'ⳍ' => 'Ⳍ',
857
+ 'ⳏ' => 'Ⳏ',
858
+ 'ⳑ' => 'Ⳑ',
859
+ 'ⳓ' => 'Ⳓ',
860
+ 'ⳕ' => 'Ⳕ',
861
+ 'ⳗ' => 'Ⳗ',
862
+ 'ⳙ' => 'Ⳙ',
863
+ 'ⳛ' => 'Ⳛ',
864
+ 'ⳝ' => 'Ⳝ',
865
+ 'ⳟ' => 'Ⳟ',
866
+ 'ⳡ' => 'Ⳡ',
867
+ 'ⳣ' => 'Ⳣ',
868
+ 'ⳬ' => 'Ⳬ',
869
+ 'ⳮ' => 'Ⳮ',
870
+ 'ⳳ' => 'Ⳳ',
871
+ 'ⴀ' => 'Ⴀ',
872
+ 'ⴁ' => 'Ⴁ',
873
+ 'ⴂ' => 'Ⴂ',
874
+ 'ⴃ' => 'Ⴃ',
875
+ 'ⴄ' => 'Ⴄ',
876
+ 'ⴅ' => 'Ⴅ',
877
+ 'ⴆ' => 'Ⴆ',
878
+ 'ⴇ' => 'Ⴇ',
879
+ 'ⴈ' => 'Ⴈ',
880
+ 'ⴉ' => 'Ⴉ',
881
+ 'ⴊ' => 'Ⴊ',
882
+ 'ⴋ' => 'Ⴋ',
883
+ 'ⴌ' => 'Ⴌ',
884
+ 'ⴍ' => 'Ⴍ',
885
+ 'ⴎ' => 'Ⴎ',
886
+ 'ⴏ' => 'Ⴏ',
887
+ 'ⴐ' => 'Ⴐ',
888
+ 'ⴑ' => 'Ⴑ',
889
+ 'ⴒ' => 'Ⴒ',
890
+ 'ⴓ' => 'Ⴓ',
891
+ 'ⴔ' => 'Ⴔ',
892
+ 'ⴕ' => 'Ⴕ',
893
+ 'ⴖ' => 'Ⴖ',
894
+ 'ⴗ' => 'Ⴗ',
895
+ 'ⴘ' => 'Ⴘ',
896
+ 'ⴙ' => 'Ⴙ',
897
+ 'ⴚ' => 'Ⴚ',
898
+ 'ⴛ' => 'Ⴛ',
899
+ 'ⴜ' => 'Ⴜ',
900
+ 'ⴝ' => 'Ⴝ',
901
+ 'ⴞ' => 'Ⴞ',
902
+ 'ⴟ' => 'Ⴟ',
903
+ 'ⴠ' => 'Ⴠ',
904
+ 'ⴡ' => 'Ⴡ',
905
+ 'ⴢ' => 'Ⴢ',
906
+ 'ⴣ' => 'Ⴣ',
907
+ 'ⴤ' => 'Ⴤ',
908
+ 'ⴥ' => 'Ⴥ',
909
+ 'ⴧ' => 'Ⴧ',
910
+ 'ⴭ' => 'Ⴭ',
911
+ 'ꙁ' => 'Ꙁ',
912
+ 'ꙃ' => 'Ꙃ',
913
+ 'ꙅ' => 'Ꙅ',
914
+ 'ꙇ' => 'Ꙇ',
915
+ 'ꙉ' => 'Ꙉ',
916
+ 'ꙋ' => 'Ꙋ',
917
+ 'ꙍ' => 'Ꙍ',
918
+ 'ꙏ' => 'Ꙏ',
919
+ 'ꙑ' => 'Ꙑ',
920
+ 'ꙓ' => 'Ꙓ',
921
+ 'ꙕ' => 'Ꙕ',
922
+ 'ꙗ' => 'Ꙗ',
923
+ 'ꙙ' => 'Ꙙ',
924
+ 'ꙛ' => 'Ꙛ',
925
+ 'ꙝ' => 'Ꙝ',
926
+ 'ꙟ' => 'Ꙟ',
927
+ 'ꙡ' => 'Ꙡ',
928
+ 'ꙣ' => 'Ꙣ',
929
+ 'ꙥ' => 'Ꙥ',
930
+ 'ꙧ' => 'Ꙧ',
931
+ 'ꙩ' => 'Ꙩ',
932
+ 'ꙫ' => 'Ꙫ',
933
+ 'ꙭ' => 'Ꙭ',
934
+ 'ꚁ' => 'Ꚁ',
935
+ 'ꚃ' => 'Ꚃ',
936
+ 'ꚅ' => 'Ꚅ',
937
+ 'ꚇ' => 'Ꚇ',
938
+ 'ꚉ' => 'Ꚉ',
939
+ 'ꚋ' => 'Ꚋ',
940
+ 'ꚍ' => 'Ꚍ',
941
+ 'ꚏ' => 'Ꚏ',
942
+ 'ꚑ' => 'Ꚑ',
943
+ 'ꚓ' => 'Ꚓ',
944
+ 'ꚕ' => 'Ꚕ',
945
+ 'ꚗ' => 'Ꚗ',
946
+ 'ꚙ' => 'Ꚙ',
947
+ 'ꚛ' => 'Ꚛ',
948
+ 'ꜣ' => 'Ꜣ',
949
+ 'ꜥ' => 'Ꜥ',
950
+ 'ꜧ' => 'Ꜧ',
951
+ 'ꜩ' => 'Ꜩ',
952
+ 'ꜫ' => 'Ꜫ',
953
+ 'ꜭ' => 'Ꜭ',
954
+ 'ꜯ' => 'Ꜯ',
955
+ 'ꜳ' => 'Ꜳ',
956
+ 'ꜵ' => 'Ꜵ',
957
+ 'ꜷ' => 'Ꜷ',
958
+ 'ꜹ' => 'Ꜹ',
959
+ 'ꜻ' => 'Ꜻ',
960
+ 'ꜽ' => 'Ꜽ',
961
+ 'ꜿ' => 'Ꜿ',
962
+ 'ꝁ' => 'Ꝁ',
963
+ 'ꝃ' => 'Ꝃ',
964
+ 'ꝅ' => 'Ꝅ',
965
+ 'ꝇ' => 'Ꝇ',
966
+ 'ꝉ' => 'Ꝉ',
967
+ 'ꝋ' => 'Ꝋ',
968
+ 'ꝍ' => 'Ꝍ',
969
+ 'ꝏ' => 'Ꝏ',
970
+ 'ꝑ' => 'Ꝑ',
971
+ 'ꝓ' => 'Ꝓ',
972
+ 'ꝕ' => 'Ꝕ',
973
+ 'ꝗ' => 'Ꝗ',
974
+ 'ꝙ' => 'Ꝙ',
975
+ 'ꝛ' => 'Ꝛ',
976
+ 'ꝝ' => 'Ꝝ',
977
+ 'ꝟ' => 'Ꝟ',
978
+ 'ꝡ' => 'Ꝡ',
979
+ 'ꝣ' => 'Ꝣ',
980
+ 'ꝥ' => 'Ꝥ',
981
+ 'ꝧ' => 'Ꝧ',
982
+ 'ꝩ' => 'Ꝩ',
983
+ 'ꝫ' => 'Ꝫ',
984
+ 'ꝭ' => 'Ꝭ',
985
+ 'ꝯ' => 'Ꝯ',
986
+ 'ꝺ' => 'Ꝺ',
987
+ 'ꝼ' => 'Ꝼ',
988
+ 'ꝿ' => 'Ꝿ',
989
+ 'ꞁ' => 'Ꞁ',
990
+ 'ꞃ' => 'Ꞃ',
991
+ 'ꞅ' => 'Ꞅ',
992
+ 'ꞇ' => 'Ꞇ',
993
+ 'ꞌ' => 'Ꞌ',
994
+ 'ꞑ' => 'Ꞑ',
995
+ 'ꞓ' => 'Ꞓ',
996
+ 'ꞗ' => 'Ꞗ',
997
+ 'ꞙ' => 'Ꞙ',
998
+ 'ꞛ' => 'Ꞛ',
999
+ 'ꞝ' => 'Ꞝ',
1000
+ 'ꞟ' => 'Ꞟ',
1001
+ 'ꞡ' => 'Ꞡ',
1002
+ 'ꞣ' => 'Ꞣ',
1003
+ 'ꞥ' => 'Ꞥ',
1004
+ 'ꞧ' => 'Ꞧ',
1005
+ 'ꞩ' => 'Ꞩ',
1006
+ 'a' => 'A',
1007
+ 'b' => 'B',
1008
+ 'c' => 'C',
1009
+ 'd' => 'D',
1010
+ 'e' => 'E',
1011
+ 'f' => 'F',
1012
+ 'g' => 'G',
1013
+ 'h' => 'H',
1014
+ 'i' => 'I',
1015
+ 'j' => 'J',
1016
+ 'k' => 'K',
1017
+ 'l' => 'L',
1018
+ 'm' => 'M',
1019
+ 'n' => 'N',
1020
+ 'o' => 'O',
1021
+ 'p' => 'P',
1022
+ 'q' => 'Q',
1023
+ 'r' => 'R',
1024
+ 's' => 'S',
1025
+ 't' => 'T',
1026
+ 'u' => 'U',
1027
+ 'v' => 'V',
1028
+ 'w' => 'W',
1029
+ 'x' => 'X',
1030
+ 'y' => 'Y',
1031
+ 'z' => 'Z',
1032
+ '𐐨' => '𐐀',
1033
+ '𐐩' => '𐐁',
1034
+ '𐐪' => '𐐂',
1035
+ '𐐫' => '𐐃',
1036
+ '𐐬' => '𐐄',
1037
+ '𐐭' => '𐐅',
1038
+ '𐐮' => '𐐆',
1039
+ '𐐯' => '𐐇',
1040
+ '𐐰' => '𐐈',
1041
+ '𐐱' => '𐐉',
1042
+ '𐐲' => '𐐊',
1043
+ '𐐳' => '𐐋',
1044
+ '𐐴' => '𐐌',
1045
+ '𐐵' => '𐐍',
1046
+ '𐐶' => '𐐎',
1047
+ '𐐷' => '𐐏',
1048
+ '𐐸' => '𐐐',
1049
+ '𐐹' => '𐐑',
1050
+ '𐐺' => '𐐒',
1051
+ '𐐻' => '𐐓',
1052
+ '𐐼' => '𐐔',
1053
+ '𐐽' => '𐐕',
1054
+ '𐐾' => '𐐖',
1055
+ '𐐿' => '𐐗',
1056
+ '𐑀' => '𐐘',
1057
+ '𐑁' => '𐐙',
1058
+ '𐑂' => '𐐚',
1059
+ '𐑃' => '𐐛',
1060
+ '𐑄' => '𐐜',
1061
+ '𐑅' => '𐐝',
1062
+ '𐑆' => '𐐞',
1063
+ '𐑇' => '𐐟',
1064
+ '𐑈' => '𐐠',
1065
+ '𐑉' => '𐐡',
1066
+ '𐑊' => '𐐢',
1067
+ '𐑋' => '𐐣',
1068
+ '𐑌' => '𐐤',
1069
+ '𐑍' => '𐐥',
1070
+ '𐑎' => '𐐦',
1071
+ '𐑏' => '𐐧',
1072
+ '𑣀' => '𑢠',
1073
+ '𑣁' => '𑢡',
1074
+ '𑣂' => '𑢢',
1075
+ '𑣃' => '𑢣',
1076
+ '𑣄' => '𑢤',
1077
+ '𑣅' => '𑢥',
1078
+ '𑣆' => '𑢦',
1079
+ '𑣇' => '𑢧',
1080
+ '𑣈' => '𑢨',
1081
+ '𑣉' => '𑢩',
1082
+ '𑣊' => '𑢪',
1083
+ '𑣋' => '𑢫',
1084
+ '𑣌' => '𑢬',
1085
+ '𑣍' => '𑢭',
1086
+ '𑣎' => '𑢮',
1087
+ '𑣏' => '𑢯',
1088
+ '𑣐' => '𑢰',
1089
+ '𑣑' => '𑢱',
1090
+ '𑣒' => '𑢲',
1091
+ '𑣓' => '𑢳',
1092
+ '𑣔' => '𑢴',
1093
+ '𑣕' => '𑢵',
1094
+ '𑣖' => '𑢶',
1095
+ '𑣗' => '𑢷',
1096
+ '𑣘' => '𑢸',
1097
+ '𑣙' => '𑢹',
1098
+ '𑣚' => '𑢺',
1099
+ '𑣛' => '𑢻',
1100
+ '𑣜' => '𑢼',
1101
+ '𑣝' => '𑢽',
1102
+ '𑣞' => '𑢾',
1103
+ '𑣟' => '𑢿',
1104
+ );
1105
+
1106
+ $result =& $data;
1107
+ unset($data);
1108
+
1109
+ return $result;
app/vendor/symfony/polyfill-mbstring/bootstrap.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ use Symfony\Polyfill\Mbstring as p;
13
+
14
+ if (!function_exists('mb_strlen')) {
15
+ define('MB_CASE_UPPER', 0);
16
+ define('MB_CASE_LOWER', 1);
17
+ define('MB_CASE_TITLE', 2);
18
+
19
+ function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
20
+ function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
21
+ function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
22
+ function mb_decode_numericentity($s, $convmap, $enc = null) { return p\Mbstring::mb_decode_numericentity($s, $convmap, $enc); }
23
+ function mb_encode_numericentity($s, $convmap, $enc = null, $is_hex = false) { return p\Mbstring::mb_encode_numericentity($s, $convmap, $enc, $is_hex); }
24
+ function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
25
+ function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
26
+ function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
27
+ function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
28
+ function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
29
+ function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
30
+ function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
31
+ function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
32
+ function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
33
+ function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
34
+ function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
35
+ function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
36
+ function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
37
+ function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
38
+ function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
39
+ function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
40
+ function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
41
+ function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
42
+ function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
43
+ function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
44
+ function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
45
+ function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
46
+ function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
47
+ function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
48
+ function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
49
+ function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
50
+ function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
51
+ function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
52
+ function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
53
+ }
54
+ if (!function_exists('mb_chr')) {
55
+ function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
56
+ function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
57
+ function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
58
+ }
app/vendor/symfony/polyfill-mbstring/composer.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "symfony/polyfill-mbstring",
3
+ "type": "library",
4
+ "description": "Symfony polyfill for the Mbstring extension",
5
+ "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
6
+ "homepage": "https://symfony.com",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Nicolas Grekas",
11
+ "email": "p@tchwork.com"
12
+ },
13
+ {
14
+ "name": "Symfony Community",
15
+ "homepage": "https://symfony.com/contributors"
16
+ }
17
+ ],
18
+ "require": {
19
+ "php": ">=5.3.3"
20
+ },
21
+ "autoload": {
22
+ "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
23
+ "files": [ "bootstrap.php" ]
24
+ },
25
+ "suggest": {
26
+ "ext-mbstring": "For best performance"
27
+ },
28
+ "minimum-stability": "dev",
29
+ "extra": {
30
+ "branch-alias": {
31
+ "dev-master": "1.8-dev"
32
+ }
33
+ }
34
+ }
app/vendor/symfony/translation/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ vendor/
2
+ composer.lock
3
+ phpunit.xml
app/vendor/symfony/translation/CHANGELOG.md ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CHANGELOG
2
+ =========
3
+
4
+ 4.1.0
5
+ -----
6
+
7
+ * The `FileDumper::setBackup()` method is deprecated.
8
+ * The `TranslationWriter::disableBackup()` method is deprecated.
9
+ * The `XliffFileDumper` will write "name" on the "unit" node when dumping XLIFF 2.0.
10
+
11
+ 4.0.0
12
+ -----
13
+
14
+ * removed the backup feature of the `FileDumper` class
15
+ * removed `TranslationWriter::writeTranslations()` method
16
+ * removed support for passing `MessageSelector` instances to the constructor of the `Translator` class
17
+
18
+ 3.4.0
19
+ -----
20
+
21
+ * Added `TranslationDumperPass`
22
+ * Added `TranslationExtractorPass`
23
+ * Added `TranslatorPass`
24
+ * Added `TranslationReader` and `TranslationReaderInterface`
25
+ * Added `<notes>` section to the Xliff 2.0 dumper.
26
+ * Improved Xliff 2.0 loader to load `<notes>` section.
27
+ * Added `TranslationWriterInterface`
28
+ * Deprecated `TranslationWriter::writeTranslations` in favor of `TranslationWriter::write`
29
+ * added support for adding custom message formatter and decoupling the default one.
30
+ * Added `PhpExtractor`
31
+ * Added `PhpStringTokenParser`
32
+
33
+ 3.2.0
34
+ -----
35
+
36
+ * Added support for escaping `|` in plural translations with double pipe.
37
+
38
+ 3.1.0
39
+ -----
40
+
41
+ * Deprecated the backup feature of the file dumper classes.
42
+
43
+ 3.0.0
44
+ -----
45
+
46
+ * removed `FileDumper::format()` method.
47
+ * Changed the visibility of the locale property in `Translator` from protected to private.
48
+
49
+ 2.8.0
50
+ -----
51
+
52
+ * deprecated FileDumper::format(), overwrite FileDumper::formatCatalogue() instead.
53
+ * deprecated Translator::getMessages(), rely on TranslatorBagInterface::getCatalogue() instead.
54
+ * added `FileDumper::formatCatalogue` which allows format the catalogue without dumping it into file.
55
+ * added option `json_encoding` to JsonFileDumper
56
+ * added options `as_tree`, `inline` to YamlFileDumper
57
+ * added support for XLIFF 2.0.
58
+ * added support for XLIFF target and tool attributes.
59
+ * added message parameters to DataCollectorTranslator.
60
+ * [DEPRECATION] The `DiffOperation` class has been deprecated and
61
+ will be removed in Symfony 3.0, since its operation has nothing to do with 'diff',
62
+ so the class name is misleading. The `TargetOperation` class should be used for
63
+ this use-case instead.
64
+
65
+ 2.7.0
66
+ -----
67
+
68
+ * added DataCollectorTranslator for collecting the translated messages.
69
+
70
+ 2.6.0
71
+ -----
72
+
73
+ * added possibility to cache catalogues
74
+ * added TranslatorBagInterface
75
+ * added LoggingTranslator
76
+ * added Translator::getMessages() for retrieving the message catalogue as an array
77
+
78
+ 2.5.0
79
+ -----
80
+
81
+ * added relative file path template to the file dumpers
82
+ * added optional backup to the file dumpers
83
+ * changed IcuResFileDumper to extend FileDumper
84
+
85
+ 2.3.0
86
+ -----
87
+
88
+ * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
89
+ * added Translator::getFallbackLocales()
90
+ * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method
91
+
92
+ 2.2.0
93
+ -----
94
+
95
+ * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
96
+ * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
97
+ throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
98
+ and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
99
+ * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
100
+ (IcuDatFileLoader, IcuResFileLoader and QtFileLoader)
101
+
102
+ 2.1.0
103
+ -----
104
+
105
+ * added support for more than one fallback locale
106
+ * added support for extracting translation messages from templates (Twig and PHP)
107
+ * added dumpers for translation catalogs
108
+ * added support for QT, gettext, and ResourceBundles
app/vendor/symfony/translation/Catalogue/AbstractOperation.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Catalogue;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\MessageCatalogueInterface;
16
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
17
+ use Symfony\Component\Translation\Exception\LogicException;
18
+
19
+ /**
20
+ * Base catalogues binary operation class.
21
+ *
22
+ * A catalogue binary operation performs operation on
23
+ * source (the left argument) and target (the right argument) catalogues.
24
+ *
25
+ * @author Jean-François Simon <contact@jfsimon.fr>
26
+ */
27
+ abstract class AbstractOperation implements OperationInterface
28
+ {
29
+ protected $source;
30
+ protected $target;
31
+ protected $result;
32
+
33
+ /**
34
+ * @var null|array The domains affected by this operation
35
+ */
36
+ private $domains;
37
+
38
+ /**
39
+ * This array stores 'all', 'new' and 'obsolete' messages for all valid domains.
40
+ *
41
+ * The data structure of this array is as follows:
42
+ * ```php
43
+ * array(
44
+ * 'domain 1' => array(
45
+ * 'all' => array(...),
46
+ * 'new' => array(...),
47
+ * 'obsolete' => array(...)
48
+ * ),
49
+ * 'domain 2' => array(
50
+ * 'all' => array(...),
51
+ * 'new' => array(...),
52
+ * 'obsolete' => array(...)
53
+ * ),
54
+ * ...
55
+ * )
56
+ * ```
57
+ *
58
+ * @var array The array that stores 'all', 'new' and 'obsolete' messages
59
+ */
60
+ protected $messages;
61
+
62
+ /**
63
+ * @throws LogicException
64
+ */
65
+ public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
66
+ {
67
+ if ($source->getLocale() !== $target->getLocale()) {
68
+ throw new LogicException('Operated catalogues must belong to the same locale.');
69
+ }
70
+
71
+ $this->source = $source;
72
+ $this->target = $target;
73
+ $this->result = new MessageCatalogue($source->getLocale());
74
+ $this->messages = array();
75
+ }
76
+
77
+ /**
78
+ * {@inheritdoc}
79
+ */
80
+ public function getDomains()
81
+ {
82
+ if (null === $this->domains) {
83
+ $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
84
+ }
85
+
86
+ return $this->domains;
87
+ }
88
+
89
+ /**
90
+ * {@inheritdoc}
91
+ */
92
+ public function getMessages($domain)
93
+ {
94
+ if (!in_array($domain, $this->getDomains())) {
95
+ throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
96
+ }
97
+
98
+ if (!isset($this->messages[$domain]['all'])) {
99
+ $this->processDomain($domain);
100
+ }
101
+
102
+ return $this->messages[$domain]['all'];
103
+ }
104
+
105
+ /**
106
+ * {@inheritdoc}
107
+ */
108
+ public function getNewMessages($domain)
109
+ {
110
+ if (!in_array($domain, $this->getDomains())) {
111
+ throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
112
+ }
113
+
114
+ if (!isset($this->messages[$domain]['new'])) {
115
+ $this->processDomain($domain);
116
+ }
117
+
118
+ return $this->messages[$domain]['new'];
119
+ }
120
+
121
+ /**
122
+ * {@inheritdoc}
123
+ */
124
+ public function getObsoleteMessages($domain)
125
+ {
126
+ if (!in_array($domain, $this->getDomains())) {
127
+ throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
128
+ }
129
+
130
+ if (!isset($this->messages[$domain]['obsolete'])) {
131
+ $this->processDomain($domain);
132
+ }
133
+
134
+ return $this->messages[$domain]['obsolete'];
135
+ }
136
+
137
+ /**
138
+ * {@inheritdoc}
139
+ */
140
+ public function getResult()
141
+ {
142
+ foreach ($this->getDomains() as $domain) {
143
+ if (!isset($this->messages[$domain])) {
144
+ $this->processDomain($domain);
145
+ }
146
+ }
147
+
148
+ return $this->result;
149
+ }
150
+
151
+ /**
152
+ * Performs operation on source and target catalogues for the given domain and
153
+ * stores the results.
154
+ *
155
+ * @param string $domain The domain which the operation will be performed for
156
+ */
157
+ abstract protected function processDomain($domain);
158
+ }
app/vendor/symfony/translation/Catalogue/MergeOperation.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Catalogue;
13
+
14
+ /**
15
+ * Merge operation between two catalogues as follows:
16
+ * all = source ∪ target = {x: x ∈ source ∨ x ∈ target}
17
+ * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
18
+ * obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ source ∧ x ∉ target} = ∅
19
+ * Basically, the result contains messages from both catalogues.
20
+ *
21
+ * @author Jean-François Simon <contact@jfsimon.fr>
22
+ */
23
+ class MergeOperation extends AbstractOperation
24
+ {
25
+ /**
26
+ * {@inheritdoc}
27
+ */
28
+ protected function processDomain($domain)
29
+ {
30
+ $this->messages[$domain] = array(
31
+ 'all' => array(),
32
+ 'new' => array(),
33
+ 'obsolete' => array(),
34
+ );
35
+
36
+ foreach ($this->source->all($domain) as $id => $message) {
37
+ $this->messages[$domain]['all'][$id] = $message;
38
+ $this->result->add(array($id => $message), $domain);
39
+ if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
40
+ $this->result->setMetadata($id, $keyMetadata, $domain);
41
+ }
42
+ }
43
+
44
+ foreach ($this->target->all($domain) as $id => $message) {
45
+ if (!$this->source->has($id, $domain)) {
46
+ $this->messages[$domain]['all'][$id] = $message;
47
+ $this->messages[$domain]['new'][$id] = $message;
48
+ $this->result->add(array($id => $message), $domain);
49
+ if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
50
+ $this->result->setMetadata($id, $keyMetadata, $domain);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
app/vendor/symfony/translation/Catalogue/OperationInterface.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Catalogue;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogueInterface;
15
+
16
+ /**
17
+ * Represents an operation on catalogue(s).
18
+ *
19
+ * An instance of this interface performs an operation on one or more catalogues and
20
+ * stores intermediate and final results of the operation.
21
+ *
22
+ * The first catalogue in its argument(s) is called the 'source catalogue' or 'source' and
23
+ * the following results are stored:
24
+ *
25
+ * Messages: also called 'all', are valid messages for the given domain after the operation is performed.
26
+ *
27
+ * New Messages: also called 'new' (new = all ∖ source = {x: x ∈ all ∧ x ∉ source}).
28
+ *
29
+ * Obsolete Messages: also called 'obsolete' (obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ all}).
30
+ *
31
+ * Result: also called 'result', is the resulting catalogue for the given domain that holds the same messages as 'all'.
32
+ *
33
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
34
+ */
35
+ interface OperationInterface
36
+ {
37
+ /**
38
+ * Returns domains affected by operation.
39
+ *
40
+ * @return array
41
+ */
42
+ public function getDomains();
43
+
44
+ /**
45
+ * Returns all valid messages ('all') after operation.
46
+ *
47
+ * @param string $domain
48
+ *
49
+ * @return array
50
+ */
51
+ public function getMessages($domain);
52
+
53
+ /**
54
+ * Returns new messages ('new') after operation.
55
+ *
56
+ * @param string $domain
57
+ *
58
+ * @return array
59
+ */
60
+ public function getNewMessages($domain);
61
+
62
+ /**
63
+ * Returns obsolete messages ('obsolete') after operation.
64
+ *
65
+ * @param string $domain
66
+ *
67
+ * @return array
68
+ */
69
+ public function getObsoleteMessages($domain);
70
+
71
+ /**
72
+ * Returns resulting catalogue ('result').
73
+ *
74
+ * @return MessageCatalogueInterface
75
+ */
76
+ public function getResult();
77
+ }
app/vendor/symfony/translation/Catalogue/TargetOperation.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Catalogue;
13
+
14
+ /**
15
+ * Target operation between two catalogues:
16
+ * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
17
+ * all = intersection ∪ (target ∖ intersection) = target
18
+ * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
19
+ * obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
20
+ * Basically, the result contains messages from the target catalogue.
21
+ *
22
+ * @author Michael Lee <michael.lee@zerustech.com>
23
+ */
24
+ class TargetOperation extends AbstractOperation
25
+ {
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ protected function processDomain($domain)
30
+ {
31
+ $this->messages[$domain] = array(
32
+ 'all' => array(),
33
+ 'new' => array(),
34
+ 'obsolete' => array(),
35
+ );
36
+
37
+ // For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``,
38
+ // because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
39
+ //
40
+ // For 'new' messages, the code can't be simplied as ``array_diff_assoc($this->target->all($domain), $this->source->all($domain));``
41
+ // because doing so will not exclude messages like {x: x ∈ target ∧ x ∉ source.all ∧ x ∈ source.fallback}
42
+ //
43
+ // For 'obsolete' messages, the code can't be simplifed as ``array_diff_assoc($this->source->all($domain), $this->target->all($domain))``
44
+ // because doing so will not exclude messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
45
+
46
+ foreach ($this->source->all($domain) as $id => $message) {
47
+ if ($this->target->has($id, $domain)) {
48
+ $this->messages[$domain]['all'][$id] = $message;
49
+ $this->result->add(array($id => $message), $domain);
50
+ if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
51
+ $this->result->setMetadata($id, $keyMetadata, $domain);
52
+ }
53
+ } else {
54
+ $this->messages[$domain]['obsolete'][$id] = $message;
55
+ }
56
+ }
57
+
58
+ foreach ($this->target->all($domain) as $id => $message) {
59
+ if (!$this->source->has($id, $domain)) {
60
+ $this->messages[$domain]['all'][$id] = $message;
61
+ $this->messages[$domain]['new'][$id] = $message;
62
+ $this->result->add(array($id => $message), $domain);
63
+ if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
64
+ $this->result->setMetadata($id, $keyMetadata, $domain);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
app/vendor/symfony/translation/Command/XliffLintCommand.php ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Command;
13
+
14
+ use Symfony\Component\Console\Command\Command;
15
+ use Symfony\Component\Console\Exception\RuntimeException;
16
+ use Symfony\Component\Console\Input\InputInterface;
17
+ use Symfony\Component\Console\Input\InputOption;
18
+ use Symfony\Component\Console\Output\OutputInterface;
19
+ use Symfony\Component\Console\Style\SymfonyStyle;
20
+
21
+ /**
22
+ * Validates XLIFF files syntax and outputs encountered errors.
23
+ *
24
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
25
+ * @author Robin Chalas <robin.chalas@gmail.com>
26
+ * @author Javier Eguiluz <javier.eguiluz@gmail.com>
27
+ */
28
+ class XliffLintCommand extends Command
29
+ {
30
+ protected static $defaultName = 'lint:xliff';
31
+
32
+ private $format;
33
+ private $displayCorrectFiles;
34
+ private $directoryIteratorProvider;
35
+ private $isReadableProvider;
36
+
37
+ public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null)
38
+ {
39
+ parent::__construct($name);
40
+
41
+ $this->directoryIteratorProvider = $directoryIteratorProvider;
42
+ $this->isReadableProvider = $isReadableProvider;
43
+ }
44
+
45
+ /**
46
+ * {@inheritdoc}
47
+ */
48
+ protected function configure()
49
+ {
50
+ $this
51
+ ->setDescription('Lints a XLIFF file and outputs encountered errors')
52
+ ->addArgument('filename', null, 'A file or a directory or STDIN')
53
+ ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
54
+ ->setHelp(<<<EOF
55
+ The <info>%command.name%</info> command lints a XLIFF file and outputs to STDOUT
56
+ the first encountered syntax error.
57
+
58
+ You can validates XLIFF contents passed from STDIN:
59
+
60
+ <info>cat filename | php %command.full_name%</info>
61
+
62
+ You can also validate the syntax of a file:
63
+
64
+ <info>php %command.full_name% filename</info>
65
+
66
+ Or of a whole directory:
67
+
68
+ <info>php %command.full_name% dirname</info>
69
+ <info>php %command.full_name% dirname --format=json</info>
70
+
71
+ EOF
72
+ )
73
+ ;
74
+ }
75
+
76
+ protected function execute(InputInterface $input, OutputInterface $output)
77
+ {
78
+ $io = new SymfonyStyle($input, $output);
79
+ $filename = $input->getArgument('filename');
80
+ $this->format = $input->getOption('format');
81
+ $this->displayCorrectFiles = $output->isVerbose();
82
+
83
+ if (!$filename) {
84
+ if (!$stdin = $this->getStdin()) {
85
+ throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
86
+ }
87
+
88
+ return $this->display($io, array($this->validate($stdin)));
89
+ }
90
+
91
+ if (!$this->isReadable($filename)) {
92
+ throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
93
+ }
94
+
95
+ $filesInfo = array();
96
+ foreach ($this->getFiles($filename) as $file) {
97
+ $filesInfo[] = $this->validate(file_get_contents($file), $file);
98
+ }
99
+
100
+ return $this->display($io, $filesInfo);
101
+ }
102
+
103
+ private function validate($content, $file = null)
104
+ {
105
+ $errors = array();
106
+
107
+ // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input
108
+ if ('' === trim($content)) {
109
+ return array('file' => $file, 'valid' => true);
110
+ }
111
+
112
+ libxml_use_internal_errors(true);
113
+
114
+ $document = new \DOMDocument();
115
+ $document->loadXML($content);
116
+
117
+ if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
118
+ $expectedFileExtension = sprintf('%s.xlf', str_replace('-', '_', $targetLanguage));
119
+ $realFileExtension = explode('.', basename($file), 2)[1] ?? '';
120
+
121
+ if ($expectedFileExtension !== $realFileExtension) {
122
+ $errors[] = array(
123
+ 'line' => -1,
124
+ 'column' => -1,
125
+ 'message' => sprintf('There is a mismatch between the file extension ("%s") and the "%s" value used in the "target-language" attribute of the file.', $realFileExtension, $targetLanguage),
126
+ );
127
+ }
128
+ }
129
+
130
+ $document->schemaValidate(__DIR__.'/../Resources/schemas/xliff-core-1.2-strict.xsd');
131
+ foreach (libxml_get_errors() as $xmlError) {
132
+ $errors[] = array(
133
+ 'line' => $xmlError->line,
134
+ 'column' => $xmlError->column,
135
+ 'message' => trim($xmlError->message),
136
+ );
137
+ }
138
+
139
+ libxml_clear_errors();
140
+ libxml_use_internal_errors(false);
141
+
142
+ return array('file' => $file, 'valid' => 0 === count($errors), 'messages' => $errors);
143
+ }
144
+
145
+ private function display(SymfonyStyle $io, array $files)
146
+ {
147
+ switch ($this->format) {
148
+ case 'txt':
149
+ return $this->displayTxt($io, $files);
150
+ case 'json':
151
+ return $this->displayJson($io, $files);
152
+ default:
153
+ throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
154
+ }
155
+ }
156
+
157
+ private function displayTxt(SymfonyStyle $io, array $filesInfo)
158
+ {
159
+ $countFiles = count($filesInfo);
160
+ $erroredFiles = 0;
161
+
162
+ foreach ($filesInfo as $info) {
163
+ if ($info['valid'] && $this->displayCorrectFiles) {
164
+ $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
165
+ } elseif (!$info['valid']) {
166
+ ++$erroredFiles;
167
+ $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
168
+ $io->listing(array_map(function ($error) {
169
+ // general document errors have a '-1' line number
170
+ return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
171
+ }, $info['messages']));
172
+ }
173
+ }
174
+
175
+ if (0 === $erroredFiles) {
176
+ $io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
177
+ } else {
178
+ $io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
179
+ }
180
+
181
+ return min($erroredFiles, 1);
182
+ }
183
+
184
+ private function displayJson(SymfonyStyle $io, array $filesInfo)
185
+ {
186
+ $errors = 0;
187
+
188
+ array_walk($filesInfo, function (&$v) use (&$errors) {
189
+ $v['file'] = (string) $v['file'];
190
+ if (!$v['valid']) {
191
+ ++$errors;
192
+ }
193
+ });
194
+
195
+ $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
196
+
197
+ return min($errors, 1);
198
+ }
199
+
200
+ private function getFiles($fileOrDirectory)
201
+ {
202
+ if (is_file($fileOrDirectory)) {
203
+ yield new \SplFileInfo($fileOrDirectory);
204
+
205
+ return;
206
+ }
207
+
208
+ foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
209
+ if (!in_array($file->getExtension(), array('xlf', 'xliff'))) {
210
+ continue;
211
+ }
212
+
213
+ yield $file;
214
+ }
215
+ }
216
+
217
+ private function getStdin()
218
+ {
219
+ if (0 !== ftell(STDIN)) {
220
+ return;
221
+ }
222
+
223
+ $inputs = '';
224
+ while (!feof(STDIN)) {
225
+ $inputs .= fread(STDIN, 1024);
226
+ }
227
+
228
+ return $inputs;
229
+ }
230
+
231
+ private function getDirectoryIterator($directory)
232
+ {
233
+ $default = function ($directory) {
234
+ return new \RecursiveIteratorIterator(
235
+ new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
236
+ \RecursiveIteratorIterator::LEAVES_ONLY
237
+ );
238
+ };
239
+
240
+ if (null !== $this->directoryIteratorProvider) {
241
+ return call_user_func($this->directoryIteratorProvider, $directory, $default);
242
+ }
243
+
244
+ return $default($directory);
245
+ }
246
+
247
+ private function isReadable($fileOrDirectory)
248
+ {
249
+ $default = function ($fileOrDirectory) {
250
+ return is_readable($fileOrDirectory);
251
+ };
252
+
253
+ if (null !== $this->isReadableProvider) {
254
+ return call_user_func($this->isReadableProvider, $fileOrDirectory, $default);
255
+ }
256
+
257
+ return $default($fileOrDirectory);
258
+ }
259
+
260
+ private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string
261
+ {
262
+ foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? array() as $attribute) {
263
+ if ('target-language' === $attribute->nodeName) {
264
+ return $attribute->nodeValue;
265
+ }
266
+ }
267
+
268
+ return null;
269
+ }
270
+ }
app/vendor/symfony/translation/DataCollector/TranslationDataCollector.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\DataCollector;
13
+
14
+ use Symfony\Component\HttpFoundation\Request;
15
+ use Symfony\Component\HttpFoundation\Response;
16
+ use Symfony\Component\HttpKernel\DataCollector\DataCollector;
17
+ use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
18
+ use Symfony\Component\Translation\DataCollectorTranslator;
19
+
20
+ /**
21
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
22
+ */
23
+ class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
24
+ {
25
+ private $translator;
26
+
27
+ public function __construct(DataCollectorTranslator $translator)
28
+ {
29
+ $this->translator = $translator;
30
+ }
31
+
32
+ /**
33
+ * {@inheritdoc}
34
+ */
35
+ public function lateCollect()
36
+ {
37
+ $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());
38
+
39
+ $this->data = $this->computeCount($messages);
40
+ $this->data['messages'] = $messages;
41
+
42
+ $this->data['locale'] = $this->translator->getLocale();
43
+ $this->data['fallback_locales'] = $this->translator->getFallbackLocales();
44
+
45
+ $this->data = $this->cloneVar($this->data);
46
+ }
47
+
48
+ /**
49
+ * {@inheritdoc}
50
+ */
51
+ public function collect(Request $request, Response $response, \Exception $exception = null)
52
+ {
53
+ }
54
+
55
+ /**
56
+ * {@inheritdoc}
57
+ */
58
+ public function reset()
59
+ {
60
+ $this->data = array();
61
+ }
62
+
63
+ /**
64
+ * @return array
65
+ */
66
+ public function getMessages()
67
+ {
68
+ return isset($this->data['messages']) ? $this->data['messages'] : array();
69
+ }
70
+
71
+ /**
72
+ * @return int
73
+ */
74
+ public function getCountMissings()
75
+ {
76
+ return isset($this->data[DataCollectorTranslator::MESSAGE_MISSING]) ? $this->data[DataCollectorTranslator::MESSAGE_MISSING] : 0;
77
+ }
78
+
79
+ /**
80
+ * @return int
81
+ */
82
+ public function getCountFallbacks()
83
+ {
84
+ return isset($this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK]) ? $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] : 0;
85
+ }
86
+
87
+ /**
88
+ * @return int
89
+ */
90
+ public function getCountDefines()
91
+ {
92
+ return isset($this->data[DataCollectorTranslator::MESSAGE_DEFINED]) ? $this->data[DataCollectorTranslator::MESSAGE_DEFINED] : 0;
93
+ }
94
+
95
+ public function getLocale()
96
+ {
97
+ return !empty($this->data['locale']) ? $this->data['locale'] : null;
98
+ }
99
+
100
+ public function getFallbackLocales()
101
+ {
102
+ return (isset($this->data['fallback_locales']) && count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : array();
103
+ }
104
+
105
+ /**
106
+ * {@inheritdoc}
107
+ */
108
+ public function getName()
109
+ {
110
+ return 'translation';
111
+ }
112
+
113
+ private function sanitizeCollectedMessages($messages)
114
+ {
115
+ $result = array();
116
+ foreach ($messages as $key => $message) {
117
+ $messageId = $message['locale'].$message['domain'].$message['id'];
118
+
119
+ if (!isset($result[$messageId])) {
120
+ $message['count'] = 1;
121
+ $message['parameters'] = !empty($message['parameters']) ? array($message['parameters']) : array();
122
+ $messages[$key]['translation'] = $this->sanitizeString($message['translation']);
123
+ $result[$messageId] = $message;
124
+ } else {
125
+ if (!empty($message['parameters'])) {
126
+ $result[$messageId]['parameters'][] = $message['parameters'];
127
+ }
128
+
129
+ ++$result[$messageId]['count'];
130
+ }
131
+
132
+ unset($messages[$key]);
133
+ }
134
+
135
+ return $result;
136
+ }
137
+
138
+ private function computeCount($messages)
139
+ {
140
+ $count = array(
141
+ DataCollectorTranslator::MESSAGE_DEFINED => 0,
142
+ DataCollectorTranslator::MESSAGE_MISSING => 0,
143
+ DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0,
144
+ );
145
+
146
+ foreach ($messages as $message) {
147
+ ++$count[$message['state']];
148
+ }
149
+
150
+ return $count;
151
+ }
152
+
153
+ private function sanitizeString($string, $length = 80)
154
+ {
155
+ $string = trim(preg_replace('/\s+/', ' ', $string));
156
+
157
+ if (false !== $encoding = mb_detect_encoding($string, null, true)) {
158
+ if (mb_strlen($string, $encoding) > $length) {
159
+ return mb_substr($string, 0, $length - 3, $encoding).'...';
160
+ }
161
+ } elseif (strlen($string) > $length) {
162
+ return substr($string, 0, $length - 3).'...';
163
+ }
164
+
165
+ return $string;
166
+ }
167
+ }
app/vendor/symfony/translation/DataCollectorTranslator.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
15
+
16
+ /**
17
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
18
+ */
19
+ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface
20
+ {
21
+ const MESSAGE_DEFINED = 0;
22
+ const MESSAGE_MISSING = 1;
23
+ const MESSAGE_EQUALS_FALLBACK = 2;
24
+
25
+ /**
26
+ * @var TranslatorInterface|TranslatorBagInterface
27
+ */
28
+ private $translator;
29
+
30
+ private $messages = array();
31
+
32
+ /**
33
+ * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
34
+ */
35
+ public function __construct(TranslatorInterface $translator)
36
+ {
37
+ if (!$translator instanceof TranslatorBagInterface) {
38
+ throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator)));
39
+ }
40
+
41
+ $this->translator = $translator;
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
48
+ {
49
+ $trans = $this->translator->trans($id, $parameters, $domain, $locale);
50
+ $this->collectMessage($locale, $domain, $id, $trans, $parameters);
51
+
52
+ return $trans;
53
+ }
54
+
55
+ /**
56
+ * {@inheritdoc}
57
+ */
58
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
59
+ {
60
+ $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
61
+ $this->collectMessage($locale, $domain, $id, $trans, $parameters, $number);
62
+
63
+ return $trans;
64
+ }
65
+
66
+ /**
67
+ * {@inheritdoc}
68
+ */
69
+ public function setLocale($locale)
70
+ {
71
+ $this->translator->setLocale($locale);
72
+ }
73
+
74
+ /**
75
+ * {@inheritdoc}
76
+ */
77
+ public function getLocale()
78
+ {
79
+ return $this->translator->getLocale();
80
+ }
81
+
82
+ /**
83
+ * {@inheritdoc}
84
+ */
85
+ public function getCatalogue($locale = null)
86
+ {
87
+ return $this->translator->getCatalogue($locale);
88
+ }
89
+
90
+ /**
91
+ * Gets the fallback locales.
92
+ *
93
+ * @return array $locales The fallback locales
94
+ */
95
+ public function getFallbackLocales()
96
+ {
97
+ if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
98
+ return $this->translator->getFallbackLocales();
99
+ }
100
+
101
+ return array();
102
+ }
103
+
104
+ /**
105
+ * Passes through all unknown calls onto the translator object.
106
+ */
107
+ public function __call($method, $args)
108
+ {
109
+ return call_user_func_array(array($this->translator, $method), $args);
110
+ }
111
+
112
+ /**
113
+ * @return array
114
+ */
115
+ public function getCollectedMessages()
116
+ {
117
+ return $this->messages;
118
+ }
119
+
120
+ /**
121
+ * @param string|null $locale
122
+ * @param string|null $domain
123
+ * @param string $id
124
+ * @param string $translation
125
+ * @param array|null $parameters
126
+ * @param int|null $number
127
+ */
128
+ private function collectMessage($locale, $domain, $id, $translation, $parameters = array(), $number = null)
129
+ {
130
+ if (null === $domain) {
131
+ $domain = 'messages';
132
+ }
133
+
134
+ $id = (string) $id;
135
+ $catalogue = $this->translator->getCatalogue($locale);
136
+ $locale = $catalogue->getLocale();
137
+ if ($catalogue->defines($id, $domain)) {
138
+ $state = self::MESSAGE_DEFINED;
139
+ } elseif ($catalogue->has($id, $domain)) {
140
+ $state = self::MESSAGE_EQUALS_FALLBACK;
141
+
142
+ $fallbackCatalogue = $catalogue->getFallbackCatalogue();
143
+ while ($fallbackCatalogue) {
144
+ if ($fallbackCatalogue->defines($id, $domain)) {
145
+ $locale = $fallbackCatalogue->getLocale();
146
+ break;
147
+ }
148
+
149
+ $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
150
+ }
151
+ } else {
152
+ $state = self::MESSAGE_MISSING;
153
+ }
154
+
155
+ $this->messages[] = array(
156
+ 'locale' => $locale,
157
+ 'domain' => $domain,
158
+ 'id' => $id,
159
+ 'translation' => $translation,
160
+ 'parameters' => $parameters,
161
+ 'transChoiceNumber' => $number,
162
+ 'state' => $state,
163
+ );
164
+ }
165
+ }
app/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\DependencyInjection;
13
+
14
+ use Symfony\Component\DependencyInjection\Reference;
15
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
16
+ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17
+
18
+ /**
19
+ * Adds tagged translation.formatter services to translation writer.
20
+ */
21
+ class TranslationDumperPass implements CompilerPassInterface
22
+ {
23
+ private $writerServiceId;
24
+ private $dumperTag;
25
+
26
+ public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper')
27
+ {
28
+ $this->writerServiceId = $writerServiceId;
29
+ $this->dumperTag = $dumperTag;
30
+ }
31
+
32
+ public function process(ContainerBuilder $container)
33
+ {
34
+ if (!$container->hasDefinition($this->writerServiceId)) {
35
+ return;
36
+ }
37
+
38
+ $definition = $container->getDefinition($this->writerServiceId);
39
+
40
+ foreach ($container->findTaggedServiceIds($this->dumperTag, true) as $id => $attributes) {
41
+ $definition->addMethodCall('addDumper', array($attributes[0]['alias'], new Reference($id)));
42
+ }
43
+ }
44
+ }
app/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\DependencyInjection;
13
+
14
+ use Symfony\Component\DependencyInjection\Reference;
15
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
16
+ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17
+ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
18
+
19
+ /**
20
+ * Adds tagged translation.extractor services to translation extractor.
21
+ */
22
+ class TranslationExtractorPass implements CompilerPassInterface
23
+ {
24
+ private $extractorServiceId;
25
+ private $extractorTag;
26
+
27
+ public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor')
28
+ {
29
+ $this->extractorServiceId = $extractorServiceId;
30
+ $this->extractorTag = $extractorTag;
31
+ }
32
+
33
+ public function process(ContainerBuilder $container)
34
+ {
35
+ if (!$container->hasDefinition($this->extractorServiceId)) {
36
+ return;
37
+ }
38
+
39
+ $definition = $container->getDefinition($this->extractorServiceId);
40
+
41
+ foreach ($container->findTaggedServiceIds($this->extractorTag, true) as $id => $attributes) {
42
+ if (!isset($attributes[0]['alias'])) {
43
+ throw new RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id));
44
+ }
45
+
46
+ $definition->addMethodCall('addExtractor', array($attributes[0]['alias'], new Reference($id)));
47
+ }
48
+ }
49
+ }
app/vendor/symfony/translation/DependencyInjection/TranslatorPass.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\DependencyInjection;
13
+
14
+ use Symfony\Component\DependencyInjection\Reference;
15
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
16
+ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17
+ use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
18
+
19
+ class TranslatorPass implements CompilerPassInterface
20
+ {
21
+ private $translatorServiceId;
22
+ private $readerServiceId;
23
+ private $loaderTag;
24
+ private $debugCommandServiceId;
25
+ private $updateCommandServiceId;
26
+
27
+ public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update')
28
+ {
29
+ $this->translatorServiceId = $translatorServiceId;
30
+ $this->readerServiceId = $readerServiceId;
31
+ $this->loaderTag = $loaderTag;
32
+ $this->debugCommandServiceId = $debugCommandServiceId;
33
+ $this->updateCommandServiceId = $updateCommandServiceId;
34
+ }
35
+
36
+ public function process(ContainerBuilder $container)
37
+ {
38
+ if (!$container->hasDefinition($this->translatorServiceId)) {
39
+ return;
40
+ }
41
+
42
+ $loaders = array();
43
+ $loaderRefs = array();
44
+ foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
45
+ $loaderRefs[$id] = new Reference($id);
46
+ $loaders[$id][] = $attributes[0]['alias'];
47
+ if (isset($attributes[0]['legacy-alias'])) {
48
+ $loaders[$id][] = $attributes[0]['legacy-alias'];
49
+ }
50
+ }
51
+
52
+ if ($container->hasDefinition($this->readerServiceId)) {
53
+ $definition = $container->getDefinition($this->readerServiceId);
54
+ foreach ($loaders as $id => $formats) {
55
+ foreach ($formats as $format) {
56
+ $definition->addMethodCall('addLoader', array($format, $loaderRefs[$id]));
57
+ }
58
+ }
59
+ }
60
+
61
+ $container
62
+ ->findDefinition($this->translatorServiceId)
63
+ ->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs))
64
+ ->replaceArgument(3, $loaders)
65
+ ;
66
+
67
+ if (!$container->hasParameter('twig.default_path')) {
68
+ return;
69
+ }
70
+
71
+ if ($container->hasDefinition($this->debugCommandServiceId)) {
72
+ $container->getDefinition($this->debugCommandServiceId)->replaceArgument(4, $container->getParameter('twig.default_path'));
73
+ }
74
+
75
+ if ($container->hasDefinition($this->updateCommandServiceId)) {
76
+ $container->getDefinition($this->updateCommandServiceId)->replaceArgument(5, $container->getParameter('twig.default_path'));
77
+ }
78
+ }
79
+ }
app/vendor/symfony/translation/Dumper/CsvFileDumper.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * CsvFileDumper generates a csv formatted string representation of a message catalogue.
18
+ *
19
+ * @author Stealth35
20
+ */
21
+ class CsvFileDumper extends FileDumper
22
+ {
23
+ private $delimiter = ';';
24
+ private $enclosure = '"';
25
+
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
30
+ {
31
+ $handle = fopen('php://memory', 'rb+');
32
+
33
+ foreach ($messages->all($domain) as $source => $target) {
34
+ fputcsv($handle, array($source, $target), $this->delimiter, $this->enclosure);
35
+ }
36
+
37
+ rewind($handle);
38
+ $output = stream_get_contents($handle);
39
+ fclose($handle);
40
+
41
+ return $output;
42
+ }
43
+
44
+ /**
45
+ * Sets the delimiter and escape character for CSV.
46
+ *
47
+ * @param string $delimiter Delimiter character
48
+ * @param string $enclosure Enclosure character
49
+ */
50
+ public function setCsvControl($delimiter = ';', $enclosure = '"')
51
+ {
52
+ $this->delimiter = $delimiter;
53
+ $this->enclosure = $enclosure;
54
+ }
55
+
56
+ /**
57
+ * {@inheritdoc}
58
+ */
59
+ protected function getExtension()
60
+ {
61
+ return 'csv';
62
+ }
63
+ }
app/vendor/symfony/translation/Dumper/DumperInterface.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * DumperInterface is the interface implemented by all translation dumpers.
18
+ * There is no common option.
19
+ *
20
+ * @author Michel Salib <michelsalib@hotmail.com>
21
+ */
22
+ interface DumperInterface
23
+ {
24
+ /**
25
+ * Dumps the message catalogue.
26
+ *
27
+ * @param MessageCatalogue $messages The message catalogue
28
+ * @param array $options Options that are used by the dumper
29
+ */
30
+ public function dump(MessageCatalogue $messages, $options = array());
31
+ }
app/vendor/symfony/translation/Dumper/FileDumper.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
16
+ use Symfony\Component\Translation\Exception\RuntimeException;
17
+
18
+ /**
19
+ * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
20
+ *
21
+ * Options:
22
+ * - path (mandatory): the directory where the files should be saved
23
+ *
24
+ * @author Michel Salib <michelsalib@hotmail.com>
25
+ */
26
+ abstract class FileDumper implements DumperInterface
27
+ {
28
+ /**
29
+ * A template for the relative paths to files.
30
+ *
31
+ * @var string
32
+ */
33
+ protected $relativePathTemplate = '%domain%.%locale%.%extension%';
34
+
35
+ /**
36
+ * Sets the template for the relative paths to files.
37
+ *
38
+ * @param string $relativePathTemplate A template for the relative paths to files
39
+ */
40
+ public function setRelativePathTemplate($relativePathTemplate)
41
+ {
42
+ $this->relativePathTemplate = $relativePathTemplate;
43
+ }
44
+
45
+ /**
46
+ * Sets backup flag.
47
+ *
48
+ * @param bool
49
+ *
50
+ * @deprecated since Symfony 4.1
51
+ */
52
+ public function setBackup($backup)
53
+ {
54
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED);
55
+
56
+ if (false !== $backup) {
57
+ throw new \LogicException('The backup feature is no longer supported.');
58
+ }
59
+ }
60
+
61
+ /**
62
+ * {@inheritdoc}
63
+ */
64
+ public function dump(MessageCatalogue $messages, $options = array())
65
+ {
66
+ if (!array_key_exists('path', $options)) {
67
+ throw new InvalidArgumentException('The file dumper needs a path option.');
68
+ }
69
+
70
+ // save a file for each domain
71
+ foreach ($messages->getDomains() as $domain) {
72
+ $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
73
+ if (!file_exists($fullpath)) {
74
+ $directory = dirname($fullpath);
75
+ if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
76
+ throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
77
+ }
78
+ }
79
+ // save file
80
+ file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Transforms a domain of a message catalogue to its string representation.
86
+ *
87
+ * @param MessageCatalogue $messages
88
+ * @param string $domain
89
+ * @param array $options
90
+ *
91
+ * @return string representation
92
+ */
93
+ abstract public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array());
94
+
95
+ /**
96
+ * Gets the file extension of the dumper.
97
+ *
98
+ * @return string file extension
99
+ */
100
+ abstract protected function getExtension();
101
+
102
+ /**
103
+ * Gets the relative file path using the template.
104
+ */
105
+ private function getRelativePath(string $domain, string $locale): string
106
+ {
107
+ return strtr($this->relativePathTemplate, array(
108
+ '%domain%' => $domain,
109
+ '%locale%' => $locale,
110
+ '%extension%' => $this->getExtension(),
111
+ ));
112
+ }
113
+ }
app/vendor/symfony/translation/Dumper/IcuResFileDumper.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
18
+ *
19
+ * @author Stealth35
20
+ */
21
+ class IcuResFileDumper extends FileDumper
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ protected $relativePathTemplate = '%domain%/%locale%.%extension%';
27
+
28
+ /**
29
+ * {@inheritdoc}
30
+ */
31
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
32
+ {
33
+ $data = $indexes = $resources = '';
34
+
35
+ foreach ($messages->all($domain) as $source => $target) {
36
+ $indexes .= pack('v', strlen($data) + 28);
37
+ $data .= $source."\0";
38
+ }
39
+
40
+ $data .= $this->writePadding($data);
41
+
42
+ $keyTop = $this->getPosition($data);
43
+
44
+ foreach ($messages->all($domain) as $source => $target) {
45
+ $resources .= pack('V', $this->getPosition($data));
46
+
47
+ $data .= pack('V', strlen($target))
48
+ .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8')
49
+ .$this->writePadding($data)
50
+ ;
51
+ }
52
+
53
+ $resOffset = $this->getPosition($data);
54
+
55
+ $data .= pack('v', count($messages->all($domain)))
56
+ .$indexes
57
+ .$this->writePadding($data)
58
+ .$resources
59
+ ;
60
+
61
+ $bundleTop = $this->getPosition($data);
62
+
63
+ $root = pack('V7',
64
+ $resOffset + (2 << 28), // Resource Offset + Resource Type
65
+ 6, // Index length
66
+ $keyTop, // Index keys top
67
+ $bundleTop, // Index resources top
68
+ $bundleTop, // Index bundle top
69
+ count($messages->all($domain)), // Index max table length
70
+ 0 // Index attributes
71
+ );
72
+
73
+ $header = pack('vC2v4C12@32',
74
+ 32, // Header size
75
+ 0xDA, 0x27, // Magic number 1 and 2
76
+ 20, 0, 0, 2, // Rest of the header, ..., Size of a char
77
+ 0x52, 0x65, 0x73, 0x42, // Data format identifier
78
+ 1, 2, 0, 0, // Data version
79
+ 1, 4, 0, 0 // Unicode version
80
+ );
81
+
82
+ return $header.$root.$data;
83
+ }
84
+
85
+ private function writePadding($data)
86
+ {
87
+ $padding = strlen($data) % 4;
88
+
89
+ if ($padding) {
90
+ return str_repeat("\xAA", 4 - $padding);
91
+ }
92
+ }
93
+
94
+ private function getPosition($data)
95
+ {
96
+ return (strlen($data) + 28) / 4;
97
+ }
98
+
99
+ /**
100
+ * {@inheritdoc}
101
+ */
102
+ protected function getExtension()
103
+ {
104
+ return 'res';
105
+ }
106
+ }
app/vendor/symfony/translation/Dumper/IniFileDumper.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * IniFileDumper generates an ini formatted string representation of a message catalogue.
18
+ *
19
+ * @author Stealth35
20
+ */
21
+ class IniFileDumper extends FileDumper
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
27
+ {
28
+ $output = '';
29
+
30
+ foreach ($messages->all($domain) as $source => $target) {
31
+ $escapeTarget = str_replace('"', '\"', $target);
32
+ $output .= $source.'="'.$escapeTarget."\"\n";
33
+ }
34
+
35
+ return $output;
36
+ }
37
+
38
+ /**
39
+ * {@inheritdoc}
40
+ */
41
+ protected function getExtension()
42
+ {
43
+ return 'ini';
44
+ }
45
+ }
app/vendor/symfony/translation/Dumper/JsonFileDumper.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * JsonFileDumper generates an json formatted string representation of a message catalogue.
18
+ *
19
+ * @author singles
20
+ */
21
+ class JsonFileDumper extends FileDumper
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
27
+ {
28
+ if (isset($options['json_encoding'])) {
29
+ $flags = $options['json_encoding'];
30
+ } else {
31
+ $flags = JSON_PRETTY_PRINT;
32
+ }
33
+
34
+ return json_encode($messages->all($domain), $flags);
35
+ }
36
+
37
+ /**
38
+ * {@inheritdoc}
39
+ */
40
+ protected function getExtension()
41
+ {
42
+ return 'json';
43
+ }
44
+ }
app/vendor/symfony/translation/Dumper/MoFileDumper.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Loader\MoFileLoader;
16
+
17
+ /**
18
+ * MoFileDumper generates a gettext formatted string representation of a message catalogue.
19
+ *
20
+ * @author Stealth35
21
+ */
22
+ class MoFileDumper extends FileDumper
23
+ {
24
+ /**
25
+ * {@inheritdoc}
26
+ */
27
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
28
+ {
29
+ $sources = $targets = $sourceOffsets = $targetOffsets = '';
30
+ $offsets = array();
31
+ $size = 0;
32
+
33
+ foreach ($messages->all($domain) as $source => $target) {
34
+ $offsets[] = array_map('strlen', array($sources, $source, $targets, $target));
35
+ $sources .= "\0".$source;
36
+ $targets .= "\0".$target;
37
+ ++$size;
38
+ }
39
+
40
+ $header = array(
41
+ 'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
42
+ 'formatRevision' => 0,
43
+ 'count' => $size,
44
+ 'offsetId' => MoFileLoader::MO_HEADER_SIZE,
45
+ 'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
46
+ 'sizeHashes' => 0,
47
+ 'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
48
+ );
49
+
50
+ $sourcesSize = strlen($sources);
51
+ $sourcesStart = $header['offsetHashes'] + 1;
52
+
53
+ foreach ($offsets as $offset) {
54
+ $sourceOffsets .= $this->writeLong($offset[1])
55
+ .$this->writeLong($offset[0] + $sourcesStart);
56
+ $targetOffsets .= $this->writeLong($offset[3])
57
+ .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
58
+ }
59
+
60
+ $output = implode(array_map(array($this, 'writeLong'), $header))
61
+ .$sourceOffsets
62
+ .$targetOffsets
63
+ .$sources
64
+ .$targets
65
+ ;
66
+
67
+ return $output;
68
+ }
69
+
70
+ /**
71
+ * {@inheritdoc}
72
+ */
73
+ protected function getExtension()
74
+ {
75
+ return 'mo';
76
+ }
77
+
78
+ private function writeLong($str)
79
+ {
80
+ return pack('V*', $str);
81
+ }
82
+ }
app/vendor/symfony/translation/Dumper/PhpFileDumper.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * PhpFileDumper generates PHP files from a message catalogue.
18
+ *
19
+ * @author Michel Salib <michelsalib@hotmail.com>
20
+ */
21
+ class PhpFileDumper extends FileDumper
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
27
+ {
28
+ return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
29
+ }
30
+
31
+ /**
32
+ * {@inheritdoc}
33
+ */
34
+ protected function getExtension()
35
+ {
36
+ return 'php';
37
+ }
38
+ }
app/vendor/symfony/translation/Dumper/PoFileDumper.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * PoFileDumper generates a gettext formatted string representation of a message catalogue.
18
+ *
19
+ * @author Stealth35
20
+ */
21
+ class PoFileDumper extends FileDumper
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
27
+ {
28
+ $output = 'msgid ""'."\n";
29
+ $output .= 'msgstr ""'."\n";
30
+ $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n";
31
+ $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n";
32
+ $output .= '"Language: '.$messages->getLocale().'\n"'."\n";
33
+ $output .= "\n";
34
+
35
+ $newLine = false;
36
+ foreach ($messages->all($domain) as $source => $target) {
37
+ if ($newLine) {
38
+ $output .= "\n";
39
+ } else {
40
+ $newLine = true;
41
+ }
42
+ $output .= sprintf('msgid "%s"'."\n", $this->escape($source));
43
+ $output .= sprintf('msgstr "%s"', $this->escape($target));
44
+ }
45
+
46
+ return $output;
47
+ }
48
+
49
+ /**
50
+ * {@inheritdoc}
51
+ */
52
+ protected function getExtension()
53
+ {
54
+ return 'po';
55
+ }
56
+
57
+ private function escape($str)
58
+ {
59
+ return addcslashes($str, "\0..\37\42\134");
60
+ }
61
+ }
app/vendor/symfony/translation/Dumper/QtFileDumper.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * QtFileDumper generates ts files from a message catalogue.
18
+ *
19
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
20
+ */
21
+ class QtFileDumper extends FileDumper
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
27
+ {
28
+ $dom = new \DOMDocument('1.0', 'utf-8');
29
+ $dom->formatOutput = true;
30
+ $ts = $dom->appendChild($dom->createElement('TS'));
31
+ $context = $ts->appendChild($dom->createElement('context'));
32
+ $context->appendChild($dom->createElement('name', $domain));
33
+
34
+ foreach ($messages->all($domain) as $source => $target) {
35
+ $message = $context->appendChild($dom->createElement('message'));
36
+ $message->appendChild($dom->createElement('source', $source));
37
+ $message->appendChild($dom->createElement('translation', $target));
38
+ }
39
+
40
+ return $dom->saveXML();
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ */
46
+ protected function getExtension()
47
+ {
48
+ return 'ts';
49
+ }
50
+ }
app/vendor/symfony/translation/Dumper/XliffFileDumper.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
16
+
17
+ /**
18
+ * XliffFileDumper generates xliff files from a message catalogue.
19
+ *
20
+ * @author Michel Salib <michelsalib@hotmail.com>
21
+ */
22
+ class XliffFileDumper extends FileDumper
23
+ {
24
+ /**
25
+ * {@inheritdoc}
26
+ */
27
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
28
+ {
29
+ $xliffVersion = '1.2';
30
+ if (array_key_exists('xliff_version', $options)) {
31
+ $xliffVersion = $options['xliff_version'];
32
+ }
33
+
34
+ if (array_key_exists('default_locale', $options)) {
35
+ $defaultLocale = $options['default_locale'];
36
+ } else {
37
+ $defaultLocale = \Locale::getDefault();
38
+ }
39
+
40
+ if ('1.2' === $xliffVersion) {
41
+ return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
42
+ }
43
+ if ('2.0' === $xliffVersion) {
44
+ return $this->dumpXliff2($defaultLocale, $messages, $domain, $options);
45
+ }
46
+
47
+ throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
48
+ }
49
+
50
+ /**
51
+ * {@inheritdoc}
52
+ */
53
+ protected function getExtension()
54
+ {
55
+ return 'xlf';
56
+ }
57
+
58
+ private function dumpXliff1($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
59
+ {
60
+ $toolInfo = array('tool-id' => 'symfony', 'tool-name' => 'Symfony');
61
+ if (array_key_exists('tool_info', $options)) {
62
+ $toolInfo = array_merge($toolInfo, $options['tool_info']);
63
+ }
64
+
65
+ $dom = new \DOMDocument('1.0', 'utf-8');
66
+ $dom->formatOutput = true;
67
+
68
+ $xliff = $dom->appendChild($dom->createElement('xliff'));
69
+ $xliff->setAttribute('version', '1.2');
70
+ $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
71
+
72
+ $xliffFile = $xliff->appendChild($dom->createElement('file'));
73
+ $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
74
+ $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
75
+ $xliffFile->setAttribute('datatype', 'plaintext');
76
+ $xliffFile->setAttribute('original', 'file.ext');
77
+
78
+ $xliffHead = $xliffFile->appendChild($dom->createElement('header'));
79
+ $xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
80
+ foreach ($toolInfo as $id => $value) {
81
+ $xliffTool->setAttribute($id, $value);
82
+ }
83
+
84
+ $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
85
+ foreach ($messages->all($domain) as $source => $target) {
86
+ $translation = $dom->createElement('trans-unit');
87
+
88
+ $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
89
+ $translation->setAttribute('resname', $source);
90
+
91
+ $s = $translation->appendChild($dom->createElement('source'));
92
+ $s->appendChild($dom->createTextNode($source));
93
+
94
+ // Does the target contain characters requiring a CDATA section?
95
+ $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
96
+
97
+ $targetElement = $dom->createElement('target');
98
+ $metadata = $messages->getMetadata($source, $domain);
99
+ if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
100
+ foreach ($metadata['target-attributes'] as $name => $value) {
101
+ $targetElement->setAttribute($name, $value);
102
+ }
103
+ }
104
+ $t = $translation->appendChild($targetElement);
105
+ $t->appendChild($text);
106
+
107
+ if ($this->hasMetadataArrayInfo('notes', $metadata)) {
108
+ foreach ($metadata['notes'] as $note) {
109
+ if (!isset($note['content'])) {
110
+ continue;
111
+ }
112
+
113
+ $n = $translation->appendChild($dom->createElement('note'));
114
+ $n->appendChild($dom->createTextNode($note['content']));
115
+
116
+ if (isset($note['priority'])) {
117
+ $n->setAttribute('priority', $note['priority']);
118
+ }
119
+
120
+ if (isset($note['from'])) {
121
+ $n->setAttribute('from', $note['from']);
122
+ }
123
+ }
124
+ }
125
+
126
+ $xliffBody->appendChild($translation);
127
+ }
128
+
129
+ return $dom->saveXML();
130
+ }
131
+
132
+ private function dumpXliff2($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
133
+ {
134
+ $dom = new \DOMDocument('1.0', 'utf-8');
135
+ $dom->formatOutput = true;
136
+
137
+ $xliff = $dom->appendChild($dom->createElement('xliff'));
138
+ $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
139
+ $xliff->setAttribute('version', '2.0');
140
+ $xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
141
+ $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
142
+
143
+ $xliffFile = $xliff->appendChild($dom->createElement('file'));
144
+ $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
145
+
146
+ foreach ($messages->all($domain) as $source => $target) {
147
+ $translation = $dom->createElement('unit');
148
+ $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
149
+ $name = $source;
150
+ if (strlen($source) > 80) {
151
+ $name = substr(md5($source), -7);
152
+ }
153
+ $translation->setAttribute('name', $name);
154
+ $metadata = $messages->getMetadata($source, $domain);
155
+
156
+ // Add notes section
157
+ if ($this->hasMetadataArrayInfo('notes', $metadata)) {
158
+ $notesElement = $dom->createElement('notes');
159
+ foreach ($metadata['notes'] as $note) {
160
+ $n = $dom->createElement('note');
161
+ $n->appendChild($dom->createTextNode(isset($note['content']) ? $note['content'] : ''));
162
+ unset($note['content']);
163
+
164
+ foreach ($note as $name => $value) {
165
+ $n->setAttribute($name, $value);
166
+ }
167
+ $notesElement->appendChild($n);
168
+ }
169
+ $translation->appendChild($notesElement);
170
+ }
171
+
172
+ $segment = $translation->appendChild($dom->createElement('segment'));
173
+
174
+ $s = $segment->appendChild($dom->createElement('source'));
175
+ $s->appendChild($dom->createTextNode($source));
176
+
177
+ // Does the target contain characters requiring a CDATA section?
178
+ $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
179
+
180
+ $targetElement = $dom->createElement('target');
181
+ if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
182
+ foreach ($metadata['target-attributes'] as $name => $value) {
183
+ $targetElement->setAttribute($name, $value);
184
+ }
185
+ }
186
+ $t = $segment->appendChild($targetElement);
187
+ $t->appendChild($text);
188
+
189
+ $xliffFile->appendChild($translation);
190
+ }
191
+
192
+ return $dom->saveXML();
193
+ }
194
+
195
+ /**
196
+ * @param string $key
197
+ * @param array|null $metadata
198
+ *
199
+ * @return bool
200
+ */
201
+ private function hasMetadataArrayInfo($key, $metadata = null)
202
+ {
203
+ return null !== $metadata && array_key_exists($key, $metadata) && ($metadata[$key] instanceof \Traversable || is_array($metadata[$key]));
204
+ }
205
+ }
app/vendor/symfony/translation/Dumper/YamlFileDumper.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Dumper;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Util\ArrayConverter;
16
+ use Symfony\Component\Yaml\Yaml;
17
+ use Symfony\Component\Translation\Exception\LogicException;
18
+
19
+ /**
20
+ * YamlFileDumper generates yaml files from a message catalogue.
21
+ *
22
+ * @author Michel Salib <michelsalib@hotmail.com>
23
+ */
24
+ class YamlFileDumper extends FileDumper
25
+ {
26
+ private $extension;
27
+
28
+ public function __construct(string $extension = 'yml')
29
+ {
30
+ $this->extension = $extension;
31
+ }
32
+
33
+ /**
34
+ * {@inheritdoc}
35
+ */
36
+ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
37
+ {
38
+ if (!class_exists('Symfony\Component\Yaml\Yaml')) {
39
+ throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
40
+ }
41
+
42
+ $data = $messages->all($domain);
43
+
44
+ if (isset($options['as_tree']) && $options['as_tree']) {
45
+ $data = ArrayConverter::expandToTree($data);
46
+ }
47
+
48
+ if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
49
+ return Yaml::dump($data, $inline);
50
+ }
51
+
52
+ return Yaml::dump($data);
53
+ }
54
+
55
+ /**
56
+ * {@inheritdoc}
57
+ */
58
+ protected function getExtension()
59
+ {
60
+ return $this->extension;
61
+ }
62
+ }
app/vendor/symfony/translation/Exception/ExceptionInterface.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Exception;
13
+
14
+ /**
15
+ * Exception interface for all exceptions thrown by the component.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ interface ExceptionInterface
20
+ {
21
+ }
app/vendor/symfony/translation/Exception/InvalidArgumentException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Exception;
13
+
14
+ /**
15
+ * Base InvalidArgumentException for the Translation component.
16
+ *
17
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
18
+ */
19
+ class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
20
+ {
21
+ }
app/vendor/symfony/translation/Exception/InvalidResourceException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Exception;
13
+
14
+ /**
15
+ * Thrown when a resource cannot be loaded.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface
20
+ {
21
+ }
app/vendor/symfony/translation/Exception/LogicException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Exception;
13
+
14
+ /**
15
+ * Base LogicException for Translation component.
16
+ *
17
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
18
+ */
19
+ class LogicException extends \LogicException implements ExceptionInterface
20
+ {
21
+ }
app/vendor/symfony/translation/Exception/NotFoundResourceException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Exception;
13
+
14
+ /**
15
+ * Thrown when a resource does not exist.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface
20
+ {
21
+ }
app/vendor/symfony/translation/Exception/RuntimeException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Exception;
13
+
14
+ /**
15
+ * Base RuntimeException for the Translation component.
16
+ *
17
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
18
+ */
19
+ class RuntimeException extends \RuntimeException implements ExceptionInterface
20
+ {
21
+ }
app/vendor/symfony/translation/Extractor/AbstractFileExtractor.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Extractor;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
15
+
16
+ /**
17
+ * Base class used by classes that extract translation messages from files.
18
+ *
19
+ * @author Marcos D. Sánchez <marcosdsanchez@gmail.com>
20
+ */
21
+ abstract class AbstractFileExtractor
22
+ {
23
+ /**
24
+ * @param string|array $resource Files, a file or a directory
25
+ *
26
+ * @return array
27
+ */
28
+ protected function extractFiles($resource)
29
+ {
30
+ if (is_array($resource) || $resource instanceof \Traversable) {
31
+ $files = array();
32
+ foreach ($resource as $file) {
33
+ if ($this->canBeExtracted($file)) {
34
+ $files[] = $this->toSplFileInfo($file);
35
+ }
36
+ }
37
+ } elseif (is_file($resource)) {
38
+ $files = $this->canBeExtracted($resource) ? array($this->toSplFileInfo($resource)) : array();
39
+ } else {
40
+ $files = $this->extractFromDirectory($resource);
41
+ }
42
+
43
+ return $files;
44
+ }
45
+
46
+ private function toSplFileInfo(string $file): \SplFileInfo
47
+ {
48
+ return ($file instanceof \SplFileInfo) ? $file : new \SplFileInfo($file);
49
+ }
50
+
51
+ /**
52
+ * @param string $file
53
+ *
54
+ * @return bool
55
+ *
56
+ * @throws InvalidArgumentException
57
+ */
58
+ protected function isFile($file)
59
+ {
60
+ if (!is_file($file)) {
61
+ throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
62
+ }
63
+
64
+ return true;
65
+ }
66
+
67
+ /**
68
+ * @param string $file
69
+ *
70
+ * @return bool
71
+ */
72
+ abstract protected function canBeExtracted($file);
73
+
74
+ /**
75
+ * @param string|array $resource Files, a file or a directory
76
+ *
77
+ * @return array files to be extracted
78
+ */
79
+ abstract protected function extractFromDirectory($resource);
80
+ }
app/vendor/symfony/translation/Extractor/ChainExtractor.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Extractor;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * ChainExtractor extracts translation messages from template files.
18
+ *
19
+ * @author Michel Salib <michelsalib@hotmail.com>
20
+ */
21
+ class ChainExtractor implements ExtractorInterface
22
+ {
23
+ /**
24
+ * The extractors.
25
+ *
26
+ * @var ExtractorInterface[]
27
+ */
28
+ private $extractors = array();
29
+
30
+ /**
31
+ * Adds a loader to the translation extractor.
32
+ *
33
+ * @param string $format The format of the loader
34
+ * @param ExtractorInterface $extractor The loader
35
+ */
36
+ public function addExtractor($format, ExtractorInterface $extractor)
37
+ {
38
+ $this->extractors[$format] = $extractor;
39
+ }
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ */
44
+ public function setPrefix($prefix)
45
+ {
46
+ foreach ($this->extractors as $extractor) {
47
+ $extractor->setPrefix($prefix);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * {@inheritdoc}
53
+ */
54
+ public function extract($directory, MessageCatalogue $catalogue)
55
+ {
56
+ foreach ($this->extractors as $extractor) {
57
+ $extractor->extract($directory, $catalogue);
58
+ }
59
+ }
60
+ }
app/vendor/symfony/translation/Extractor/ExtractorInterface.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Extractor;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * Extracts translation messages from a directory or files to the catalogue.
18
+ * New found messages are injected to the catalogue using the prefix.
19
+ *
20
+ * @author Michel Salib <michelsalib@hotmail.com>
21
+ */
22
+ interface ExtractorInterface
23
+ {
24
+ /**
25
+ * Extracts translation messages from files, a file or a directory to the catalogue.
26
+ *
27
+ * @param string|array $resource Files, a file or a directory
28
+ * @param MessageCatalogue $catalogue The catalogue
29
+ */
30
+ public function extract($resource, MessageCatalogue $catalogue);
31
+
32
+ /**
33
+ * Sets the prefix that should be used for new found messages.
34
+ *
35
+ * @param string $prefix The prefix
36
+ */
37
+ public function setPrefix($prefix);
38
+ }
app/vendor/symfony/translation/Extractor/PhpExtractor.php ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Extractor;
13
+
14
+ use Symfony\Component\Finder\Finder;
15
+ use Symfony\Component\Translation\MessageCatalogue;
16
+
17
+ /**
18
+ * PhpExtractor extracts translation messages from a PHP template.
19
+ *
20
+ * @author Michel Salib <michelsalib@hotmail.com>
21
+ */
22
+ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
23
+ {
24
+ const MESSAGE_TOKEN = 300;
25
+ const METHOD_ARGUMENTS_TOKEN = 1000;
26
+ const DOMAIN_TOKEN = 1001;
27
+
28
+ /**
29
+ * Prefix for new found message.
30
+ *
31
+ * @var string
32
+ */
33
+ private $prefix = '';
34
+
35
+ /**
36
+ * The sequence that captures translation messages.
37
+ *
38
+ * @var array
39
+ */
40
+ protected $sequences = array(
41
+ array(
42
+ '->',
43
+ 'trans',
44
+ '(',
45
+ self::MESSAGE_TOKEN,
46
+ ',',
47
+ self::METHOD_ARGUMENTS_TOKEN,
48
+ ',',
49
+ self::DOMAIN_TOKEN,
50
+ ),
51
+ array(
52
+ '->',
53
+ 'transChoice',
54
+ '(',
55
+ self::MESSAGE_TOKEN,
56
+ ',',
57
+ self::METHOD_ARGUMENTS_TOKEN,
58
+ ',',
59
+ self::METHOD_ARGUMENTS_TOKEN,
60
+ ',',
61
+ self::DOMAIN_TOKEN,
62
+ ),
63
+ array(
64
+ '->',
65
+ 'trans',
66
+ '(',
67
+ self::MESSAGE_TOKEN,
68
+ ),
69
+ array(
70
+ '->',
71
+ 'transChoice',
72
+ '(',
73
+ self::MESSAGE_TOKEN,
74
+ ),
75
+ );
76
+
77
+ /**
78
+ * {@inheritdoc}
79
+ */
80
+ public function extract($resource, MessageCatalogue $catalog)
81
+ {
82
+ $files = $this->extractFiles($resource);
83
+ foreach ($files as $file) {
84
+ $this->parseTokens(token_get_all(file_get_contents($file)), $catalog);
85
+
86
+ // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
87
+ gc_mem_caches();
88
+ }
89
+ }
90
+
91
+ /**
92
+ * {@inheritdoc}
93
+ */
94
+ public function setPrefix($prefix)
95
+ {
96
+ $this->prefix = $prefix;
97
+ }
98
+
99
+ /**
100
+ * Normalizes a token.
101
+ *
102
+ * @param mixed $token
103
+ *
104
+ * @return string
105
+ */
106
+ protected function normalizeToken($token)
107
+ {
108
+ if (isset($token[1]) && 'b"' !== $token) {
109
+ return $token[1];
110
+ }
111
+
112
+ return $token;
113
+ }
114
+
115
+ /**
116
+ * Seeks to a non-whitespace token.
117
+ */
118
+ private function seekToNextRelevantToken(\Iterator $tokenIterator)
119
+ {
120
+ for (; $tokenIterator->valid(); $tokenIterator->next()) {
121
+ $t = $tokenIterator->current();
122
+ if (T_WHITESPACE !== $t[0]) {
123
+ break;
124
+ }
125
+ }
126
+ }
127
+
128
+ private function skipMethodArgument(\Iterator $tokenIterator)
129
+ {
130
+ $openBraces = 0;
131
+
132
+ for (; $tokenIterator->valid(); $tokenIterator->next()) {
133
+ $t = $tokenIterator->current();
134
+
135
+ if ('[' === $t[0] || '(' === $t[0]) {
136
+ ++$openBraces;
137
+ }
138
+
139
+ if (']' === $t[0] || ')' === $t[0]) {
140
+ --$openBraces;
141
+ }
142
+
143
+ if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) {
144
+ break;
145
+ }
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Extracts the message from the iterator while the tokens
151
+ * match allowed message tokens.
152
+ */
153
+ private function getValue(\Iterator $tokenIterator)
154
+ {
155
+ $message = '';
156
+ $docToken = '';
157
+
158
+ for (; $tokenIterator->valid(); $tokenIterator->next()) {
159
+ $t = $tokenIterator->current();
160
+ if (!isset($t[1])) {
161
+ break;
162
+ }
163
+
164
+ switch ($t[0]) {
165
+ case T_START_HEREDOC:
166
+ $docToken = $t[1];
167
+ break;
168
+ case T_ENCAPSED_AND_WHITESPACE:
169
+ case T_CONSTANT_ENCAPSED_STRING:
170
+ $message .= $t[1];
171
+ break;
172
+ case T_END_HEREDOC:
173
+ return PhpStringTokenParser::parseDocString($docToken, $message);
174
+ default:
175
+ break 2;
176
+ }
177
+ }
178
+
179
+ if ($message) {
180
+ $message = PhpStringTokenParser::parse($message);
181
+ }
182
+
183
+ return $message;
184
+ }
185
+
186
+ /**
187
+ * Extracts trans message from PHP tokens.
188
+ *
189
+ * @param array $tokens
190
+ * @param MessageCatalogue $catalog
191
+ */
192
+ protected function parseTokens($tokens, MessageCatalogue $catalog)
193
+ {
194
+ $tokenIterator = new \ArrayIterator($tokens);
195
+
196
+ for ($key = 0; $key < $tokenIterator->count(); ++$key) {
197
+ foreach ($this->sequences as $sequence) {
198
+ $message = '';
199
+ $domain = 'messages';
200
+ $tokenIterator->seek($key);
201
+
202
+ foreach ($sequence as $sequenceKey => $item) {
203
+ $this->seekToNextRelevantToken($tokenIterator);
204
+
205
+ if ($this->normalizeToken($tokenIterator->current()) === $item) {
206
+ $tokenIterator->next();
207
+ continue;
208
+ } elseif (self::MESSAGE_TOKEN === $item) {
209
+ $message = $this->getValue($tokenIterator);
210
+
211
+ if (count($sequence) === ($sequenceKey + 1)) {
212
+ break;
213
+ }
214
+ } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
215
+ $this->skipMethodArgument($tokenIterator);
216
+ } elseif (self::DOMAIN_TOKEN === $item) {
217
+ $domain = $this->getValue($tokenIterator);
218
+
219
+ break;
220
+ } else {
221
+ break;
222
+ }
223
+ }
224
+
225
+ if ($message) {
226
+ $catalog->set($message, $this->prefix.$message, $domain);
227
+ break;
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ /**
234
+ * @param string $file
235
+ *
236
+ * @return bool
237
+ *
238
+ * @throws \InvalidArgumentException
239
+ */
240
+ protected function canBeExtracted($file)
241
+ {
242
+ return $this->isFile($file) && 'php' === pathinfo($file, PATHINFO_EXTENSION);
243
+ }
244
+
245
+ /**
246
+ * @param string|array $directory
247
+ *
248
+ * @return array
249
+ */
250
+ protected function extractFromDirectory($directory)
251
+ {
252
+ $finder = new Finder();
253
+
254
+ return $finder->files()->name('*.php')->in($directory);
255
+ }
256
+ }
app/vendor/symfony/translation/Extractor/PhpStringTokenParser.php ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Extractor;
13
+
14
+ /*
15
+ * The following is derived from code at http://github.com/nikic/PHP-Parser
16
+ *
17
+ * Copyright (c) 2011 by Nikita Popov
18
+ *
19
+ * Some rights reserved.
20
+ *
21
+ * Redistribution and use in source and binary forms, with or without
22
+ * modification, are permitted provided that the following conditions are
23
+ * met:
24
+ *
25
+ * * Redistributions of source code must retain the above copyright
26
+ * notice, this list of conditions and the following disclaimer.
27
+ *
28
+ * * Redistributions in binary form must reproduce the above
29
+ * copyright notice, this list of conditions and the following
30
+ * disclaimer in the documentation and/or other materials provided
31
+ * with the distribution.
32
+ *
33
+ * * The names of the contributors may not be used to endorse or
34
+ * promote products derived from this software without specific
35
+ * prior written permission.
36
+ *
37
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48
+ */
49
+
50
+ class PhpStringTokenParser
51
+ {
52
+ protected static $replacements = array(
53
+ '\\' => '\\',
54
+ '$' => '$',
55
+ 'n' => "\n",
56
+ 'r' => "\r",
57
+ 't' => "\t",
58
+ 'f' => "\f",
59
+ 'v' => "\v",
60
+ 'e' => "\x1B",
61
+ );
62
+
63
+ /**
64
+ * Parses a string token.
65
+ *
66
+ * @param string $str String token content
67
+ *
68
+ * @return string The parsed string
69
+ */
70
+ public static function parse($str)
71
+ {
72
+ $bLength = 0;
73
+ if ('b' === $str[0]) {
74
+ $bLength = 1;
75
+ }
76
+
77
+ if ('\'' === $str[$bLength]) {
78
+ return str_replace(
79
+ array('\\\\', '\\\''),
80
+ array('\\', '\''),
81
+ substr($str, $bLength + 1, -1)
82
+ );
83
+ } else {
84
+ return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Parses escape sequences in strings (all string types apart from single quoted).
90
+ *
91
+ * @param string $str String without quotes
92
+ * @param null|string $quote Quote type
93
+ *
94
+ * @return string String with escape sequences parsed
95
+ */
96
+ public static function parseEscapeSequences($str, $quote)
97
+ {
98
+ if (null !== $quote) {
99
+ $str = str_replace('\\'.$quote, $quote, $str);
100
+ }
101
+
102
+ return preg_replace_callback(
103
+ '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~',
104
+ array(__CLASS__, 'parseCallback'),
105
+ $str
106
+ );
107
+ }
108
+
109
+ private static function parseCallback($matches)
110
+ {
111
+ $str = $matches[1];
112
+
113
+ if (isset(self::$replacements[$str])) {
114
+ return self::$replacements[$str];
115
+ } elseif ('x' === $str[0] || 'X' === $str[0]) {
116
+ return chr(hexdec($str));
117
+ } else {
118
+ return chr(octdec($str));
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Parses a constant doc string.
124
+ *
125
+ * @param string $startToken Doc string start token content (<<<SMTHG)
126
+ * @param string $str String token content
127
+ *
128
+ * @return string Parsed string
129
+ */
130
+ public static function parseDocString($startToken, $str)
131
+ {
132
+ // strip last newline (thanks tokenizer for sticking it into the string!)
133
+ $str = preg_replace('~(\r\n|\n|\r)$~', '', $str);
134
+
135
+ // nowdoc string
136
+ if (false !== strpos($startToken, '\'')) {
137
+ return $str;
138
+ }
139
+
140
+ return self::parseEscapeSequences($str, null);
141
+ }
142
+ }
app/vendor/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Formatter;
13
+
14
+ /**
15
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
16
+ */
17
+ interface ChoiceMessageFormatterInterface
18
+ {
19
+ /**
20
+ * Formats a localized message pattern with given arguments.
21
+ *
22
+ * @param string $message The message (may also be an object that can be cast to string)
23
+ * @param int $number The number to use to find the indice of the message
24
+ * @param string $locale The message locale
25
+ * @param array $parameters An array of parameters for the message
26
+ *
27
+ * @return string
28
+ */
29
+ public function choiceFormat($message, $number, $locale, array $parameters = array());
30
+ }
app/vendor/symfony/translation/Formatter/MessageFormatter.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Formatter;
13
+
14
+ use Symfony\Component\Translation\MessageSelector;
15
+
16
+ /**
17
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
18
+ */
19
+ class MessageFormatter implements MessageFormatterInterface, ChoiceMessageFormatterInterface
20
+ {
21
+ private $selector;
22
+
23
+ /**
24
+ * @param MessageSelector|null $selector The message selector for pluralization
25
+ */
26
+ public function __construct(MessageSelector $selector = null)
27
+ {
28
+ $this->selector = $selector ?: new MessageSelector();
29
+ }
30
+
31
+ /**
32
+ * {@inheritdoc}
33
+ */
34
+ public function format($message, $locale, array $parameters = array())
35
+ {
36
+ return strtr($message, $parameters);
37
+ }
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ */
42
+ public function choiceFormat($message, $number, $locale, array $parameters = array())
43
+ {
44
+ $parameters = array_merge(array('%count%' => $number), $parameters);
45
+
46
+ return $this->format($this->selector->choose($message, (int) $number, $locale), $locale, $parameters);
47
+ }
48
+ }
app/vendor/symfony/translation/Formatter/MessageFormatterInterface.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Formatter;
13
+
14
+ /**
15
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
16
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
17
+ */
18
+ interface MessageFormatterInterface
19
+ {
20
+ /**
21
+ * Formats a localized message pattern with given arguments.
22
+ *
23
+ * @param string $message The message (may also be an object that can be cast to string)
24
+ * @param string $locale The message locale
25
+ * @param array $parameters An array of parameters for the message
26
+ *
27
+ * @return string
28
+ */
29
+ public function format($message, $locale, array $parameters = array());
30
+ }
app/vendor/symfony/translation/IdentityTranslator.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ /**
15
+ * IdentityTranslator does not translate anything.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class IdentityTranslator implements TranslatorInterface
20
+ {
21
+ private $selector;
22
+ private $locale;
23
+
24
+ /**
25
+ * @param MessageSelector|null $selector The message selector for pluralization
26
+ */
27
+ public function __construct(MessageSelector $selector = null)
28
+ {
29
+ $this->selector = $selector ?: new MessageSelector();
30
+ }
31
+
32
+ /**
33
+ * {@inheritdoc}
34
+ */
35
+ public function setLocale($locale)
36
+ {
37
+ $this->locale = $locale;
38
+ }
39
+
40
+ /**
41
+ * {@inheritdoc}
42
+ */
43
+ public function getLocale()
44
+ {
45
+ return $this->locale ?: \Locale::getDefault();
46
+ }
47
+
48
+ /**
49
+ * {@inheritdoc}
50
+ */
51
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
52
+ {
53
+ return strtr((string) $id, $parameters);
54
+ }
55
+
56
+ /**
57
+ * {@inheritdoc}
58
+ */
59
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
60
+ {
61
+ return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters);
62
+ }
63
+ }
app/vendor/symfony/translation/Interval.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
15
+
16
+ /**
17
+ * Tests if a given number belongs to a given math interval.
18
+ *
19
+ * An interval can represent a finite set of numbers:
20
+ *
21
+ * {1,2,3,4}
22
+ *
23
+ * An interval can represent numbers between two numbers:
24
+ *
25
+ * [1, +Inf]
26
+ * ]-1,2[
27
+ *
28
+ * The left delimiter can be [ (inclusive) or ] (exclusive).
29
+ * The right delimiter can be [ (exclusive) or ] (inclusive).
30
+ * Beside numbers, you can use -Inf and +Inf for the infinite.
31
+ *
32
+ * @author Fabien Potencier <fabien@symfony.com>
33
+ *
34
+ * @see http://en.wikipedia.org/wiki/Interval_%28mathematics%29#The_ISO_notation
35
+ */
36
+ class Interval
37
+ {
38
+ /**
39
+ * Tests if the given number is in the math interval.
40
+ *
41
+ * @param int $number A number
42
+ * @param string $interval An interval
43
+ *
44
+ * @return bool
45
+ *
46
+ * @throws InvalidArgumentException
47
+ */
48
+ public static function test($number, $interval)
49
+ {
50
+ $interval = trim($interval);
51
+
52
+ if (!preg_match('/^'.self::getIntervalRegexp().'$/x', $interval, $matches)) {
53
+ throw new InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval));
54
+ }
55
+
56
+ if ($matches[1]) {
57
+ foreach (explode(',', $matches[2]) as $n) {
58
+ if ($number == $n) {
59
+ return true;
60
+ }
61
+ }
62
+ } else {
63
+ $leftNumber = self::convertNumber($matches['left']);
64
+ $rightNumber = self::convertNumber($matches['right']);
65
+
66
+ return
67
+ ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
68
+ && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
69
+ ;
70
+ }
71
+
72
+ return false;
73
+ }
74
+
75
+ /**
76
+ * Returns a Regexp that matches valid intervals.
77
+ *
78
+ * @return string A Regexp (without the delimiters)
79
+ */
80
+ public static function getIntervalRegexp()
81
+ {
82
+ return <<<EOF
83
+ ({\s*
84
+ (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
85
+ \s*})
86
+
87
+ |
88
+
89
+ (?P<left_delimiter>[\[\]])
90
+ \s*
91
+ (?P<left>-Inf|\-?\d+(\.\d+)?)
92
+ \s*,\s*
93
+ (?P<right>\+?Inf|\-?\d+(\.\d+)?)
94
+ \s*
95
+ (?P<right_delimiter>[\[\]])
96
+ EOF;
97
+ }
98
+
99
+ private static function convertNumber($number)
100
+ {
101
+ if ('-Inf' === $number) {
102
+ return log(0);
103
+ } elseif ('+Inf' === $number || 'Inf' === $number) {
104
+ return -log(0);
105
+ }
106
+
107
+ return (float) $number;
108
+ }
109
+ }
app/vendor/symfony/translation/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2004-2018 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
app/vendor/symfony/translation/Loader/ArrayLoader.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * ArrayLoader loads translations from a PHP array.
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ */
21
+ class ArrayLoader implements LoaderInterface
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function load($resource, $locale, $domain = 'messages')
27
+ {
28
+ $this->flatten($resource);
29
+ $catalogue = new MessageCatalogue($locale);
30
+ $catalogue->add($resource, $domain);
31
+
32
+ return $catalogue;
33
+ }
34
+
35
+ /**
36
+ * Flattens an nested array of translations.
37
+ *
38
+ * The scheme used is:
39
+ * 'key' => array('key2' => array('key3' => 'value'))
40
+ * Becomes:
41
+ * 'key.key2.key3' => 'value'
42
+ *
43
+ * This function takes an array by reference and will modify it
44
+ *
45
+ * @param array &$messages The array that will be flattened
46
+ * @param array $subnode Current subnode being parsed, used internally for recursive calls
47
+ * @param string $path Current path being parsed, used internally for recursive calls
48
+ */
49
+ private function flatten(array &$messages, array $subnode = null, $path = null)
50
+ {
51
+ if (null === $subnode) {
52
+ $subnode = &$messages;
53
+ }
54
+ foreach ($subnode as $key => $value) {
55
+ if (is_array($value)) {
56
+ $nodePath = $path ? $path.'.'.$key : $key;
57
+ $this->flatten($messages, $value, $nodePath);
58
+ if (null === $path) {
59
+ unset($messages[$key]);
60
+ }
61
+ } elseif (null !== $path) {
62
+ $messages[$path.'.'.$key] = $value;
63
+ }
64
+ }
65
+ }
66
+ }
app/vendor/symfony/translation/Loader/CsvFileLoader.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
15
+
16
+ /**
17
+ * CsvFileLoader loads translations from CSV files.
18
+ *
19
+ * @author Saša Stamenković <umpirsky@gmail.com>
20
+ */
21
+ class CsvFileLoader extends FileLoader
22
+ {
23
+ private $delimiter = ';';
24
+ private $enclosure = '"';
25
+ private $escape = '\\';
26
+
27
+ /**
28
+ * {@inheritdoc}
29
+ */
30
+ protected function loadResource($resource)
31
+ {
32
+ $messages = array();
33
+
34
+ try {
35
+ $file = new \SplFileObject($resource, 'rb');
36
+ } catch (\RuntimeException $e) {
37
+ throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
38
+ }
39
+
40
+ $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
41
+ $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
42
+
43
+ foreach ($file as $data) {
44
+ if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === count($data)) {
45
+ $messages[$data[0]] = $data[1];
46
+ }
47
+ }
48
+
49
+ return $messages;
50
+ }
51
+
52
+ /**
53
+ * Sets the delimiter, enclosure, and escape character for CSV.
54
+ *
55
+ * @param string $delimiter Delimiter character
56
+ * @param string $enclosure Enclosure character
57
+ * @param string $escape Escape character
58
+ */
59
+ public function setCsvControl($delimiter = ';', $enclosure = '"', $escape = '\\')
60
+ {
61
+ $this->delimiter = $delimiter;
62
+ $this->enclosure = $enclosure;
63
+ $this->escape = $escape;
64
+ }
65
+ }
app/vendor/symfony/translation/Loader/FileLoader.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
15
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
16
+ use Symfony\Component\Config\Resource\FileResource;
17
+
18
+ /**
19
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
20
+ */
21
+ abstract class FileLoader extends ArrayLoader
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function load($resource, $locale, $domain = 'messages')
27
+ {
28
+ if (!stream_is_local($resource)) {
29
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
30
+ }
31
+
32
+ if (!file_exists($resource)) {
33
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
34
+ }
35
+
36
+ $messages = $this->loadResource($resource);
37
+
38
+ // empty resource
39
+ if (null === $messages) {
40
+ $messages = array();
41
+ }
42
+
43
+ // not an array
44
+ if (!is_array($messages)) {
45
+ throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
46
+ }
47
+
48
+ $catalogue = parent::load($messages, $locale, $domain);
49
+
50
+ if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
51
+ $catalogue->addResource(new FileResource($resource));
52
+ }
53
+
54
+ return $catalogue;
55
+ }
56
+
57
+ /**
58
+ * @param string $resource
59
+ *
60
+ * @return array
61
+ *
62
+ * @throws InvalidResourceException if stream content has an invalid format
63
+ */
64
+ abstract protected function loadResource($resource);
65
+ }
app/vendor/symfony/translation/Loader/IcuDatFileLoader.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
16
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
17
+ use Symfony\Component\Config\Resource\FileResource;
18
+
19
+ /**
20
+ * IcuResFileLoader loads translations from a resource bundle.
21
+ *
22
+ * @author stealth35
23
+ */
24
+ class IcuDatFileLoader extends IcuResFileLoader
25
+ {
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ public function load($resource, $locale, $domain = 'messages')
30
+ {
31
+ if (!stream_is_local($resource.'.dat')) {
32
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
33
+ }
34
+
35
+ if (!file_exists($resource.'.dat')) {
36
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
37
+ }
38
+
39
+ try {
40
+ $rb = new \ResourceBundle($locale, $resource);
41
+ } catch (\Exception $e) {
42
+ $rb = null;
43
+ }
44
+
45
+ if (!$rb) {
46
+ throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource));
47
+ } elseif (intl_is_failure($rb->getErrorCode())) {
48
+ throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
49
+ }
50
+
51
+ $messages = $this->flatten($rb);
52
+ $catalogue = new MessageCatalogue($locale);
53
+ $catalogue->add($messages, $domain);
54
+
55
+ if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
56
+ $catalogue->addResource(new FileResource($resource.'.dat'));
57
+ }
58
+
59
+ return $catalogue;
60
+ }
61
+ }
app/vendor/symfony/translation/Loader/IcuResFileLoader.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
16
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
17
+ use Symfony\Component\Config\Resource\DirectoryResource;
18
+
19
+ /**
20
+ * IcuResFileLoader loads translations from a resource bundle.
21
+ *
22
+ * @author stealth35
23
+ */
24
+ class IcuResFileLoader implements LoaderInterface
25
+ {
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ public function load($resource, $locale, $domain = 'messages')
30
+ {
31
+ if (!stream_is_local($resource)) {
32
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
33
+ }
34
+
35
+ if (!is_dir($resource)) {
36
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
37
+ }
38
+
39
+ try {
40
+ $rb = new \ResourceBundle($locale, $resource);
41
+ } catch (\Exception $e) {
42
+ $rb = null;
43
+ }
44
+
45
+ if (!$rb) {
46
+ throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource));
47
+ } elseif (intl_is_failure($rb->getErrorCode())) {
48
+ throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
49
+ }
50
+
51
+ $messages = $this->flatten($rb);
52
+ $catalogue = new MessageCatalogue($locale);
53
+ $catalogue->add($messages, $domain);
54
+
55
+ if (class_exists('Symfony\Component\Config\Resource\DirectoryResource')) {
56
+ $catalogue->addResource(new DirectoryResource($resource));
57
+ }
58
+
59
+ return $catalogue;
60
+ }
61
+
62
+ /**
63
+ * Flattens an ResourceBundle.
64
+ *
65
+ * The scheme used is:
66
+ * key { key2 { key3 { "value" } } }
67
+ * Becomes:
68
+ * 'key.key2.key3' => 'value'
69
+ *
70
+ * This function takes an array by reference and will modify it
71
+ *
72
+ * @param \ResourceBundle $rb The ResourceBundle that will be flattened
73
+ * @param array $messages Used internally for recursive calls
74
+ * @param string $path Current path being parsed, used internally for recursive calls
75
+ *
76
+ * @return array the flattened ResourceBundle
77
+ */
78
+ protected function flatten(\ResourceBundle $rb, array &$messages = array(), $path = null)
79
+ {
80
+ foreach ($rb as $key => $value) {
81
+ $nodePath = $path ? $path.'.'.$key : $key;
82
+ if ($value instanceof \ResourceBundle) {
83
+ $this->flatten($value, $messages, $nodePath);
84
+ } else {
85
+ $messages[$nodePath] = $value;
86
+ }
87
+ }
88
+
89
+ return $messages;
90
+ }
91
+ }
app/vendor/symfony/translation/Loader/IniFileLoader.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ /**
15
+ * IniFileLoader loads translations from an ini file.
16
+ *
17
+ * @author stealth35
18
+ */
19
+ class IniFileLoader extends FileLoader
20
+ {
21
+ /**
22
+ * {@inheritdoc}
23
+ */
24
+ protected function loadResource($resource)
25
+ {
26
+ return parse_ini_file($resource, true);
27
+ }
28
+ }
app/vendor/symfony/translation/Loader/JsonFileLoader.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
15
+
16
+ /**
17
+ * JsonFileLoader loads translations from an json file.
18
+ *
19
+ * @author singles
20
+ */
21
+ class JsonFileLoader extends FileLoader
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ protected function loadResource($resource)
27
+ {
28
+ $messages = array();
29
+ if ($data = file_get_contents($resource)) {
30
+ $messages = json_decode($data, true);
31
+
32
+ if (0 < $errorCode = json_last_error()) {
33
+ throw new InvalidResourceException(sprintf('Error parsing JSON - %s', $this->getJSONErrorMessage($errorCode)));
34
+ }
35
+ }
36
+
37
+ return $messages;
38
+ }
39
+
40
+ /**
41
+ * Translates JSON_ERROR_* constant into meaningful message.
42
+ *
43
+ * @param int $errorCode Error code returned by json_last_error() call
44
+ *
45
+ * @return string Message string
46
+ */
47
+ private function getJSONErrorMessage($errorCode)
48
+ {
49
+ switch ($errorCode) {
50
+ case JSON_ERROR_DEPTH:
51
+ return 'Maximum stack depth exceeded';
52
+ case JSON_ERROR_STATE_MISMATCH:
53
+ return 'Underflow or the modes mismatch';
54
+ case JSON_ERROR_CTRL_CHAR:
55
+ return 'Unexpected control character found';
56
+ case JSON_ERROR_SYNTAX:
57
+ return 'Syntax error, malformed JSON';
58
+ case JSON_ERROR_UTF8:
59
+ return 'Malformed UTF-8 characters, possibly incorrectly encoded';
60
+ default:
61
+ return 'Unknown error';
62
+ }
63
+ }
64
+ }
app/vendor/symfony/translation/Loader/LoaderInterface.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
16
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
17
+
18
+ /**
19
+ * LoaderInterface is the interface implemented by all translation loaders.
20
+ *
21
+ * @author Fabien Potencier <fabien@symfony.com>
22
+ */
23
+ interface LoaderInterface
24
+ {
25
+ /**
26
+ * Loads a locale.
27
+ *
28
+ * @param mixed $resource A resource
29
+ * @param string $locale A locale
30
+ * @param string $domain The domain
31
+ *
32
+ * @return MessageCatalogue A MessageCatalogue instance
33
+ *
34
+ * @throws NotFoundResourceException when the resource cannot be found
35
+ * @throws InvalidResourceException when the resource cannot be loaded
36
+ */
37
+ public function load($resource, $locale, $domain = 'messages');
38
+ }
app/vendor/symfony/translation/Loader/MoFileLoader.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
15
+
16
+ /**
17
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
18
+ */
19
+ class MoFileLoader extends FileLoader
20
+ {
21
+ /**
22
+ * Magic used for validating the format of a MO file as well as
23
+ * detecting if the machine used to create that file was little endian.
24
+ */
25
+ const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;
26
+
27
+ /**
28
+ * Magic used for validating the format of a MO file as well as
29
+ * detecting if the machine used to create that file was big endian.
30
+ */
31
+ const MO_BIG_ENDIAN_MAGIC = 0xde120495;
32
+
33
+ /**
34
+ * The size of the header of a MO file in bytes.
35
+ */
36
+ const MO_HEADER_SIZE = 28;
37
+
38
+ /**
39
+ * Parses machine object (MO) format, independent of the machine's endian it
40
+ * was created on. Both 32bit and 64bit systems are supported.
41
+ *
42
+ * {@inheritdoc}
43
+ */
44
+ protected function loadResource($resource)
45
+ {
46
+ $stream = fopen($resource, 'r');
47
+
48
+ $stat = fstat($stream);
49
+
50
+ if ($stat['size'] < self::MO_HEADER_SIZE) {
51
+ throw new InvalidResourceException('MO stream content has an invalid format.');
52
+ }
53
+ $magic = unpack('V1', fread($stream, 4));
54
+ $magic = hexdec(substr(dechex(current($magic)), -8));
55
+
56
+ if (self::MO_LITTLE_ENDIAN_MAGIC == $magic) {
57
+ $isBigEndian = false;
58
+ } elseif (self::MO_BIG_ENDIAN_MAGIC == $magic) {
59
+ $isBigEndian = true;
60
+ } else {
61
+ throw new InvalidResourceException('MO stream content has an invalid format.');
62
+ }
63
+
64
+ // formatRevision
65
+ $this->readLong($stream, $isBigEndian);
66
+ $count = $this->readLong($stream, $isBigEndian);
67
+ $offsetId = $this->readLong($stream, $isBigEndian);
68
+ $offsetTranslated = $this->readLong($stream, $isBigEndian);
69
+ // sizeHashes
70
+ $this->readLong($stream, $isBigEndian);
71
+ // offsetHashes
72
+ $this->readLong($stream, $isBigEndian);
73
+
74
+ $messages = array();
75
+
76
+ for ($i = 0; $i < $count; ++$i) {
77
+ $pluralId = null;
78
+ $translated = null;
79
+
80
+ fseek($stream, $offsetId + $i * 8);
81
+
82
+ $length = $this->readLong($stream, $isBigEndian);
83
+ $offset = $this->readLong($stream, $isBigEndian);
84
+
85
+ if ($length < 1) {
86
+ continue;
87
+ }
88
+
89
+ fseek($stream, $offset);
90
+ $singularId = fread($stream, $length);
91
+
92
+ if (false !== strpos($singularId, "\000")) {
93
+ list($singularId, $pluralId) = explode("\000", $singularId);
94
+ }
95
+
96
+ fseek($stream, $offsetTranslated + $i * 8);
97
+ $length = $this->readLong($stream, $isBigEndian);
98
+ $offset = $this->readLong($stream, $isBigEndian);
99
+
100
+ if ($length < 1) {
101
+ continue;
102
+ }
103
+
104
+ fseek($stream, $offset);
105
+ $translated = fread($stream, $length);
106
+
107
+ if (false !== strpos($translated, "\000")) {
108
+ $translated = explode("\000", $translated);
109
+ }
110
+
111
+ $ids = array('singular' => $singularId, 'plural' => $pluralId);
112
+ $item = compact('ids', 'translated');
113
+
114
+ if (is_array($item['translated'])) {
115
+ $messages[$item['ids']['singular']] = stripcslashes($item['translated'][0]);
116
+ if (isset($item['ids']['plural'])) {
117
+ $plurals = array();
118
+ foreach ($item['translated'] as $plural => $translated) {
119
+ $plurals[] = sprintf('{%d} %s', $plural, $translated);
120
+ }
121
+ $messages[$item['ids']['plural']] = stripcslashes(implode('|', $plurals));
122
+ }
123
+ } elseif (!empty($item['ids']['singular'])) {
124
+ $messages[$item['ids']['singular']] = stripcslashes($item['translated']);
125
+ }
126
+ }
127
+
128
+ fclose($stream);
129
+
130
+ return array_filter($messages);
131
+ }
132
+
133
+ /**
134
+ * Reads an unsigned long from stream respecting endianness.
135
+ *
136
+ * @param resource $stream
137
+ */
138
+ private function readLong($stream, bool $isBigEndian): int
139
+ {
140
+ $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
141
+ $result = current($result);
142
+
143
+ return (int) substr($result, -8);
144
+ }
145
+ }
app/vendor/symfony/translation/Loader/PhpFileLoader.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ /**
15
+ * PhpFileLoader loads translations from PHP files returning an array of translations.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class PhpFileLoader extends FileLoader
20
+ {
21
+ /**
22
+ * {@inheritdoc}
23
+ */
24
+ protected function loadResource($resource)
25
+ {
26
+ return require $resource;
27
+ }
28
+ }
app/vendor/symfony/translation/Loader/PoFileLoader.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ /**
15
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
16
+ * @copyright Copyright (c) 2012, Clemens Tolboom
17
+ */
18
+ class PoFileLoader extends FileLoader
19
+ {
20
+ /**
21
+ * Parses portable object (PO) format.
22
+ *
23
+ * From http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
24
+ * we should be able to parse files having:
25
+ *
26
+ * white-space
27
+ * # translator-comments
28
+ * #. extracted-comments
29
+ * #: reference...
30
+ * #, flag...
31
+ * #| msgid previous-untranslated-string
32
+ * msgid untranslated-string
33
+ * msgstr translated-string
34
+ *
35
+ * extra or different lines are:
36
+ *
37
+ * #| msgctxt previous-context
38
+ * #| msgid previous-untranslated-string
39
+ * msgctxt context
40
+ *
41
+ * #| msgid previous-untranslated-string-singular
42
+ * #| msgid_plural previous-untranslated-string-plural
43
+ * msgid untranslated-string-singular
44
+ * msgid_plural untranslated-string-plural
45
+ * msgstr[0] translated-string-case-0
46
+ * ...
47
+ * msgstr[N] translated-string-case-n
48
+ *
49
+ * The definition states:
50
+ * - white-space and comments are optional.
51
+ * - msgid "" that an empty singleline defines a header.
52
+ *
53
+ * This parser sacrifices some features of the reference implementation the
54
+ * differences to that implementation are as follows.
55
+ * - No support for comments spanning multiple lines.
56
+ * - Translator and extracted comments are treated as being the same type.
57
+ * - Message IDs are allowed to have other encodings as just US-ASCII.
58
+ *
59
+ * Items with an empty id are ignored.
60
+ *
61
+ * {@inheritdoc}
62
+ */
63
+ protected function loadResource($resource)
64
+ {
65
+ $stream = fopen($resource, 'r');
66
+
67
+ $defaults = array(
68
+ 'ids' => array(),
69
+ 'translated' => null,
70
+ );
71
+
72
+ $messages = array();
73
+ $item = $defaults;
74
+ $flags = array();
75
+
76
+ while ($line = fgets($stream)) {
77
+ $line = trim($line);
78
+
79
+ if ('' === $line) {
80
+ // Whitespace indicated current item is done
81
+ if (!in_array('fuzzy', $flags)) {
82
+ $this->addMessage($messages, $item);
83
+ }
84
+ $item = $defaults;
85
+ $flags = array();
86
+ } elseif ('#,' === substr($line, 0, 2)) {
87
+ $flags = array_map('trim', explode(',', substr($line, 2)));
88
+ } elseif ('msgid "' === substr($line, 0, 7)) {
89
+ // We start a new msg so save previous
90
+ // TODO: this fails when comments or contexts are added
91
+ $this->addMessage($messages, $item);
92
+ $item = $defaults;
93
+ $item['ids']['singular'] = substr($line, 7, -1);
94
+ } elseif ('msgstr "' === substr($line, 0, 8)) {
95
+ $item['translated'] = substr($line, 8, -1);
96
+ } elseif ('"' === $line[0]) {
97
+ $continues = isset($item['translated']) ? 'translated' : 'ids';
98
+
99
+ if (is_array($item[$continues])) {
100
+ end($item[$continues]);
101
+ $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
102
+ } else {
103
+ $item[$continues] .= substr($line, 1, -1);
104
+ }
105
+ } elseif ('msgid_plural "' === substr($line, 0, 14)) {
106
+ $item['ids']['plural'] = substr($line, 14, -1);
107
+ } elseif ('msgstr[' === substr($line, 0, 7)) {
108
+ $size = strpos($line, ']');
109
+ $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
110
+ }
111
+ }
112
+ // save last item
113
+ if (!in_array('fuzzy', $flags)) {
114
+ $this->addMessage($messages, $item);
115
+ }
116
+ fclose($stream);
117
+
118
+ return $messages;
119
+ }
120
+
121
+ /**
122
+ * Save a translation item to the messages.
123
+ *
124
+ * A .po file could contain by error missing plural indexes. We need to
125
+ * fix these before saving them.
126
+ */
127
+ private function addMessage(array &$messages, array $item)
128
+ {
129
+ if (is_array($item['translated'])) {
130
+ $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated'][0]);
131
+ if (isset($item['ids']['plural'])) {
132
+ $plurals = $item['translated'];
133
+ // PO are by definition indexed so sort by index.
134
+ ksort($plurals);
135
+ // Make sure every index is filled.
136
+ end($plurals);
137
+ $count = key($plurals);
138
+ // Fill missing spots with '-'.
139
+ $empties = array_fill(0, $count + 1, '-');
140
+ $plurals += $empties;
141
+ ksort($plurals);
142
+ $messages[stripcslashes($item['ids']['plural'])] = stripcslashes(implode('|', $plurals));
143
+ }
144
+ } elseif (!empty($item['ids']['singular'])) {
145
+ $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated']);
146
+ }
147
+ }
148
+ }
app/vendor/symfony/translation/Loader/QtFileLoader.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Config\Util\XmlUtils;
15
+ use Symfony\Component\Translation\MessageCatalogue;
16
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
17
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
18
+ use Symfony\Component\Config\Resource\FileResource;
19
+
20
+ /**
21
+ * QtFileLoader loads translations from QT Translations XML files.
22
+ *
23
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
24
+ */
25
+ class QtFileLoader implements LoaderInterface
26
+ {
27
+ /**
28
+ * {@inheritdoc}
29
+ */
30
+ public function load($resource, $locale, $domain = 'messages')
31
+ {
32
+ if (!stream_is_local($resource)) {
33
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
34
+ }
35
+
36
+ if (!file_exists($resource)) {
37
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
38
+ }
39
+
40
+ try {
41
+ $dom = XmlUtils::loadFile($resource);
42
+ } catch (\InvalidArgumentException $e) {
43
+ throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
44
+ }
45
+
46
+ $internalErrors = libxml_use_internal_errors(true);
47
+ libxml_clear_errors();
48
+
49
+ $xpath = new \DOMXPath($dom);
50
+ $nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');
51
+
52
+ $catalogue = new MessageCatalogue($locale);
53
+ if (1 == $nodes->length) {
54
+ $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
55
+ foreach ($translations as $translation) {
56
+ $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue;
57
+
58
+ if (!empty($translationValue)) {
59
+ $catalogue->set(
60
+ (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
61
+ $translationValue,
62
+ $domain
63
+ );
64
+ }
65
+ $translation = $translation->nextSibling;
66
+ }
67
+
68
+ if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
69
+ $catalogue->addResource(new FileResource($resource));
70
+ }
71
+ }
72
+
73
+ libxml_use_internal_errors($internalErrors);
74
+
75
+ return $catalogue;
76
+ }
77
+ }
app/vendor/symfony/translation/Loader/XliffFileLoader.php ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Config\Util\XmlUtils;
15
+ use Symfony\Component\Translation\MessageCatalogue;
16
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
17
+ use Symfony\Component\Translation\Exception\NotFoundResourceException;
18
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
19
+ use Symfony\Component\Config\Resource\FileResource;
20
+
21
+ /**
22
+ * XliffFileLoader loads translations from XLIFF files.
23
+ *
24
+ * @author Fabien Potencier <fabien@symfony.com>
25
+ */
26
+ class XliffFileLoader implements LoaderInterface
27
+ {
28
+ /**
29
+ * {@inheritdoc}
30
+ */
31
+ public function load($resource, $locale, $domain = 'messages')
32
+ {
33
+ if (!stream_is_local($resource)) {
34
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
35
+ }
36
+
37
+ if (!file_exists($resource)) {
38
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
39
+ }
40
+
41
+ $catalogue = new MessageCatalogue($locale);
42
+ $this->extract($resource, $catalogue, $domain);
43
+
44
+ if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
45
+ $catalogue->addResource(new FileResource($resource));
46
+ }
47
+
48
+ return $catalogue;
49
+ }
50
+
51
+ private function extract($resource, MessageCatalogue $catalogue, $domain)
52
+ {
53
+ try {
54
+ $dom = XmlUtils::loadFile($resource);
55
+ } catch (\InvalidArgumentException $e) {
56
+ throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $resource, $e->getMessage()), $e->getCode(), $e);
57
+ }
58
+
59
+ $xliffVersion = $this->getVersionNumber($dom);
60
+ $this->validateSchema($xliffVersion, $dom, $this->getSchema($xliffVersion));
61
+
62
+ if ('1.2' === $xliffVersion) {
63
+ $this->extractXliff1($dom, $catalogue, $domain);
64
+ }
65
+
66
+ if ('2.0' === $xliffVersion) {
67
+ $this->extractXliff2($dom, $catalogue, $domain);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Extract messages and metadata from DOMDocument into a MessageCatalogue.
73
+ *
74
+ * @param \DOMDocument $dom Source to extract messages and metadata
75
+ * @param MessageCatalogue $catalogue Catalogue where we'll collect messages and metadata
76
+ * @param string $domain The domain
77
+ */
78
+ private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
79
+ {
80
+ $xml = simplexml_import_dom($dom);
81
+ $encoding = strtoupper($dom->encoding);
82
+
83
+ $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
84
+ foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
85
+ $attributes = $translation->attributes();
86
+
87
+ if (!(isset($attributes['resname']) || isset($translation->source))) {
88
+ continue;
89
+ }
90
+
91
+ $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
92
+ // If the xlf file has another encoding specified, try to convert it because
93
+ // simple_xml will always return utf-8 encoded values
94
+ $target = $this->utf8ToCharset((string) (isset($translation->target) ? $translation->target : $source), $encoding);
95
+
96
+ $catalogue->set((string) $source, $target, $domain);
97
+
98
+ $metadata = array();
99
+ if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) {
100
+ $metadata['notes'] = $notes;
101
+ }
102
+
103
+ if (isset($translation->target) && $translation->target->attributes()) {
104
+ $metadata['target-attributes'] = array();
105
+ foreach ($translation->target->attributes() as $key => $value) {
106
+ $metadata['target-attributes'][$key] = (string) $value;
107
+ }
108
+ }
109
+
110
+ if (isset($attributes['id'])) {
111
+ $metadata['id'] = (string) $attributes['id'];
112
+ }
113
+
114
+ $catalogue->setMetadata((string) $source, $metadata, $domain);
115
+ }
116
+ }
117
+
118
+ private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
119
+ {
120
+ $xml = simplexml_import_dom($dom);
121
+ $encoding = strtoupper($dom->encoding);
122
+
123
+ $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');
124
+
125
+ foreach ($xml->xpath('//xliff:unit') as $unit) {
126
+ foreach ($unit->segment as $segment) {
127
+ $source = $segment->source;
128
+
129
+ // If the xlf file has another encoding specified, try to convert it because
130
+ // simple_xml will always return utf-8 encoded values
131
+ $target = $this->utf8ToCharset((string) (isset($segment->target) ? $segment->target : $source), $encoding);
132
+
133
+ $catalogue->set((string) $source, $target, $domain);
134
+
135
+ $metadata = array();
136
+ if (isset($segment->target) && $segment->target->attributes()) {
137
+ $metadata['target-attributes'] = array();
138
+ foreach ($segment->target->attributes() as $key => $value) {
139
+ $metadata['target-attributes'][$key] = (string) $value;
140
+ }
141
+ }
142
+
143
+ if (isset($unit->notes)) {
144
+ $metadata['notes'] = array();
145
+ foreach ($unit->notes->note as $noteNode) {
146
+ $note = array();
147
+ foreach ($noteNode->attributes() as $key => $value) {
148
+ $note[$key] = (string) $value;
149
+ }
150
+ $note['content'] = (string) $noteNode;
151
+ $metadata['notes'][] = $note;
152
+ }
153
+ }
154
+
155
+ $catalogue->setMetadata((string) $source, $metadata, $domain);
156
+ }
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Convert a UTF8 string to the specified encoding.
162
+ */
163
+ private function utf8ToCharset(string $content, string $encoding = null): string
164
+ {
165
+ if ('UTF-8' !== $encoding && !empty($encoding)) {
166
+ return mb_convert_encoding($content, $encoding, 'UTF-8');
167
+ }
168
+
169
+ return $content;
170
+ }
171
+
172
+ /**
173
+ * Validates and parses the given file into a DOMDocument.
174
+ *
175
+ * @throws InvalidResourceException
176
+ */
177
+ private function validateSchema(string $file, \DOMDocument $dom, string $schema)
178
+ {
179
+ $internalErrors = libxml_use_internal_errors(true);
180
+
181
+ $disableEntities = libxml_disable_entity_loader(false);
182
+
183
+ if (!@$dom->schemaValidateSource($schema)) {
184
+ libxml_disable_entity_loader($disableEntities);
185
+
186
+ throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $file, implode("\n", $this->getXmlErrors($internalErrors))));
187
+ }
188
+
189
+ libxml_disable_entity_loader($disableEntities);
190
+
191
+ $dom->normalizeDocument();
192
+
193
+ libxml_clear_errors();
194
+ libxml_use_internal_errors($internalErrors);
195
+ }
196
+
197
+ private function getSchema($xliffVersion)
198
+ {
199
+ if ('1.2' === $xliffVersion) {
200
+ $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd');
201
+ $xmlUri = 'http://www.w3.org/2001/xml.xsd';
202
+ } elseif ('2.0' === $xliffVersion) {
203
+ $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-2.0.xsd');
204
+ $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd';
205
+ } else {
206
+ throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
207
+ }
208
+
209
+ return $this->fixXmlLocation($schemaSource, $xmlUri);
210
+ }
211
+
212
+ /**
213
+ * Internally changes the URI of a dependent xsd to be loaded locally.
214
+ */
215
+ private function fixXmlLocation(string $schemaSource, string $xmlUri): string
216
+ {
217
+ $newPath = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
218
+ $parts = explode('/', $newPath);
219
+ $locationstart = 'file:///';
220
+ if (0 === stripos($newPath, 'phar://')) {
221
+ $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
222
+ if ($tmpfile) {
223
+ copy($newPath, $tmpfile);
224
+ $parts = explode('/', str_replace('\\', '/', $tmpfile));
225
+ } else {
226
+ array_shift($parts);
227
+ $locationstart = 'phar:///';
228
+ }
229
+ }
230
+
231
+ $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
232
+ $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));
233
+
234
+ return str_replace($xmlUri, $newPath, $schemaSource);
235
+ }
236
+
237
+ /**
238
+ * Returns the XML errors of the internal XML parser.
239
+ */
240
+ private function getXmlErrors(bool $internalErrors): array
241
+ {
242
+ $errors = array();
243
+ foreach (libxml_get_errors() as $error) {
244
+ $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
245
+ LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
246
+ $error->code,
247
+ trim($error->message),
248
+ $error->file ?: 'n/a',
249
+ $error->line,
250
+ $error->column
251
+ );
252
+ }
253
+
254
+ libxml_clear_errors();
255
+ libxml_use_internal_errors($internalErrors);
256
+
257
+ return $errors;
258
+ }
259
+
260
+ /**
261
+ * Gets xliff file version based on the root "version" attribute.
262
+ * Defaults to 1.2 for backwards compatibility.
263
+ *
264
+ * @throws InvalidArgumentException
265
+ */
266
+ private function getVersionNumber(\DOMDocument $dom): string
267
+ {
268
+ /** @var \DOMNode $xliff */
269
+ foreach ($dom->getElementsByTagName('xliff') as $xliff) {
270
+ $version = $xliff->attributes->getNamedItem('version');
271
+ if ($version) {
272
+ return $version->nodeValue;
273
+ }
274
+
275
+ $namespace = $xliff->attributes->getNamedItem('xmlns');
276
+ if ($namespace) {
277
+ if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) {
278
+ throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace));
279
+ }
280
+
281
+ return substr($namespace, 34);
282
+ }
283
+ }
284
+
285
+ // Falls back to v1.2
286
+ return '1.2';
287
+ }
288
+
289
+ private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, string $encoding = null): array
290
+ {
291
+ $notes = array();
292
+
293
+ if (null === $noteElement) {
294
+ return $notes;
295
+ }
296
+
297
+ /** @var \SimpleXMLElement $xmlNote */
298
+ foreach ($noteElement as $xmlNote) {
299
+ $noteAttributes = $xmlNote->attributes();
300
+ $note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
301
+ if (isset($noteAttributes['priority'])) {
302
+ $note['priority'] = (int) $noteAttributes['priority'];
303
+ }
304
+
305
+ if (isset($noteAttributes['from'])) {
306
+ $note['from'] = (string) $noteAttributes['from'];
307
+ }
308
+
309
+ $notes[] = $note;
310
+ }
311
+
312
+ return $notes;
313
+ }
314
+ }
app/vendor/symfony/translation/Loader/YamlFileLoader.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Loader;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidResourceException;
15
+ use Symfony\Component\Translation\Exception\LogicException;
16
+ use Symfony\Component\Yaml\Parser as YamlParser;
17
+ use Symfony\Component\Yaml\Exception\ParseException;
18
+ use Symfony\Component\Yaml\Yaml;
19
+
20
+ /**
21
+ * YamlFileLoader loads translations from Yaml files.
22
+ *
23
+ * @author Fabien Potencier <fabien@symfony.com>
24
+ */
25
+ class YamlFileLoader extends FileLoader
26
+ {
27
+ private $yamlParser;
28
+
29
+ /**
30
+ * {@inheritdoc}
31
+ */
32
+ protected function loadResource($resource)
33
+ {
34
+ if (null === $this->yamlParser) {
35
+ if (!class_exists('Symfony\Component\Yaml\Parser')) {
36
+ throw new LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
37
+ }
38
+
39
+ $this->yamlParser = new YamlParser();
40
+ }
41
+
42
+ try {
43
+ $messages = $this->yamlParser->parseFile($resource, Yaml::PARSE_CONSTANT);
44
+ } catch (ParseException $e) {
45
+ throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e);
46
+ }
47
+
48
+ return $messages;
49
+ }
50
+ }
app/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd ADDED
@@ -0,0 +1,2223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!--
4
+
5
+ May-19-2004:
6
+ - Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements
7
+ to <choice> itself.
8
+ - Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
9
+ <alt-trans>.
10
+
11
+ Oct-2005
12
+ - updated version info to 1.2
13
+ - equiv-trans attribute to <trans-unit> element
14
+ - merged-trans attribute for <group> element
15
+ - Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source>
16
+ - Create a new value "seg" for the mtype attribute of the <mrk> element
17
+ - Add mid as an optional attribute for the <alt-trans> element
18
+
19
+ Nov-14-2005
20
+ - Changed name attribute for <context-group> from required to optional
21
+ - Added extension point at <xliff>
22
+
23
+ Jan-9-2006
24
+ - Added alttranstype type attribute to <alt-trans>, and values
25
+
26
+ Jan-10-2006
27
+ - Corrected error with overwritten purposeValueList
28
+ - Corrected name="AttrType_Version", attribute should have been "name"
29
+
30
+ -->
31
+ <xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
32
+ <!-- Import for xml:lang and xml:space -->
33
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
34
+ <!-- Attributes Lists -->
35
+ <xsd:simpleType name="XTend">
36
+ <xsd:restriction base="xsd:string">
37
+ <xsd:pattern value="x-[^\s]+"/>
38
+ </xsd:restriction>
39
+ </xsd:simpleType>
40
+ <xsd:simpleType name="context-typeValueList">
41
+ <xsd:annotation>
42
+ <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
43
+ </xsd:annotation>
44
+ <xsd:restriction base="xsd:string">
45
+ <xsd:enumeration value="database">
46
+ <xsd:annotation>
47
+ <xsd:documentation>Indicates a database content.</xsd:documentation>
48
+ </xsd:annotation>
49
+ </xsd:enumeration>
50
+ <xsd:enumeration value="element">
51
+ <xsd:annotation>
52
+ <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
53
+ </xsd:annotation>
54
+ </xsd:enumeration>
55
+ <xsd:enumeration value="elementtitle">
56
+ <xsd:annotation>
57
+ <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
58
+ </xsd:annotation>
59
+ </xsd:enumeration>
60
+ <xsd:enumeration value="linenumber">
61
+ <xsd:annotation>
62
+ <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
63
+ </xsd:annotation>
64
+ </xsd:enumeration>
65
+ <xsd:enumeration value="numparams">
66
+ <xsd:annotation>
67
+ <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
68
+ </xsd:annotation>
69
+ </xsd:enumeration>
70
+ <xsd:enumeration value="paramnotes">
71
+ <xsd:annotation>
72
+ <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
73
+ </xsd:annotation>
74
+ </xsd:enumeration>
75
+ <xsd:enumeration value="record">
76
+ <xsd:annotation>
77
+ <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
78
+ </xsd:annotation>
79
+ </xsd:enumeration>
80
+ <xsd:enumeration value="recordtitle">
81
+ <xsd:annotation>
82
+ <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
83
+ </xsd:annotation>
84
+ </xsd:enumeration>
85
+ <xsd:enumeration value="sourcefile">
86
+ <xsd:annotation>
87
+ <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
88
+ </xsd:annotation>
89
+ </xsd:enumeration>
90
+ </xsd:restriction>
91
+ </xsd:simpleType>
92
+ <xsd:simpleType name="count-typeValueList">
93
+ <xsd:annotation>
94
+ <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
95
+ </xsd:annotation>
96
+ <xsd:restriction base="xsd:NMTOKEN">
97
+ <xsd:enumeration value="num-usages">
98
+ <xsd:annotation>
99
+ <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
100
+ </xsd:annotation>
101
+ </xsd:enumeration>
102
+ <xsd:enumeration value="repetition">
103
+ <xsd:annotation>
104
+ <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
105
+ </xsd:annotation>
106
+ </xsd:enumeration>
107
+ <xsd:enumeration value="total">
108
+ <xsd:annotation>
109
+ <xsd:documentation>Indicates a total count.</xsd:documentation>
110
+ </xsd:annotation>
111
+ </xsd:enumeration>
112
+ </xsd:restriction>
113
+ </xsd:simpleType>
114
+ <xsd:simpleType name="InlineDelimitersValueList">
115
+ <xsd:annotation>
116
+ <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
117
+ </xsd:annotation>
118
+ <xsd:restriction base="xsd:NMTOKEN">
119
+ <xsd:enumeration value="bold">
120
+ <xsd:annotation>
121
+ <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
122
+ </xsd:annotation>
123
+ </xsd:enumeration>
124
+ <xsd:enumeration value="italic">
125
+ <xsd:annotation>
126
+ <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
127
+ </xsd:annotation>
128
+ </xsd:enumeration>
129
+ <xsd:enumeration value="underlined">
130
+ <xsd:annotation>
131
+ <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
132
+ </xsd:annotation>
133
+ </xsd:enumeration>
134
+ <xsd:enumeration value="link">
135
+ <xsd:annotation>
136
+ <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
137
+ </xsd:annotation>
138
+ </xsd:enumeration>
139
+ </xsd:restriction>
140
+ </xsd:simpleType>
141
+ <xsd:simpleType name="InlinePlaceholdersValueList">
142
+ <xsd:annotation>
143
+ <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
144
+ </xsd:annotation>
145
+ <xsd:restriction base="xsd:NMTOKEN">
146
+ <xsd:enumeration value="image">
147
+ <xsd:annotation>
148
+ <xsd:documentation>Indicates a inline image.</xsd:documentation>
149
+ </xsd:annotation>
150
+ </xsd:enumeration>
151
+ <xsd:enumeration value="pb">
152
+ <xsd:annotation>
153
+ <xsd:documentation>Indicates a page break.</xsd:documentation>
154
+ </xsd:annotation>
155
+ </xsd:enumeration>
156
+ <xsd:enumeration value="lb">
157
+ <xsd:annotation>
158
+ <xsd:documentation>Indicates a line break.</xsd:documentation>
159
+ </xsd:annotation>
160
+ </xsd:enumeration>
161
+ </xsd:restriction>
162
+ </xsd:simpleType>
163
+ <xsd:simpleType name="mime-typeValueList">
164
+ <xsd:restriction base="xsd:string">
165
+ <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
166
+ </xsd:restriction>
167
+ </xsd:simpleType>
168
+ <xsd:simpleType name="datatypeValueList">
169
+ <xsd:annotation>
170
+ <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
171
+ </xsd:annotation>
172
+ <xsd:restriction base="xsd:NMTOKEN">
173
+ <xsd:enumeration value="asp">
174
+ <xsd:annotation>
175
+ <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
176
+ </xsd:annotation>
177
+ </xsd:enumeration>
178
+ <xsd:enumeration value="c">
179
+ <xsd:annotation>
180
+ <xsd:documentation>Indicates C source file data.</xsd:documentation>
181
+ </xsd:annotation>
182
+ </xsd:enumeration>
183
+ <xsd:enumeration value="cdf">
184
+ <xsd:annotation>
185
+ <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
186
+ </xsd:annotation>
187
+ </xsd:enumeration>
188
+ <xsd:enumeration value="cfm">
189
+ <xsd:annotation>
190
+ <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
191
+ </xsd:annotation>
192
+ </xsd:enumeration>
193
+ <xsd:enumeration value="cpp">
194
+ <xsd:annotation>
195
+ <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
196
+ </xsd:annotation>
197
+ </xsd:enumeration>
198
+ <xsd:enumeration value="csharp">
199
+ <xsd:annotation>
200
+ <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
201
+ </xsd:annotation>
202
+ </xsd:enumeration>
203
+ <xsd:enumeration value="cstring">
204
+ <xsd:annotation>
205
+ <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
206
+ </xsd:annotation>
207
+ </xsd:enumeration>
208
+ <xsd:enumeration value="csv">
209
+ <xsd:annotation>
210
+ <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
211
+ </xsd:annotation>
212
+ </xsd:enumeration>
213
+ <xsd:enumeration value="database">
214
+ <xsd:annotation>
215
+ <xsd:documentation>Indicates database data.</xsd:documentation>
216
+ </xsd:annotation>
217
+ </xsd:enumeration>
218
+ <xsd:enumeration value="documentfooter">
219
+ <xsd:annotation>
220
+ <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
221
+ </xsd:annotation>
222
+ </xsd:enumeration>
223
+ <xsd:enumeration value="documentheader">
224
+ <xsd:annotation>
225
+ <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
226
+ </xsd:annotation>
227
+ </xsd:enumeration>
228
+ <xsd:enumeration value="filedialog">
229
+ <xsd:annotation>
230
+ <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
231
+ </xsd:annotation>
232
+ </xsd:enumeration>
233
+ <xsd:enumeration value="form">
234
+ <xsd:annotation>
235
+ <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
236
+ </xsd:annotation>
237
+ </xsd:enumeration>
238
+ <xsd:enumeration value="html">
239
+ <xsd:annotation>
240
+ <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
241
+ </xsd:annotation>
242
+ </xsd:enumeration>
243
+ <xsd:enumeration value="htmlbody">
244
+ <xsd:annotation>
245
+ <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
246
+ </xsd:annotation>
247
+ </xsd:enumeration>
248
+ <xsd:enumeration value="ini">
249
+ <xsd:annotation>
250
+ <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
251
+ </xsd:annotation>
252
+ </xsd:enumeration>
253
+ <xsd:enumeration value="interleaf">
254
+ <xsd:annotation>
255
+ <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
256
+ </xsd:annotation>
257
+ </xsd:enumeration>
258
+ <xsd:enumeration value="javaclass">
259
+ <xsd:annotation>
260
+ <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
261
+ </xsd:annotation>
262
+ </xsd:enumeration>
263
+ <xsd:enumeration value="javapropertyresourcebundle">
264
+ <xsd:annotation>
265
+ <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
266
+ </xsd:annotation>
267
+ </xsd:enumeration>
268
+ <xsd:enumeration value="javalistresourcebundle">
269
+ <xsd:annotation>
270
+ <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
271
+ </xsd:annotation>
272
+ </xsd:enumeration>
273
+ <xsd:enumeration value="javascript">
274
+ <xsd:annotation>
275
+ <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
276
+ </xsd:annotation>
277
+ </xsd:enumeration>
278
+ <xsd:enumeration value="jscript">
279
+ <xsd:annotation>
280
+ <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
281
+ </xsd:annotation>
282
+ </xsd:enumeration>
283
+ <xsd:enumeration value="layout">
284
+ <xsd:annotation>
285
+ <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
286
+ </xsd:annotation>
287
+ </xsd:enumeration>
288
+ <xsd:enumeration value="lisp">
289
+ <xsd:annotation>
290
+ <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
291
+ </xsd:annotation>
292
+ </xsd:enumeration>
293
+ <xsd:enumeration value="margin">
294
+ <xsd:annotation>
295
+ <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
296
+ </xsd:annotation>
297
+ </xsd:enumeration>
298
+ <xsd:enumeration value="menufile">
299
+ <xsd:annotation>
300
+ <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
301
+ </xsd:annotation>
302
+ </xsd:enumeration>
303
+ <xsd:enumeration value="messagefile">
304
+ <xsd:annotation>
305
+ <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
306
+ </xsd:annotation>
307
+ </xsd:enumeration>
308
+ <xsd:enumeration value="mif">
309
+ <xsd:annotation>
310
+ <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
311
+ </xsd:annotation>
312
+ </xsd:enumeration>
313
+ <xsd:enumeration value="mimetype">
314
+ <xsd:annotation>
315
+ <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
316
+ </xsd:annotation>
317
+ </xsd:enumeration>
318
+ <xsd:enumeration value="mo">
319
+ <xsd:annotation>
320
+ <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
321
+ </xsd:annotation>
322
+ </xsd:enumeration>
323
+ <xsd:enumeration value="msglib">
324
+ <xsd:annotation>
325
+ <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
326
+ </xsd:annotation>
327
+ </xsd:enumeration>
328
+ <xsd:enumeration value="pagefooter">
329
+ <xsd:annotation>
330
+ <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
331
+ </xsd:annotation>
332
+ </xsd:enumeration>
333
+ <xsd:enumeration value="pageheader">
334
+ <xsd:annotation>
335
+ <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
336
+ </xsd:annotation>
337
+ </xsd:enumeration>
338
+ <xsd:enumeration value="parameters">
339
+ <xsd:annotation>
340
+ <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
341
+ </xsd:annotation>
342
+ </xsd:enumeration>
343
+ <xsd:enumeration value="pascal">
344
+ <xsd:annotation>
345
+ <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
346
+ </xsd:annotation>
347
+ </xsd:enumeration>
348
+ <xsd:enumeration value="php">
349
+ <xsd:annotation>
350
+ <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
351
+ </xsd:annotation>
352
+ </xsd:enumeration>
353
+ <xsd:enumeration value="plaintext">
354
+ <xsd:annotation>
355
+ <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
356
+ </xsd:annotation>
357
+ </xsd:enumeration>
358
+ <xsd:enumeration value="po">
359
+ <xsd:annotation>
360
+ <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
361
+ </xsd:annotation>
362
+ </xsd:enumeration>
363
+ <xsd:enumeration value="report">
364
+ <xsd:annotation>
365
+ <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
366
+ </xsd:annotation>
367
+ </xsd:enumeration>
368
+ <xsd:enumeration value="resources">
369
+ <xsd:annotation>
370
+ <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
371
+ </xsd:annotation>
372
+ </xsd:enumeration>
373
+ <xsd:enumeration value="resx">
374
+ <xsd:annotation>
375
+ <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
376
+ </xsd:annotation>
377
+ </xsd:enumeration>
378
+ <xsd:enumeration value="rtf">
379
+ <xsd:annotation>
380
+ <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
381
+ </xsd:annotation>
382
+ </xsd:enumeration>
383
+ <xsd:enumeration value="sgml">
384
+ <xsd:annotation>
385
+ <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
386
+ </xsd:annotation>
387
+ </xsd:enumeration>
388
+ <xsd:enumeration value="sgmldtd">
389
+ <xsd:annotation>
390
+ <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
391
+ </xsd:annotation>
392
+ </xsd:enumeration>
393
+ <xsd:enumeration value="svg">
394
+ <xsd:annotation>
395
+ <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
396
+ </xsd:annotation>
397
+ </xsd:enumeration>
398
+ <xsd:enumeration value="vbscript">
399
+ <xsd:annotation>
400
+ <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
401
+ </xsd:annotation>
402
+ </xsd:enumeration>
403
+ <xsd:enumeration value="warning">
404
+ <xsd:annotation>
405
+ <xsd:documentation>Indicates warning message.</xsd:documentation>
406
+ </xsd:annotation>
407
+ </xsd:enumeration>
408
+ <xsd:enumeration value="winres">
409
+ <xsd:annotation>
410
+ <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
411
+ </xsd:annotation>
412
+ </xsd:enumeration>
413
+ <xsd:enumeration value="xhtml">
414
+ <xsd:annotation>
415
+ <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
416
+ </xsd:annotation>
417
+ </xsd:enumeration>
418
+ <xsd:enumeration value="xml">
419
+ <xsd:annotation>
420
+ <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
421
+ </xsd:annotation>
422
+ </xsd:enumeration>
423
+ <xsd:enumeration value="xmldtd">
424
+ <xsd:annotation>
425
+ <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
426
+ </xsd:annotation>
427
+ </xsd:enumeration>
428
+ <xsd:enumeration value="xsl">
429
+ <xsd:annotation>
430
+ <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
431
+ </xsd:annotation>
432
+ </xsd:enumeration>
433
+ <xsd:enumeration value="xul">
434
+ <xsd:annotation>
435
+ <xsd:documentation>Indicates XUL elements.</xsd:documentation>
436
+ </xsd:annotation>
437
+ </xsd:enumeration>
438
+ </xsd:restriction>
439
+ </xsd:simpleType>
440
+ <xsd:simpleType name="mtypeValueList">
441
+ <xsd:annotation>
442
+ <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
443
+ </xsd:annotation>
444
+ <xsd:restriction base="xsd:NMTOKEN">
445
+ <xsd:enumeration value="abbrev">
446
+ <xsd:annotation>
447
+ <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
448
+ </xsd:annotation>
449
+ </xsd:enumeration>
450
+ <xsd:enumeration value="abbreviated-form">
451
+ <xsd:annotation>
452
+ <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
453
+ </xsd:annotation>
454
+ </xsd:enumeration>
455
+ <xsd:enumeration value="abbreviation">
456
+ <xsd:annotation>
457
+ <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
458
+ </xsd:annotation>
459
+ </xsd:enumeration>
460
+ <xsd:enumeration value="acronym">
461
+ <xsd:annotation>
462
+ <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
463
+ </xsd:annotation>
464
+ </xsd:enumeration>
465
+ <xsd:enumeration value="appellation">
466
+ <xsd:annotation>
467
+ <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
468
+ </xsd:annotation>
469
+ </xsd:enumeration>
470
+ <xsd:enumeration value="collocation">
471
+ <xsd:annotation>
472
+ <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
473
+ </xsd:annotation>
474
+ </xsd:enumeration>
475
+ <xsd:enumeration value="common-name">
476
+ <xsd:annotation>
477
+ <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
478
+ </xsd:annotation>
479
+ </xsd:enumeration>
480
+ <xsd:enumeration value="datetime">
481
+ <xsd:annotation>
482
+ <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
483
+ </xsd:annotation>
484
+ </xsd:enumeration>
485
+ <xsd:enumeration value="equation">
486
+ <xsd:annotation>
487
+ <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
488
+ </xsd:annotation>
489
+ </xsd:enumeration>
490
+ <xsd:enumeration value="expanded-form">
491
+ <xsd:annotation>
492
+ <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
493
+ </xsd:annotation>
494
+ </xsd:enumeration>
495
+ <xsd:enumeration value="formula">
496
+ <xsd:annotation>
497
+ <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
498
+ </xsd:annotation>
499
+ </xsd:enumeration>
500
+ <xsd:enumeration value="head-term">
501
+ <xsd:annotation>
502
+ <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
503
+ </xsd:annotation>
504
+ </xsd:enumeration>
505
+ <xsd:enumeration value="initialism">
506
+ <xsd:annotation>
507
+ <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
508
+ </xsd:annotation>
509
+ </xsd:enumeration>
510
+ <xsd:enumeration value="international-scientific-term">
511
+ <xsd:annotation>
512
+ <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
513
+ </xsd:annotation>
514
+ </xsd:enumeration>
515
+ <xsd:enumeration value="internationalism">
516
+ <xsd:annotation>
517
+ <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
518
+ </xsd:annotation>
519
+ </xsd:enumeration>
520
+ <xsd:enumeration value="logical-expression">
521
+ <xsd:annotation>
522
+ <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
523
+ </xsd:annotation>
524
+ </xsd:enumeration>
525
+ <xsd:enumeration value="materials-management-unit">
526
+ <xsd:annotation>
527
+ <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
528
+ </xsd:annotation>
529
+ </xsd:enumeration>
530
+ <xsd:enumeration value="name">
531
+ <xsd:annotation>
532
+ <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
533
+ </xsd:annotation>
534
+ </xsd:enumeration>
535
+ <xsd:enumeration value="near-synonym">
536
+ <xsd:annotation>
537
+ <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
538
+ </xsd:annotation>
539
+ </xsd:enumeration>
540
+ <xsd:enumeration value="part-number">
541
+ <xsd:annotation>
542
+ <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
543
+ </xsd:annotation>
544
+ </xsd:enumeration>
545
+ <xsd:enumeration value="phrase">
546
+ <xsd:annotation>
547
+ <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
548
+ </xsd:annotation>
549
+ </xsd:enumeration>
550
+ <xsd:enumeration value="phraseological-unit">
551
+ <xsd:annotation>
552
+ <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
553
+ </xsd:annotation>
554
+ </xsd:enumeration>
555
+ <xsd:enumeration value="protected">
556
+ <xsd:annotation>
557
+ <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
558
+ </xsd:annotation>
559
+ </xsd:enumeration>
560
+ <xsd:enumeration value="romanized-form">
561
+ <xsd:annotation>
562
+ <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
563
+ </xsd:annotation>
564
+ </xsd:enumeration>
565
+ <xsd:enumeration value="seg">
566
+ <xsd:annotation>
567
+ <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
568
+ </xsd:annotation>
569
+ </xsd:enumeration>
570
+ <xsd:enumeration value="set-phrase">
571
+ <xsd:annotation>
572
+ <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
573
+ </xsd:annotation>
574
+ </xsd:enumeration>
575
+ <xsd:enumeration value="short-form">
576
+ <xsd:annotation>
577
+ <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
578
+ </xsd:annotation>
579
+ </xsd:enumeration>
580
+ <xsd:enumeration value="sku">
581
+ <xsd:annotation>
582
+ <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
583
+ </xsd:annotation>
584
+ </xsd:enumeration>
585
+ <xsd:enumeration value="standard-text">
586
+ <xsd:annotation>
587
+ <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
588
+ </xsd:annotation>
589
+ </xsd:enumeration>
590
+ <xsd:enumeration value="symbol">
591
+ <xsd:annotation>
592
+ <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
593
+ </xsd:annotation>
594
+ </xsd:enumeration>
595
+ <xsd:enumeration value="synonym">
596
+ <xsd:annotation>
597
+ <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
598
+ </xsd:annotation>
599
+ </xsd:enumeration>
600
+ <xsd:enumeration value="synonymous-phrase">
601
+ <xsd:annotation>
602
+ <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
603
+ </xsd:annotation>
604
+ </xsd:enumeration>
605
+ <xsd:enumeration value="term">
606
+ <xsd:annotation>
607
+ <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
608
+ </xsd:annotation>
609
+ </xsd:enumeration>
610
+ <xsd:enumeration value="transcribed-form">
611
+ <xsd:annotation>
612
+ <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
613
+ </xsd:annotation>
614
+ </xsd:enumeration>
615
+ <xsd:enumeration value="transliterated-form">
616
+ <xsd:annotation>
617
+ <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
618
+ </xsd:annotation>
619
+ </xsd:enumeration>
620
+ <xsd:enumeration value="truncated-term">
621
+ <xsd:annotation>
622
+ <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
623
+ </xsd:annotation>
624
+ </xsd:enumeration>
625
+ <xsd:enumeration value="variant">
626
+ <xsd:annotation>
627
+ <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
628
+ </xsd:annotation>
629
+ </xsd:enumeration>
630
+ </xsd:restriction>
631
+ </xsd:simpleType>
632
+ <xsd:simpleType name="restypeValueList">
633
+ <xsd:annotation>
634
+ <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
635
+ </xsd:annotation>
636
+ <xsd:restriction base="xsd:NMTOKEN">
637
+ <xsd:enumeration value="auto3state">
638
+ <xsd:annotation>
639
+ <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
640
+ </xsd:annotation>
641
+ </xsd:enumeration>
642
+ <xsd:enumeration value="autocheckbox">
643
+ <xsd:annotation>
644
+ <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
645
+ </xsd:annotation>
646
+ </xsd:enumeration>
647
+ <xsd:enumeration value="autoradiobutton">
648
+ <xsd:annotation>
649
+ <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
650
+ </xsd:annotation>
651
+ </xsd:enumeration>
652
+ <xsd:enumeration value="bedit">
653
+ <xsd:annotation>
654
+ <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
655
+ </xsd:annotation>
656
+ </xsd:enumeration>
657
+ <xsd:enumeration value="bitmap">
658
+ <xsd:annotation>
659
+ <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
660
+ </xsd:annotation>
661
+ </xsd:enumeration>
662
+ <xsd:enumeration value="button">
663
+ <xsd:annotation>
664
+ <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
665
+ </xsd:annotation>
666
+ </xsd:enumeration>
667
+ <xsd:enumeration value="caption">
668
+ <xsd:annotation>
669
+ <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
670
+ </xsd:annotation>
671
+ </xsd:enumeration>
672
+ <xsd:enumeration value="cell">
673
+ <xsd:annotation>
674
+ <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
675
+ </xsd:annotation>
676
+ </xsd:enumeration>
677
+ <xsd:enumeration value="checkbox">
678
+ <xsd:annotation>
679
+ <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
680
+ </xsd:annotation>
681
+ </xsd:enumeration>
682
+ <xsd:enumeration value="checkboxmenuitem">
683
+ <xsd:annotation>
684
+ <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
685
+ </xsd:annotation>
686
+ </xsd:enumeration>
687
+ <xsd:enumeration value="checkedlistbox">
688
+ <xsd:annotation>
689
+ <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
690
+ </xsd:annotation>
691
+ </xsd:enumeration>
692
+ <xsd:enumeration value="colorchooser">
693
+ <xsd:annotation>
694
+ <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
695
+ </xsd:annotation>
696
+ </xsd:enumeration>
697
+ <xsd:enumeration value="combobox">
698
+ <xsd:annotation>
699
+ <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
700
+ </xsd:annotation>
701
+ </xsd:enumeration>
702
+ <xsd:enumeration value="comboboxexitem">
703
+ <xsd:annotation>
704
+ <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
705
+ </xsd:annotation>
706
+ </xsd:enumeration>
707
+ <xsd:enumeration value="comboboxitem">
708
+ <xsd:annotation>
709
+ <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
710
+ </xsd:annotation>
711
+ </xsd:enumeration>
712
+ <xsd:enumeration value="component">
713
+ <xsd:annotation>
714
+ <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
715
+ </xsd:annotation>
716
+ </xsd:enumeration>
717
+ <xsd:enumeration value="contextmenu">
718
+ <xsd:annotation>
719
+ <xsd:documentation>Indicates a context menu.</xsd:documentation>
720
+ </xsd:annotation>
721
+ </xsd:enumeration>
722
+ <xsd:enumeration value="ctext">
723
+ <xsd:annotation>
724
+ <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
725
+ </xsd:annotation>
726
+ </xsd:enumeration>
727
+ <xsd:enumeration value="cursor">
728
+ <xsd:annotation>
729
+ <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
730
+ </xsd:annotation>
731
+ </xsd:enumeration>
732
+ <xsd:enumeration value="datetimepicker">
733
+ <xsd:annotation>
734
+ <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
735
+ </xsd:annotation>
736
+ </xsd:enumeration>
737
+ <xsd:enumeration value="defpushbutton">
738
+ <xsd:annotation>
739
+ <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
740
+ </xsd:annotation>
741
+ </xsd:enumeration>
742
+ <xsd:enumeration value="dialog">
743
+ <xsd:annotation>
744
+ <xsd:documentation>Indicates a dialog box.</xsd:documentation>
745
+ </xsd:annotation>
746
+ </xsd:enumeration>
747
+ <xsd:enumeration value="dlginit">
748
+ <xsd:annotation>
749
+ <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
750
+ </xsd:annotation>
751
+ </xsd:enumeration>
752
+ <xsd:enumeration value="edit">
753
+ <xsd:annotation>
754
+ <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
755
+ </xsd:annotation>
756
+ </xsd:enumeration>
757
+ <xsd:enumeration value="file">
758
+ <xsd:annotation>
759
+ <xsd:documentation>Indicates a filename.</xsd:documentation>
760
+ </xsd:annotation>
761
+ </xsd:enumeration>
762
+ <xsd:enumeration value="filechooser">
763
+ <xsd:annotation>
764
+ <xsd:documentation>Indicates a file dialog.</xsd:documentation>
765
+ </xsd:annotation>
766
+ </xsd:enumeration>
767
+ <xsd:enumeration value="fn">
768
+ <xsd:annotation>
769
+ <xsd:documentation>Indicates a footnote.</xsd:documentation>
770
+ </xsd:annotation>
771
+ </xsd:enumeration>
772
+ <xsd:enumeration value="font">
773
+ <xsd:annotation>
774
+ <xsd:documentation>Indicates a font name.</xsd:documentation>
775
+ </xsd:annotation>
776
+ </xsd:enumeration>
777
+ <xsd:enumeration value="footer">
778
+ <xsd:annotation>
779
+ <xsd:documentation>Indicates a footer.</xsd:documentation>
780
+ </xsd:annotation>
781
+ </xsd:enumeration>
782
+ <xsd:enumeration value="frame">
783
+ <xsd:annotation>
784
+ <xsd:documentation>Indicates a frame object.</xsd:documentation>
785
+ </xsd:annotation>
786
+ </xsd:enumeration>
787
+ <xsd:enumeration value="grid">
788
+ <xsd:annotation>
789
+ <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
790
+ </xsd:annotation>
791
+ </xsd:enumeration>
792
+ <xsd:enumeration value="groupbox">
793
+ <xsd:annotation>
794
+ <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
795
+ </xsd:annotation>
796
+ </xsd:enumeration>
797
+ <xsd:enumeration value="header">
798
+ <xsd:annotation>
799
+ <xsd:documentation>Indicates a header item.</xsd:documentation>
800
+ </xsd:annotation>
801
+ </xsd:enumeration>
802
+ <xsd:enumeration value="heading">
803
+ <xsd:annotation>
804
+ <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
805
+ </xsd:annotation>
806
+ </xsd:enumeration>
807
+ <xsd:enumeration value="hedit">
808
+ <xsd:annotation>
809
+ <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
810
+ </xsd:annotation>
811
+ </xsd:enumeration>
812
+ <xsd:enumeration value="hscrollbar">
813
+ <xsd:annotation>
814
+ <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
815
+ </xsd:annotation>
816
+ </xsd:enumeration>
817
+ <xsd:enumeration value="icon">
818
+ <xsd:annotation>
819
+ <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
820
+ </xsd:annotation>
821
+ </xsd:enumeration>
822
+ <xsd:enumeration value="iedit">
823
+ <xsd:annotation>
824
+ <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
825
+ </xsd:annotation>
826
+ </xsd:enumeration>
827
+ <xsd:enumeration value="keywords">
828
+ <xsd:annotation>
829
+ <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
830
+ </xsd:annotation>
831
+ </xsd:enumeration>
832
+ <xsd:enumeration value="label">
833
+ <xsd:annotation>
834
+ <xsd:documentation>Indicates a label object.</xsd:documentation>
835
+ </xsd:annotation>
836
+ </xsd:enumeration>
837
+ <xsd:enumeration value="linklabel">
838
+ <xsd:annotation>
839
+ <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
840
+ </xsd:annotation>
841
+ </xsd:enumeration>
842
+ <xsd:enumeration value="list">
843
+ <xsd:annotation>
844
+ <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
845
+ </xsd:annotation>
846
+ </xsd:enumeration>
847
+ <xsd:enumeration value="listbox">
848
+ <xsd:annotation>
849
+ <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
850
+ </xsd:annotation>
851
+ </xsd:enumeration>
852
+ <xsd:enumeration value="listitem">
853
+ <xsd:annotation>
854
+ <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
855
+ </xsd:annotation>
856
+ </xsd:enumeration>
857
+ <xsd:enumeration value="ltext">
858
+ <xsd:annotation>
859
+ <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
860
+ </xsd:annotation>
861
+ </xsd:enumeration>
862
+ <xsd:enumeration value="menu">
863
+ <xsd:annotation>
864
+ <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
865
+ </xsd:annotation>
866
+ </xsd:enumeration>
867
+ <xsd:enumeration value="menubar">
868
+ <xsd:annotation>
869
+ <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
870
+ </xsd:annotation>
871
+ </xsd:enumeration>
872
+ <xsd:enumeration value="menuitem">
873
+ <xsd:annotation>
874
+ <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
875
+ </xsd:annotation>
876
+ </xsd:enumeration>
877
+ <xsd:enumeration value="menuseparator">
878
+ <xsd:annotation>
879
+ <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
880
+ </xsd:annotation>
881
+ </xsd:enumeration>
882
+ <xsd:enumeration value="message">
883
+ <xsd:annotation>
884
+ <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
885
+ </xsd:annotation>
886
+ </xsd:enumeration>
887
+ <xsd:enumeration value="monthcalendar">
888
+ <xsd:annotation>
889
+ <xsd:documentation>Indicates a calendar control.</xsd:documentation>
890
+ </xsd:annotation>
891
+ </xsd:enumeration>
892
+ <xsd:enumeration value="numericupdown">
893
+ <xsd:annotation>
894
+ <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
895
+ </xsd:annotation>
896
+ </xsd:enumeration>
897
+ <xsd:enumeration value="panel">
898
+ <xsd:annotation>
899
+ <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
900
+ </xsd:annotation>
901
+ </xsd:enumeration>
902
+ <xsd:enumeration value="popupmenu">
903
+ <xsd:annotation>
904
+ <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
905
+ </xsd:annotation>
906
+ </xsd:enumeration>
907
+ <xsd:enumeration value="pushbox">
908
+ <xsd:annotation>
909
+ <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
910
+ </xsd:annotation>
911
+ </xsd:enumeration>
912
+ <xsd:enumeration value="pushbutton">
913
+ <xsd:annotation>
914
+ <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
915
+ </xsd:annotation>
916
+ </xsd:enumeration>
917
+ <xsd:enumeration value="radio">
918
+ <xsd:annotation>
919
+ <xsd:documentation>Indicates a radio button object.</xsd:documentation>
920
+ </xsd:annotation>
921
+ </xsd:enumeration>
922
+ <xsd:enumeration value="radiobuttonmenuitem">
923
+ <xsd:annotation>
924
+ <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
925
+ </xsd:annotation>
926
+ </xsd:enumeration>
927
+ <xsd:enumeration value="rcdata">
928
+ <xsd:annotation>
929
+ <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
930
+ </xsd:annotation>
931
+ </xsd:enumeration>
932
+ <xsd:enumeration value="row">
933
+ <xsd:annotation>
934
+ <xsd:documentation>Indicates a row in a table.</xsd:documentation>
935
+ </xsd:annotation>
936
+ </xsd:enumeration>
937
+ <xsd:enumeration value="rtext">
938
+ <xsd:annotation>
939
+ <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
940
+ </xsd:annotation>
941
+ </xsd:enumeration>
942
+ <xsd:enumeration value="scrollpane">
943
+ <xsd:annotation>
944
+ <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
945
+ </xsd:annotation>
946
+ </xsd:enumeration>
947
+ <xsd:enumeration value="separator">
948
+ <xsd:annotation>
949
+ <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
950
+ </xsd:annotation>
951
+ </xsd:enumeration>
952
+ <xsd:enumeration value="shortcut">
953
+ <xsd:annotation>
954
+ <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
955
+ </xsd:annotation>
956
+ </xsd:enumeration>
957
+ <xsd:enumeration value="spinner">
958
+ <xsd:annotation>
959
+ <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
960
+ </xsd:annotation>
961
+ </xsd:enumeration>
962
+ <xsd:enumeration value="splitter">
963
+ <xsd:annotation>
964
+ <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
965
+ </xsd:annotation>
966
+ </xsd:enumeration>
967
+ <xsd:enumeration value="state3">
968
+ <xsd:annotation>
969
+ <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
970
+ </xsd:annotation>
971
+ </xsd:enumeration>
972
+ <xsd:enumeration value="statusbar">
973
+ <xsd:annotation>
974
+ <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
975
+ </xsd:annotation>
976
+ </xsd:enumeration>
977
+ <xsd:enumeration value="string">
978
+ <xsd:annotation>
979
+ <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
980
+ </xsd:annotation>
981
+ </xsd:enumeration>
982
+ <xsd:enumeration value="tabcontrol">
983
+ <xsd:annotation>
984
+ <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
985
+ </xsd:annotation>
986
+ </xsd:enumeration>
987
+ <xsd:enumeration value="table">
988
+ <xsd:annotation>
989
+ <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
990
+ </xsd:annotation>
991
+ </xsd:enumeration>
992
+ <xsd:enumeration value="textbox">
993
+ <xsd:annotation>
994
+ <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
995
+ </xsd:annotation>
996
+ </xsd:enumeration>
997
+ <xsd:enumeration value="togglebutton">
998
+ <xsd:annotation>
999
+ <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
1000
+ </xsd:annotation>
1001
+ </xsd:enumeration>
1002
+ <xsd:enumeration value="toolbar">
1003
+ <xsd:annotation>
1004
+ <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
1005
+ </xsd:annotation>
1006
+ </xsd:enumeration>
1007
+ <xsd:enumeration value="tooltip">
1008
+ <xsd:annotation>
1009
+ <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
1010
+ </xsd:annotation>
1011
+ </xsd:enumeration>
1012
+ <xsd:enumeration value="trackbar">
1013
+ <xsd:annotation>
1014
+ <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
1015
+ </xsd:annotation>
1016
+ </xsd:enumeration>
1017
+ <xsd:enumeration value="tree">
1018
+ <xsd:annotation>
1019
+ <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
1020
+ </xsd:annotation>
1021
+ </xsd:enumeration>
1022
+ <xsd:enumeration value="uri">
1023
+ <xsd:annotation>
1024
+ <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
1025
+ </xsd:annotation>
1026
+ </xsd:enumeration>
1027
+ <xsd:enumeration value="userbutton">
1028
+ <xsd:annotation>
1029
+ <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
1030
+ </xsd:annotation>
1031
+ </xsd:enumeration>
1032
+ <xsd:enumeration value="usercontrol">
1033
+ <xsd:annotation>
1034
+ <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
1035
+ </xsd:annotation>
1036
+ </xsd:enumeration>
1037
+ <xsd:enumeration value="var">
1038
+ <xsd:annotation>
1039
+ <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
1040
+ </xsd:annotation>
1041
+ </xsd:enumeration>
1042
+ <xsd:enumeration value="versioninfo">
1043
+ <xsd:annotation>
1044
+ <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
1045
+ </xsd:annotation>
1046
+ </xsd:enumeration>
1047
+ <xsd:enumeration value="vscrollbar">
1048
+ <xsd:annotation>
1049
+ <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
1050
+ </xsd:annotation>
1051
+ </xsd:enumeration>
1052
+ <xsd:enumeration value="window">
1053
+ <xsd:annotation>
1054
+ <xsd:documentation>Indicates a graphical window.</xsd:documentation>
1055
+ </xsd:annotation>
1056
+ </xsd:enumeration>
1057
+ </xsd:restriction>
1058
+ </xsd:simpleType>
1059
+ <xsd:simpleType name="size-unitValueList">
1060
+ <xsd:annotation>
1061
+ <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
1062
+ </xsd:annotation>
1063
+ <xsd:restriction base="xsd:NMTOKEN">
1064
+ <xsd:enumeration value="byte">
1065
+ <xsd:annotation>
1066
+ <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
1067
+ </xsd:annotation>
1068
+ </xsd:enumeration>
1069
+ <xsd:enumeration value="char">
1070
+ <xsd:annotation>
1071
+ <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
1072
+ </xsd:annotation>
1073
+ </xsd:enumeration>
1074
+ <xsd:enumeration value="col">
1075
+ <xsd:annotation>
1076
+ <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
1077
+ </xsd:annotation>
1078
+ </xsd:enumeration>
1079
+ <xsd:enumeration value="cm">
1080
+ <xsd:annotation>
1081
+ <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
1082
+ </xsd:annotation>
1083
+ </xsd:enumeration>
1084
+ <xsd:enumeration value="dlgunit">
1085
+ <xsd:annotation>
1086
+ <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
1087
+ </xsd:annotation>
1088
+ </xsd:enumeration>
1089
+ <xsd:enumeration value="em">
1090
+ <xsd:annotation>
1091
+ <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
1092
+ </xsd:annotation>
1093
+ </xsd:enumeration>
1094
+ <xsd:enumeration value="ex">
1095
+ <xsd:annotation>
1096
+ <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
1097
+ </xsd:annotation>
1098
+ </xsd:enumeration>
1099
+ <xsd:enumeration value="glyph">
1100
+ <xsd:annotation>
1101
+ <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
1102
+ </xsd:annotation>
1103
+ </xsd:enumeration>
1104
+ <xsd:enumeration value="in">
1105
+ <xsd:annotation>
1106
+ <xsd:documentation>Indicates a size in inches.</xsd:documentation>
1107
+ </xsd:annotation>
1108
+ </xsd:enumeration>
1109
+ <xsd:enumeration value="mm">
1110
+ <xsd:annotation>
1111
+ <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
1112
+ </xsd:annotation>
1113
+ </xsd:enumeration>
1114
+ <xsd:enumeration value="percent">
1115
+ <xsd:annotation>
1116
+ <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
1117
+ </xsd:annotation>
1118
+ </xsd:enumeration>
1119
+ <xsd:enumeration value="pixel">
1120
+ <xsd:annotation>
1121
+ <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
1122
+ </xsd:annotation>
1123
+ </xsd:enumeration>
1124
+ <xsd:enumeration value="point">
1125
+ <xsd:annotation>
1126
+ <xsd:documentation>Indicates a size in point.</xsd:documentation>
1127
+ </xsd:annotation>
1128
+ </xsd:enumeration>
1129
+ <xsd:enumeration value="row">
1130
+ <xsd:annotation>
1131
+ <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
1132
+ </xsd:annotation>
1133
+ </xsd:enumeration>
1134
+ </xsd:restriction>
1135
+ </xsd:simpleType>
1136
+ <xsd:simpleType name="stateValueList">
1137
+ <xsd:annotation>
1138
+ <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
1139
+ </xsd:annotation>
1140
+ <xsd:restriction base="xsd:NMTOKEN">
1141
+ <xsd:enumeration value="final">
1142
+ <xsd:annotation>
1143
+ <xsd:documentation>Indicates the terminating state.</xsd:documentation>
1144
+ </xsd:annotation>
1145
+ </xsd:enumeration>
1146
+ <xsd:enumeration value="needs-adaptation">
1147
+ <xsd:annotation>
1148
+ <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
1149
+ </xsd:annotation>
1150
+ </xsd:enumeration>
1151
+ <xsd:enumeration value="needs-l10n">
1152
+ <xsd:annotation>
1153
+ <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
1154
+ </xsd:annotation>
1155
+ </xsd:enumeration>
1156
+ <xsd:enumeration value="needs-review-adaptation">
1157
+ <xsd:annotation>
1158
+ <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
1159
+ </xsd:annotation>
1160
+ </xsd:enumeration>
1161
+ <xsd:enumeration value="needs-review-l10n">
1162
+ <xsd:annotation>
1163
+ <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
1164
+ </xsd:annotation>
1165
+ </xsd:enumeration>
1166
+ <xsd:enumeration value="needs-review-translation">
1167
+ <xsd:annotation>
1168
+ <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
1169
+ </xsd:annotation>
1170
+ </xsd:enumeration>
1171
+ <xsd:enumeration value="needs-translation">
1172
+ <xsd:annotation>
1173
+ <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
1174
+ </xsd:annotation>
1175
+ </xsd:enumeration>
1176
+ <xsd:enumeration value="new">
1177
+ <xsd:annotation>
1178
+ <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
1179
+ </xsd:annotation>
1180
+ </xsd:enumeration>
1181
+ <xsd:enumeration value="signed-off">
1182
+ <xsd:annotation>
1183
+ <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
1184
+ </xsd:annotation>
1185
+ </xsd:enumeration>
1186
+ <xsd:enumeration value="translated">
1187
+ <xsd:annotation>
1188
+ <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
1189
+ </xsd:annotation>
1190
+ </xsd:enumeration>
1191
+ </xsd:restriction>
1192
+ </xsd:simpleType>
1193
+ <xsd:simpleType name="state-qualifierValueList">
1194
+ <xsd:annotation>
1195
+ <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
1196
+ </xsd:annotation>
1197
+ <xsd:restriction base="xsd:NMTOKEN">
1198
+ <xsd:enumeration value="exact-match">
1199
+ <xsd:annotation>
1200
+ <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
1201
+ </xsd:annotation>
1202
+ </xsd:enumeration>
1203
+ <xsd:enumeration value="fuzzy-match">
1204
+ <xsd:annotation>
1205
+ <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
1206
+ </xsd:annotation>
1207
+ </xsd:enumeration>
1208
+ <xsd:enumeration value="id-match">
1209
+ <xsd:annotation>
1210
+ <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
1211
+ </xsd:annotation>
1212
+ </xsd:enumeration>
1213
+ <xsd:enumeration value="leveraged-glossary">
1214
+ <xsd:annotation>
1215
+ <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
1216
+ </xsd:annotation>
1217
+ </xsd:enumeration>
1218
+ <xsd:enumeration value="leveraged-inherited">
1219
+ <xsd:annotation>
1220
+ <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
1221
+ </xsd:annotation>
1222
+ </xsd:enumeration>
1223
+ <xsd:enumeration value="leveraged-mt">
1224
+ <xsd:annotation>
1225
+ <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
1226
+ </xsd:annotation>
1227
+ </xsd:enumeration>
1228
+ <xsd:enumeration value="leveraged-repository">
1229
+ <xsd:annotation>
1230
+ <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
1231
+ </xsd:annotation>
1232
+ </xsd:enumeration>
1233
+ <xsd:enumeration value="leveraged-tm">
1234
+ <xsd:annotation>
1235
+ <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
1236
+ </xsd:annotation>
1237
+ </xsd:enumeration>
1238
+ <xsd:enumeration value="mt-suggestion">
1239
+ <xsd:annotation>
1240
+ <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
1241
+ </xsd:annotation>
1242
+ </xsd:enumeration>
1243
+ <xsd:enumeration value="rejected-grammar">
1244
+ <xsd:annotation>
1245
+ <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
1246
+ </xsd:annotation>
1247
+ </xsd:enumeration>
1248
+ <xsd:enumeration value="rejected-inaccurate">
1249
+ <xsd:annotation>
1250
+ <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
1251
+ </xsd:annotation>
1252
+ </xsd:enumeration>
1253
+ <xsd:enumeration value="rejected-length">
1254
+ <xsd:annotation>
1255
+ <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
1256
+ </xsd:annotation>
1257
+ </xsd:enumeration>
1258
+ <xsd:enumeration value="rejected-spelling">
1259
+ <xsd:annotation>
1260
+ <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
1261
+ </xsd:annotation>
1262
+ </xsd:enumeration>
1263
+ <xsd:enumeration value="tm-suggestion">
1264
+ <xsd:annotation>
1265
+ <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
1266
+ </xsd:annotation>
1267
+ </xsd:enumeration>
1268
+ </xsd:restriction>
1269
+ </xsd:simpleType>
1270
+ <xsd:simpleType name="unitValueList">
1271
+ <xsd:annotation>
1272
+ <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
1273
+ </xsd:annotation>
1274
+ <xsd:restriction base="xsd:NMTOKEN">
1275
+ <xsd:enumeration value="word">
1276
+ <xsd:annotation>
1277
+ <xsd:documentation>Refers to words.</xsd:documentation>
1278
+ </xsd:annotation>
1279
+ </xsd:enumeration>
1280
+ <xsd:enumeration value="page">
1281
+ <xsd:annotation>
1282
+ <xsd:documentation>Refers to pages.</xsd:documentation>
1283
+ </xsd:annotation>
1284
+ </xsd:enumeration>
1285
+ <xsd:enumeration value="trans-unit">
1286
+ <xsd:annotation>
1287
+ <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
1288
+ </xsd:annotation>
1289
+ </xsd:enumeration>
1290
+ <xsd:enumeration value="bin-unit">
1291
+ <xsd:annotation>
1292
+ <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
1293
+ </xsd:annotation>
1294
+ </xsd:enumeration>
1295
+ <xsd:enumeration value="glyph">
1296
+ <xsd:annotation>
1297
+ <xsd:documentation>Refers to glyphs.</xsd:documentation>
1298
+ </xsd:annotation>
1299
+ </xsd:enumeration>
1300
+ <xsd:enumeration value="item">
1301
+ <xsd:annotation>
1302
+ <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
1303
+ </xsd:annotation>
1304
+ </xsd:enumeration>
1305
+ <xsd:enumeration value="instance">
1306
+ <xsd:annotation>
1307
+ <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
1308
+ </xsd:annotation>
1309
+ </xsd:enumeration>
1310
+ <xsd:enumeration value="character">
1311
+ <xsd:annotation>
1312
+ <xsd:documentation>Refers to characters.</xsd:documentation>
1313
+ </xsd:annotation>
1314
+ </xsd:enumeration>
1315
+ <xsd:enumeration value="line">
1316
+ <xsd:annotation>
1317
+ <xsd:documentation>Refers to lines.</xsd:documentation>
1318
+ </xsd:annotation>
1319
+ </xsd:enumeration>
1320
+ <xsd:enumeration value="sentence">
1321
+ <xsd:annotation>
1322
+ <xsd:documentation>Refers to sentences.</xsd:documentation>
1323
+ </xsd:annotation>
1324
+ </xsd:enumeration>
1325
+ <xsd:enumeration value="paragraph">
1326
+ <xsd:annotation>
1327
+ <xsd:documentation>Refers to paragraphs.</xsd:documentation>
1328
+ </xsd:annotation>
1329
+ </xsd:enumeration>
1330
+ <xsd:enumeration value="segment">
1331
+ <xsd:annotation>
1332
+ <xsd:documentation>Refers to segments.</xsd:documentation>
1333
+ </xsd:annotation>
1334
+ </xsd:enumeration>
1335
+ <xsd:enumeration value="placeable">
1336
+ <xsd:annotation>
1337
+ <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
1338
+ </xsd:annotation>
1339
+ </xsd:enumeration>
1340
+ </xsd:restriction>
1341
+ </xsd:simpleType>
1342
+ <xsd:simpleType name="priorityValueList">
1343
+ <xsd:annotation>
1344
+ <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
1345
+ </xsd:annotation>
1346
+ <xsd:restriction base="xsd:positiveInteger">
1347
+ <xsd:enumeration value="1">
1348
+ <xsd:annotation>
1349
+ <xsd:documentation>Highest priority.</xsd:documentation>
1350
+ </xsd:annotation>
1351
+ </xsd:enumeration>
1352
+ <xsd:enumeration value="2">
1353
+ <xsd:annotation>
1354
+ <xsd:documentation>High priority.</xsd:documentation>
1355
+ </xsd:annotation>
1356
+ </xsd:enumeration>
1357
+ <xsd:enumeration value="3">
1358
+ <xsd:annotation>
1359
+ <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
1360
+ </xsd:annotation>
1361
+ </xsd:enumeration>
1362
+ <xsd:enumeration value="4">
1363
+ <xsd:annotation>
1364
+ <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
1365
+ </xsd:annotation>
1366
+ </xsd:enumeration>
1367
+ <xsd:enumeration value="5">
1368
+ <xsd:annotation>
1369
+ <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
1370
+ </xsd:annotation>
1371
+ </xsd:enumeration>
1372
+ <xsd:enumeration value="6">
1373
+ <xsd:annotation>
1374
+ <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
1375
+ </xsd:annotation>
1376
+ </xsd:enumeration>
1377
+ <xsd:enumeration value="7">
1378
+ <xsd:annotation>
1379
+ <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
1380
+ </xsd:annotation>
1381
+ </xsd:enumeration>
1382
+ <xsd:enumeration value="8">
1383
+ <xsd:annotation>
1384
+ <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
1385
+ </xsd:annotation>
1386
+ </xsd:enumeration>
1387
+ <xsd:enumeration value="9">
1388
+ <xsd:annotation>
1389
+ <xsd:documentation>Low priority.</xsd:documentation>
1390
+ </xsd:annotation>
1391
+ </xsd:enumeration>
1392
+ <xsd:enumeration value="10">
1393
+ <xsd:annotation>
1394
+ <xsd:documentation>Lowest priority.</xsd:documentation>
1395
+ </xsd:annotation>
1396
+ </xsd:enumeration>
1397
+ </xsd:restriction>
1398
+ </xsd:simpleType>
1399
+ <xsd:simpleType name="reformatValueYesNo">
1400
+ <xsd:restriction base="xsd:string">
1401
+ <xsd:enumeration value="yes">
1402
+ <xsd:annotation>
1403
+ <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
1404
+ </xsd:annotation>
1405
+ </xsd:enumeration>
1406
+ <xsd:enumeration value="no">
1407
+ <xsd:annotation>
1408
+ <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
1409
+ </xsd:annotation>
1410
+ </xsd:enumeration>
1411
+ </xsd:restriction>
1412
+ </xsd:simpleType>
1413
+ <xsd:simpleType name="reformatValueList">
1414
+ <xsd:list>
1415
+ <xsd:simpleType>
1416
+ <xsd:union memberTypes="xlf:XTend">
1417
+ <xsd:simpleType>
1418
+ <xsd:restriction base="xsd:string">
1419
+ <xsd:enumeration value="coord">
1420
+ <xsd:annotation>
1421
+ <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
1422
+ </xsd:annotation>
1423
+ </xsd:enumeration>
1424
+ <xsd:enumeration value="coord-x">
1425
+ <xsd:annotation>
1426
+ <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
1427
+ </xsd:annotation>
1428
+ </xsd:enumeration>
1429
+ <xsd:enumeration value="coord-y">
1430
+ <xsd:annotation>
1431
+ <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
1432
+ </xsd:annotation>
1433
+ </xsd:enumeration>
1434
+ <xsd:enumeration value="coord-cx">
1435
+ <xsd:annotation>
1436
+ <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
1437
+ </xsd:annotation>
1438
+ </xsd:enumeration>
1439
+ <xsd:enumeration value="coord-cy">
1440
+ <xsd:annotation>
1441
+ <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
1442
+ </xsd:annotation>
1443
+ </xsd:enumeration>
1444
+ <xsd:enumeration value="font">
1445
+ <xsd:annotation>
1446
+ <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
1447
+ </xsd:annotation>
1448
+ </xsd:enumeration>
1449
+ <xsd:enumeration value="font-name">
1450
+ <xsd:annotation>
1451
+ <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
1452
+ </xsd:annotation>
1453
+ </xsd:enumeration>
1454
+ <xsd:enumeration value="font-size">
1455
+ <xsd:annotation>
1456
+ <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
1457
+ </xsd:annotation>
1458
+ </xsd:enumeration>
1459
+ <xsd:enumeration value="font-weight">
1460
+ <xsd:annotation>
1461
+ <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
1462
+ </xsd:annotation>
1463
+ </xsd:enumeration>
1464
+ <xsd:enumeration value="css-style">
1465
+ <xsd:annotation>
1466
+ <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
1467
+ </xsd:annotation>
1468
+ </xsd:enumeration>
1469
+ <xsd:enumeration value="style">
1470
+ <xsd:annotation>
1471
+ <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
1472
+ </xsd:annotation>
1473
+ </xsd:enumeration>
1474
+ <xsd:enumeration value="ex-style">
1475
+ <xsd:annotation>
1476
+ <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
1477
+ </xsd:annotation>
1478
+ </xsd:enumeration>
1479
+ </xsd:restriction>
1480
+ </xsd:simpleType>
1481
+ </xsd:union>
1482
+ </xsd:simpleType>
1483
+ </xsd:list>
1484
+ </xsd:simpleType>
1485
+ <xsd:simpleType name="purposeValueList">
1486
+ <xsd:restriction base="xsd:string">
1487
+ <xsd:enumeration value="information">
1488
+ <xsd:annotation>
1489
+ <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
1490
+ </xsd:annotation>
1491
+ </xsd:enumeration>
1492
+ <xsd:enumeration value="location">
1493
+ <xsd:annotation>
1494
+ <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
1495
+ </xsd:annotation>
1496
+ </xsd:enumeration>
1497
+ <xsd:enumeration value="match">
1498
+ <xsd:annotation>
1499
+ <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
1500
+ </xsd:annotation>
1501
+ </xsd:enumeration>
1502
+ </xsd:restriction>
1503
+ </xsd:simpleType>
1504
+ <xsd:simpleType name="alttranstypeValueList">
1505
+ <xsd:restriction base="xsd:string">
1506
+ <xsd:enumeration value="proposal">
1507
+ <xsd:annotation>
1508
+ <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
1509
+ </xsd:annotation>
1510
+ </xsd:enumeration>
1511
+ <xsd:enumeration value="previous-version">
1512
+ <xsd:annotation>
1513
+ <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
1514
+ </xsd:annotation>
1515
+ </xsd:enumeration>
1516
+ <xsd:enumeration value="rejected">
1517
+ <xsd:annotation>
1518
+ <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
1519
+ </xsd:annotation>
1520
+ </xsd:enumeration>
1521
+ <xsd:enumeration value="reference">
1522
+ <xsd:annotation>
1523
+ <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
1524
+ </xsd:annotation>
1525
+ </xsd:enumeration>
1526
+ <xsd:enumeration value="accepted">
1527
+ <xsd:annotation>
1528
+ <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
1529
+ </xsd:annotation>
1530
+ </xsd:enumeration>
1531
+ </xsd:restriction>
1532
+ </xsd:simpleType>
1533
+ <!-- Other Types -->
1534
+ <xsd:complexType name="ElemType_ExternalReference">
1535
+ <xsd:choice>
1536
+ <xsd:element ref="xlf:internal-file"/>
1537
+ <xsd:element ref="xlf:external-file"/>
1538
+ </xsd:choice>
1539
+ </xsd:complexType>
1540
+ <xsd:simpleType name="AttrType_purpose">
1541
+ <xsd:list>
1542
+ <xsd:simpleType>
1543
+ <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
1544
+ </xsd:simpleType>
1545
+ </xsd:list>
1546
+ </xsd:simpleType>
1547
+ <xsd:simpleType name="AttrType_datatype">
1548
+ <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
1549
+ </xsd:simpleType>
1550
+ <xsd:simpleType name="AttrType_restype">
1551
+ <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
1552
+ </xsd:simpleType>
1553
+ <xsd:simpleType name="AttrType_alttranstype">
1554
+ <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
1555
+ </xsd:simpleType>
1556
+ <xsd:simpleType name="AttrType_context-type">
1557
+ <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
1558
+ </xsd:simpleType>
1559
+ <xsd:simpleType name="AttrType_state">
1560
+ <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
1561
+ </xsd:simpleType>
1562
+ <xsd:simpleType name="AttrType_state-qualifier">
1563
+ <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
1564
+ </xsd:simpleType>
1565
+ <xsd:simpleType name="AttrType_count-type">
1566
+ <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
1567
+ </xsd:simpleType>
1568
+ <xsd:simpleType name="AttrType_InlineDelimiters">
1569
+ <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
1570
+ </xsd:simpleType>
1571
+ <xsd:simpleType name="AttrType_InlinePlaceholders">
1572
+ <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
1573
+ </xsd:simpleType>
1574
+ <xsd:simpleType name="AttrType_size-unit">
1575
+ <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
1576
+ </xsd:simpleType>
1577
+ <xsd:simpleType name="AttrType_mtype">
1578
+ <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
1579
+ </xsd:simpleType>
1580
+ <xsd:simpleType name="AttrType_unit">
1581
+ <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
1582
+ </xsd:simpleType>
1583
+ <xsd:simpleType name="AttrType_priority">
1584
+ <xsd:union memberTypes="xlf:priorityValueList"/>
1585
+ </xsd:simpleType>
1586
+ <xsd:simpleType name="AttrType_reformat">
1587
+ <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
1588
+ </xsd:simpleType>
1589
+ <xsd:simpleType name="AttrType_YesNo">
1590
+ <xsd:restriction base="xsd:NMTOKEN">
1591
+ <xsd:enumeration value="yes"/>
1592
+ <xsd:enumeration value="no"/>
1593
+ </xsd:restriction>
1594
+ </xsd:simpleType>
1595
+ <xsd:simpleType name="AttrType_Position">
1596
+ <xsd:restriction base="xsd:NMTOKEN">
1597
+ <xsd:enumeration value="open"/>
1598
+ <xsd:enumeration value="close"/>
1599
+ </xsd:restriction>
1600
+ </xsd:simpleType>
1601
+ <xsd:simpleType name="AttrType_assoc">
1602
+ <xsd:restriction base="xsd:NMTOKEN">
1603
+ <xsd:enumeration value="preceding"/>
1604
+ <xsd:enumeration value="following"/>
1605
+ <xsd:enumeration value="both"/>
1606
+ </xsd:restriction>
1607
+ </xsd:simpleType>
1608
+ <xsd:simpleType name="AttrType_annotates">
1609
+ <xsd:restriction base="xsd:NMTOKEN">
1610
+ <xsd:enumeration value="source"/>
1611
+ <xsd:enumeration value="target"/>
1612
+ <xsd:enumeration value="general"/>
1613
+ </xsd:restriction>
1614
+ </xsd:simpleType>
1615
+ <xsd:simpleType name="AttrType_Coordinates">
1616
+ <xsd:annotation>
1617
+ <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
1618
+ </xsd:annotation>
1619
+ <xsd:restriction base="xsd:string">
1620
+ <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
1621
+ </xsd:restriction>
1622
+ </xsd:simpleType>
1623
+ <xsd:simpleType name="AttrType_Version">
1624
+ <xsd:annotation>
1625
+ <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
1626
+ </xsd:annotation>
1627
+ <xsd:restriction base="xsd:string">
1628
+ <xsd:enumeration value="1.2"/>
1629
+ <xsd:enumeration value="1.1"/>
1630
+ <xsd:enumeration value="1.0"/>
1631
+ </xsd:restriction>
1632
+ </xsd:simpleType>
1633
+ <!-- Groups -->
1634
+ <xsd:group name="ElemGroup_TextContent">
1635
+ <xsd:choice>
1636
+ <xsd:element ref="xlf:g"/>
1637
+ <xsd:element ref="xlf:bpt"/>
1638
+ <xsd:element ref="xlf:ept"/>
1639
+ <xsd:element ref="xlf:ph"/>
1640
+ <xsd:element ref="xlf:it"/>
1641
+ <xsd:element ref="xlf:mrk"/>
1642
+ <xsd:element ref="xlf:x"/>
1643
+ <xsd:element ref="xlf:bx"/>
1644
+ <xsd:element ref="xlf:ex"/>
1645
+ </xsd:choice>
1646
+ </xsd:group>
1647
+ <xsd:attributeGroup name="AttrGroup_TextContent">
1648
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
1649
+ <xsd:attribute name="xid" type="xsd:string" use="optional"/>
1650
+ <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
1651
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1652
+ </xsd:attributeGroup>
1653
+ <!-- XLIFF Structure -->
1654
+ <xsd:element name="xliff">
1655
+ <xsd:complexType>
1656
+ <xsd:sequence maxOccurs="unbounded">
1657
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1658
+ <xsd:element ref="xlf:file"/>
1659
+ </xsd:sequence>
1660
+ <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
1661
+ <xsd:attribute ref="xml:lang" use="optional"/>
1662
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1663
+ </xsd:complexType>
1664
+ </xsd:element>
1665
+ <xsd:element name="file">
1666
+ <xsd:complexType>
1667
+ <xsd:sequence>
1668
+ <xsd:element minOccurs="0" ref="xlf:header"/>
1669
+ <xsd:element ref="xlf:body"/>
1670
+ </xsd:sequence>
1671
+ <xsd:attribute name="original" type="xsd:string" use="required"/>
1672
+ <xsd:attribute name="source-language" type="xsd:language" use="required"/>
1673
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
1674
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
1675
+ <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
1676
+ <xsd:attribute ref="xml:space" use="optional"/>
1677
+ <xsd:attribute name="category" type="xsd:string" use="optional"/>
1678
+ <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
1679
+ <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
1680
+ <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
1681
+ <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
1682
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1683
+ </xsd:complexType>
1684
+ <xsd:unique name="U_group_id">
1685
+ <xsd:selector xpath=".//xlf:group"/>
1686
+ <xsd:field xpath="@id"/>
1687
+ </xsd:unique>
1688
+ <xsd:key name="K_unit_id">
1689
+ <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
1690
+ <xsd:field xpath="@id"/>
1691
+ </xsd:key>
1692
+ <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
1693
+ <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
1694
+ <xsd:field xpath="@xid"/>
1695
+ </xsd:keyref>
1696
+ <xsd:key name="K_tool-id">
1697
+ <xsd:selector xpath="xlf:header/xlf:tool"/>
1698
+ <xsd:field xpath="@tool-id"/>
1699
+ </xsd:key>
1700
+ <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
1701
+ <xsd:selector xpath="."/>
1702
+ <xsd:field xpath="@tool-id"/>
1703
+ </xsd:keyref>
1704
+ <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
1705
+ <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
1706
+ <xsd:field xpath="@tool-id"/>
1707
+ </xsd:keyref>
1708
+ <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
1709
+ <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
1710
+ <xsd:field xpath="@tool-id"/>
1711
+ </xsd:keyref>
1712
+ <xsd:key name="K_count-group_name">
1713
+ <xsd:selector xpath=".//xlf:count-group"/>
1714
+ <xsd:field xpath="@name"/>
1715
+ </xsd:key>
1716
+ <xsd:unique name="U_context-group_name">
1717
+ <xsd:selector xpath=".//xlf:context-group"/>
1718
+ <xsd:field xpath="@name"/>
1719
+ </xsd:unique>
1720
+ <xsd:key name="K_phase-name">
1721
+ <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
1722
+ <xsd:field xpath="@phase-name"/>
1723
+ </xsd:key>
1724
+ <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
1725
+ <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
1726
+ <xsd:field xpath="@phase-name"/>
1727
+ </xsd:keyref>
1728
+ <xsd:unique name="U_uid">
1729
+ <xsd:selector xpath=".//xlf:external-file"/>
1730
+ <xsd:field xpath="@uid"/>
1731
+ </xsd:unique>
1732
+ </xsd:element>
1733
+ <xsd:element name="header">
1734
+ <xsd:complexType>
1735
+ <xsd:sequence>
1736
+ <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
1737
+ <xsd:element minOccurs="0" ref="xlf:phase-group"/>
1738
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
1739
+ <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
1740
+ <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
1741
+ <xsd:element ref="xlf:count-group"/>
1742
+ <xsd:element ref="xlf:note"/>
1743
+ <xsd:element ref="xlf:tool"/>
1744
+ </xsd:choice>
1745
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1746
+ </xsd:sequence>
1747
+ </xsd:complexType>
1748
+ </xsd:element>
1749
+ <xsd:element name="internal-file">
1750
+ <xsd:complexType>
1751
+ <xsd:simpleContent>
1752
+ <xsd:extension base="xsd:string">
1753
+ <xsd:attribute name="form" type="xsd:string"/>
1754
+ <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
1755
+ </xsd:extension>
1756
+ </xsd:simpleContent>
1757
+ </xsd:complexType>
1758
+ </xsd:element>
1759
+ <xsd:element name="external-file">
1760
+ <xsd:complexType>
1761
+ <xsd:attribute name="href" type="xsd:string" use="required"/>
1762
+ <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
1763
+ <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
1764
+ </xsd:complexType>
1765
+ </xsd:element>
1766
+ <xsd:element name="note">
1767
+ <xsd:complexType>
1768
+ <xsd:simpleContent>
1769
+ <xsd:extension base="xsd:string">
1770
+ <xsd:attribute ref="xml:lang" use="optional"/>
1771
+ <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
1772
+ <xsd:attribute name="from" type="xsd:string" use="optional"/>
1773
+ <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
1774
+ </xsd:extension>
1775
+ </xsd:simpleContent>
1776
+ </xsd:complexType>
1777
+ </xsd:element>
1778
+ <xsd:element name="phase-group">
1779
+ <xsd:complexType>
1780
+ <xsd:sequence maxOccurs="unbounded">
1781
+ <xsd:element ref="xlf:phase"/>
1782
+ </xsd:sequence>
1783
+ </xsd:complexType>
1784
+ </xsd:element>
1785
+ <xsd:element name="phase">
1786
+ <xsd:complexType>
1787
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
1788
+ <xsd:element ref="xlf:note"/>
1789
+ </xsd:sequence>
1790
+ <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
1791
+ <xsd:attribute name="process-name" type="xsd:string" use="required"/>
1792
+ <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
1793
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
1794
+ <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
1795
+ <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
1796
+ <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
1797
+ <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
1798
+ <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
1799
+ </xsd:complexType>
1800
+ </xsd:element>
1801
+ <xsd:element name="count-group">
1802
+ <xsd:complexType>
1803
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
1804
+ <xsd:element ref="xlf:count"/>
1805
+ </xsd:sequence>
1806
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
1807
+ </xsd:complexType>
1808
+ </xsd:element>
1809
+ <xsd:element name="count">
1810
+ <xsd:complexType>
1811
+ <xsd:simpleContent>
1812
+ <xsd:extension base="xsd:string">
1813
+ <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
1814
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
1815
+ <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
1816
+ </xsd:extension>
1817
+ </xsd:simpleContent>
1818
+ </xsd:complexType>
1819
+ </xsd:element>
1820
+ <xsd:element name="context-group">
1821
+ <xsd:complexType>
1822
+ <xsd:sequence maxOccurs="unbounded">
1823
+ <xsd:element ref="xlf:context"/>
1824
+ </xsd:sequence>
1825
+ <xsd:attribute name="name" type="xsd:string" use="optional"/>
1826
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
1827
+ <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
1828
+ </xsd:complexType>
1829
+ </xsd:element>
1830
+ <xsd:element name="context">
1831
+ <xsd:complexType>
1832
+ <xsd:simpleContent>
1833
+ <xsd:extension base="xsd:string">
1834
+ <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
1835
+ <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
1836
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
1837
+ </xsd:extension>
1838
+ </xsd:simpleContent>
1839
+ </xsd:complexType>
1840
+ </xsd:element>
1841
+ <xsd:element name="tool">
1842
+ <xsd:complexType mixed="true">
1843
+ <xsd:sequence>
1844
+ <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
1845
+ </xsd:sequence>
1846
+ <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
1847
+ <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
1848
+ <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
1849
+ <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
1850
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1851
+ </xsd:complexType>
1852
+ </xsd:element>
1853
+ <xsd:element name="body">
1854
+ <xsd:complexType>
1855
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
1856
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
1857
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
1858
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
1859
+ </xsd:choice>
1860
+ </xsd:complexType>
1861
+ </xsd:element>
1862
+ <xsd:element name="group">
1863
+ <xsd:complexType>
1864
+ <xsd:sequence>
1865
+ <xsd:sequence>
1866
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
1867
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
1868
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
1869
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1870
+ </xsd:sequence>
1871
+ <xsd:choice maxOccurs="unbounded">
1872
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
1873
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
1874
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
1875
+ </xsd:choice>
1876
+ </xsd:sequence>
1877
+ <xsd:attribute name="id" type="xsd:string" use="optional"/>
1878
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
1879
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
1880
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
1881
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
1882
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
1883
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
1884
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
1885
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
1886
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
1887
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
1888
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
1889
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
1890
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
1891
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
1892
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
1893
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
1894
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
1895
+ <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
1896
+ <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
1897
+ <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
1898
+ <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
1899
+ <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
1900
+ <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
1901
+ <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
1902
+ <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
1903
+ <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
1904
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1905
+ </xsd:complexType>
1906
+ </xsd:element>
1907
+ <xsd:element name="trans-unit">
1908
+ <xsd:complexType>
1909
+ <xsd:sequence>
1910
+ <xsd:element ref="xlf:source"/>
1911
+ <xsd:element minOccurs="0" ref="xlf:seg-source"/>
1912
+ <xsd:element minOccurs="0" ref="xlf:target"/>
1913
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
1914
+ <xsd:element ref="xlf:context-group"/>
1915
+ <xsd:element ref="xlf:count-group"/>
1916
+ <xsd:element ref="xlf:note"/>
1917
+ <xsd:element ref="xlf:alt-trans"/>
1918
+ </xsd:choice>
1919
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1920
+ </xsd:sequence>
1921
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
1922
+ <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
1923
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
1924
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
1925
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
1926
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
1927
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
1928
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
1929
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
1930
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
1931
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
1932
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
1933
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
1934
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
1935
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
1936
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
1937
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
1938
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
1939
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
1940
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
1941
+ <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
1942
+ <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
1943
+ <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
1944
+ <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
1945
+ <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
1946
+ <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
1947
+ <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
1948
+ <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
1949
+ <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
1950
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1951
+ </xsd:complexType>
1952
+ <xsd:unique name="U_tu_segsrc_mid">
1953
+ <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
1954
+ <xsd:field xpath="@mid"/>
1955
+ </xsd:unique>
1956
+ <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
1957
+ <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
1958
+ <xsd:field xpath="@mid"/>
1959
+ </xsd:keyref>
1960
+ </xsd:element>
1961
+ <xsd:element name="source">
1962
+ <xsd:complexType mixed="true">
1963
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
1964
+ <xsd:attribute ref="xml:lang" use="optional"/>
1965
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1966
+ </xsd:complexType>
1967
+ <xsd:unique name="U_source_bpt_rid">
1968
+ <xsd:selector xpath=".//xlf:bpt"/>
1969
+ <xsd:field xpath="@rid"/>
1970
+ </xsd:unique>
1971
+ <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
1972
+ <xsd:selector xpath=".//xlf:ept"/>
1973
+ <xsd:field xpath="@rid"/>
1974
+ </xsd:keyref>
1975
+ <xsd:unique name="U_source_bx_rid">
1976
+ <xsd:selector xpath=".//xlf:bx"/>
1977
+ <xsd:field xpath="@rid"/>
1978
+ </xsd:unique>
1979
+ <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
1980
+ <xsd:selector xpath=".//xlf:ex"/>
1981
+ <xsd:field xpath="@rid"/>
1982
+ </xsd:keyref>
1983
+ </xsd:element>
1984
+ <xsd:element name="seg-source">
1985
+ <xsd:complexType mixed="true">
1986
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
1987
+ <xsd:attribute ref="xml:lang" use="optional"/>
1988
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1989
+ </xsd:complexType>
1990
+ <xsd:unique name="U_segsrc_bpt_rid">
1991
+ <xsd:selector xpath=".//xlf:bpt"/>
1992
+ <xsd:field xpath="@rid"/>
1993
+ </xsd:unique>
1994
+ <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
1995
+ <xsd:selector xpath=".//xlf:ept"/>
1996
+ <xsd:field xpath="@rid"/>
1997
+ </xsd:keyref>
1998
+ <xsd:unique name="U_segsrc_bx_rid">
1999
+ <xsd:selector xpath=".//xlf:bx"/>
2000
+ <xsd:field xpath="@rid"/>
2001
+ </xsd:unique>
2002
+ <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
2003
+ <xsd:selector xpath=".//xlf:ex"/>
2004
+ <xsd:field xpath="@rid"/>
2005
+ </xsd:keyref>
2006
+ </xsd:element>
2007
+ <xsd:element name="target">
2008
+ <xsd:complexType mixed="true">
2009
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2010
+ <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
2011
+ <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
2012
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
2013
+ <xsd:attribute ref="xml:lang" use="optional"/>
2014
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2015
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
2016
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
2017
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
2018
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
2019
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
2020
+ <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
2021
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2022
+ </xsd:complexType>
2023
+ <xsd:unique name="U_target_bpt_rid">
2024
+ <xsd:selector xpath=".//xlf:bpt"/>
2025
+ <xsd:field xpath="@rid"/>
2026
+ </xsd:unique>
2027
+ <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
2028
+ <xsd:selector xpath=".//xlf:ept"/>
2029
+ <xsd:field xpath="@rid"/>
2030
+ </xsd:keyref>
2031
+ <xsd:unique name="U_target_bx_rid">
2032
+ <xsd:selector xpath=".//xlf:bx"/>
2033
+ <xsd:field xpath="@rid"/>
2034
+ </xsd:unique>
2035
+ <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
2036
+ <xsd:selector xpath=".//xlf:ex"/>
2037
+ <xsd:field xpath="@rid"/>
2038
+ </xsd:keyref>
2039
+ </xsd:element>
2040
+ <xsd:element name="alt-trans">
2041
+ <xsd:complexType>
2042
+ <xsd:sequence>
2043
+ <xsd:element minOccurs="0" ref="xlf:source"/>
2044
+ <xsd:element minOccurs="0" ref="xlf:seg-source"/>
2045
+ <xsd:element maxOccurs="1" ref="xlf:target"/>
2046
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
2047
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
2048
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
2049
+ </xsd:sequence>
2050
+ <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
2051
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
2052
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
2053
+ <xsd:attribute ref="xml:lang" use="optional"/>
2054
+ <xsd:attribute name="origin" type="xsd:string" use="optional"/>
2055
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
2056
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
2057
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
2058
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2059
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
2060
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
2061
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
2062
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
2063
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
2064
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
2065
+ <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
2066
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
2067
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
2068
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
2069
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
2070
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
2071
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
2072
+ <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
2073
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2074
+ </xsd:complexType>
2075
+ <xsd:unique name="U_at_segsrc_mid">
2076
+ <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
2077
+ <xsd:field xpath="@mid"/>
2078
+ </xsd:unique>
2079
+ <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
2080
+ <xsd:selector xpath="./xlf:target/xlf:mrk"/>
2081
+ <xsd:field xpath="@mid"/>
2082
+ </xsd:keyref>
2083
+ </xsd:element>
2084
+ <xsd:element name="bin-unit">
2085
+ <xsd:complexType>
2086
+ <xsd:sequence>
2087
+ <xsd:element ref="xlf:bin-source"/>
2088
+ <xsd:element minOccurs="0" ref="xlf:bin-target"/>
2089
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
2090
+ <xsd:element ref="xlf:context-group"/>
2091
+ <xsd:element ref="xlf:count-group"/>
2092
+ <xsd:element ref="xlf:note"/>
2093
+ <xsd:element ref="xlf:trans-unit"/>
2094
+ </xsd:choice>
2095
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
2096
+ </xsd:sequence>
2097
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
2098
+ <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
2099
+ <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
2100
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
2101
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
2102
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
2103
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2104
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
2105
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2106
+ </xsd:complexType>
2107
+ </xsd:element>
2108
+ <xsd:element name="bin-source">
2109
+ <xsd:complexType>
2110
+ <xsd:choice>
2111
+ <xsd:element ref="xlf:internal-file"/>
2112
+ <xsd:element ref="xlf:external-file"/>
2113
+ </xsd:choice>
2114
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2115
+ </xsd:complexType>
2116
+ </xsd:element>
2117
+ <xsd:element name="bin-target">
2118
+ <xsd:complexType>
2119
+ <xsd:choice>
2120
+ <xsd:element ref="xlf:internal-file"/>
2121
+ <xsd:element ref="xlf:external-file"/>
2122
+ </xsd:choice>
2123
+ <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
2124
+ <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
2125
+ <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
2126
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
2127
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
2128
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2129
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2130
+ </xsd:complexType>
2131
+ </xsd:element>
2132
+ <!-- Element for inline codes -->
2133
+ <xsd:element name="g">
2134
+ <xsd:complexType mixed="true">
2135
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2136
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2137
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
2138
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2139
+ </xsd:complexType>
2140
+ </xsd:element>
2141
+ <xsd:element name="x">
2142
+ <xsd:complexType>
2143
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
2144
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
2145
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2146
+ </xsd:complexType>
2147
+ </xsd:element>
2148
+ <xsd:element name="bx">
2149
+ <xsd:complexType>
2150
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2151
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2152
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
2153
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2154
+ </xsd:complexType>
2155
+ </xsd:element>
2156
+ <xsd:element name="ex">
2157
+ <xsd:complexType>
2158
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2159
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2160
+ </xsd:complexType>
2161
+ </xsd:element>
2162
+ <xsd:element name="ph">
2163
+ <xsd:complexType mixed="true">
2164
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2165
+ <xsd:element ref="xlf:sub"/>
2166
+ </xsd:sequence>
2167
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
2168
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2169
+ <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
2170
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2171
+ </xsd:complexType>
2172
+ </xsd:element>
2173
+ <xsd:element name="bpt">
2174
+ <xsd:complexType mixed="true">
2175
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2176
+ <xsd:element ref="xlf:sub"/>
2177
+ </xsd:sequence>
2178
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2179
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2180
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2181
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2182
+ </xsd:complexType>
2183
+ </xsd:element>
2184
+ <xsd:element name="ept">
2185
+ <xsd:complexType mixed="true">
2186
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2187
+ <xsd:element ref="xlf:sub"/>
2188
+ </xsd:sequence>
2189
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2190
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2191
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2192
+ </xsd:complexType>
2193
+ </xsd:element>
2194
+ <xsd:element name="it">
2195
+ <xsd:complexType mixed="true">
2196
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2197
+ <xsd:element ref="xlf:sub"/>
2198
+ </xsd:sequence>
2199
+ <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
2200
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2201
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2202
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2203
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2204
+ </xsd:complexType>
2205
+ </xsd:element>
2206
+ <xsd:element name="sub">
2207
+ <xsd:complexType mixed="true">
2208
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2209
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
2210
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2211
+ <xsd:attribute name="xid" type="xsd:string" use="optional"/>
2212
+ </xsd:complexType>
2213
+ </xsd:element>
2214
+ <xsd:element name="mrk">
2215
+ <xsd:complexType mixed="true">
2216
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2217
+ <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
2218
+ <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
2219
+ <xsd:attribute name="comment" type="xsd:string" use="optional"/>
2220
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2221
+ </xsd:complexType>
2222
+ </xsd:element>
2223
+ </xsd:schema>
app/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-2.0.xsd ADDED
@@ -0,0 +1,411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+
4
+ XLIFF Version 2.0
5
+ OASIS Standard
6
+ 05 August 2014
7
+ Copyright (c) OASIS Open 2014. All rights reserved.
8
+ Source: http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/
9
+ -->
10
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
11
+ elementFormDefault="qualified"
12
+ xmlns:xlf="urn:oasis:names:tc:xliff:document:2.0"
13
+ targetNamespace="urn:oasis:names:tc:xliff:document:2.0">
14
+
15
+ <!-- Import -->
16
+
17
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"
18
+ schemaLocation="informativeCopiesOf3rdPartySchemas/w3c/xml.xsd"/>
19
+
20
+ <!-- Element Group -->
21
+
22
+ <xs:group name="inline">
23
+ <xs:choice>
24
+ <xs:element ref="xlf:cp"/>
25
+ <xs:element ref="xlf:ph"/>
26
+ <xs:element ref="xlf:pc"/>
27
+ <xs:element ref="xlf:sc"/>
28
+ <xs:element ref="xlf:ec"/>
29
+ <xs:element ref="xlf:mrk"/>
30
+ <xs:element ref="xlf:sm"/>
31
+ <xs:element ref="xlf:em"/>
32
+ </xs:choice>
33
+ </xs:group>
34
+
35
+ <!-- Attribute Types -->
36
+
37
+ <xs:simpleType name="yesNo">
38
+ <xs:restriction base="xs:string">
39
+ <xs:enumeration value="yes"/>
40
+ <xs:enumeration value="no"/>
41
+ </xs:restriction>
42
+ </xs:simpleType>
43
+
44
+ <xs:simpleType name="yesNoFirstNo">
45
+ <xs:restriction base="xs:string">
46
+ <xs:enumeration value="yes"/>
47
+ <xs:enumeration value="firstNo"/>
48
+ <xs:enumeration value="no"/>
49
+ </xs:restriction>
50
+ </xs:simpleType>
51
+
52
+ <xs:simpleType name="dirValue">
53
+ <xs:restriction base="xs:string">
54
+ <xs:enumeration value="ltr"/>
55
+ <xs:enumeration value="rtl"/>
56
+ <xs:enumeration value="auto"/>
57
+ </xs:restriction>
58
+ </xs:simpleType>
59
+
60
+ <xs:simpleType name="appliesTo">
61
+ <xs:restriction base="xs:string">
62
+ <xs:enumeration value="source"/>
63
+ <xs:enumeration value="target"/>
64
+ </xs:restriction>
65
+ </xs:simpleType>
66
+
67
+ <xs:simpleType name="userDefinedValue">
68
+ <xs:restriction base="xs:string">
69
+ <xs:pattern value="[^\s:]+:[^\s:]+"/>
70
+ </xs:restriction>
71
+ </xs:simpleType>
72
+
73
+ <xs:simpleType name="attrType_type">
74
+ <xs:restriction base="xs:string">
75
+ <xs:enumeration value="fmt"/>
76
+ <xs:enumeration value="ui"/>
77
+ <xs:enumeration value="quote"/>
78
+ <xs:enumeration value="link"/>
79
+ <xs:enumeration value="image"/>
80
+ <xs:enumeration value="other"/>
81
+ </xs:restriction>
82
+ </xs:simpleType>
83
+
84
+ <xs:simpleType name="typeForMrkValues">
85
+ <xs:restriction base="xs:NMTOKEN">
86
+ <xs:enumeration value="generic"/>
87
+ <xs:enumeration value="comment"/>
88
+ <xs:enumeration value="term"/>
89
+ </xs:restriction>
90
+ </xs:simpleType>
91
+
92
+ <xs:simpleType name="attrType_typeForMrk">
93
+ <xs:union memberTypes="xlf:typeForMrkValues xlf:userDefinedValue"/>
94
+ </xs:simpleType>
95
+
96
+ <xs:simpleType name="priorityValue">
97
+ <xs:restriction base="xs:positiveInteger">
98
+ <xs:minInclusive value="1"/>
99
+ <xs:maxInclusive value="10"/>
100
+ </xs:restriction>
101
+ </xs:simpleType>
102
+
103
+ <xs:simpleType name="stateType">
104
+ <xs:restriction base="xs:string">
105
+ <xs:enumeration value="initial"/>
106
+ <xs:enumeration value="translated"/>
107
+ <xs:enumeration value="reviewed"/>
108
+ <xs:enumeration value="final"/>
109
+ </xs:restriction>
110
+ </xs:simpleType>
111
+
112
+ <!-- Structural Elements -->
113
+
114
+ <xs:element name="xliff">
115
+ <xs:complexType mixed="false">
116
+ <xs:sequence>
117
+ <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:file"/>
118
+ </xs:sequence>
119
+ <xs:attribute name="version" use="required"/>
120
+ <xs:attribute name="srcLang" use="required"/>
121
+ <xs:attribute name="trgLang" use="optional"/>
122
+ <xs:attribute ref="xml:space" use="optional" default="default"/>
123
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
124
+ </xs:complexType>
125
+ </xs:element>
126
+
127
+ <xs:element name="file">
128
+ <xs:complexType mixed="false">
129
+ <xs:sequence>
130
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:skeleton"/>
131
+ <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
132
+ processContents="lax"/>
133
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
134
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
135
+ <xs:element ref="xlf:unit"/>
136
+ <xs:element ref="xlf:group"/>
137
+ </xs:choice>
138
+ </xs:sequence>
139
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
140
+ <xs:attribute name="canResegment" use="optional" type="xlf:yesNo" default="yes"/>
141
+ <xs:attribute name="original" use="optional"/>
142
+ <xs:attribute name="translate" use="optional" type="xlf:yesNo" default="yes"/>
143
+ <xs:attribute name="srcDir" use="optional" type="xlf:dirValue" default="auto"/>
144
+ <xs:attribute name="trgDir" use="optional" type="xlf:dirValue" default="auto"/>
145
+ <xs:attribute ref="xml:space" use="optional"/>
146
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
147
+ </xs:complexType>
148
+ </xs:element>
149
+
150
+ <xs:element name="skeleton">
151
+ <xs:complexType mixed="true">
152
+ <xs:sequence>
153
+ <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
154
+ processContents="lax"/>
155
+ </xs:sequence>
156
+ <xs:attribute name="href" use="optional"/>
157
+ </xs:complexType>
158
+ </xs:element>
159
+
160
+ <xs:element name="group">
161
+ <xs:complexType mixed="false">
162
+ <xs:sequence>
163
+ <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
164
+ processContents="lax"/>
165
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
166
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
167
+ <xs:element ref="xlf:unit"/>
168
+ <xs:element ref="xlf:group"/>
169
+ </xs:choice>
170
+ </xs:sequence>
171
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
172
+ <xs:attribute name="name" use="optional"/>
173
+ <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
174
+ <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
175
+ <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
176
+ <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
177
+ <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
178
+ <xs:attribute ref="xml:space" use="optional"/>
179
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
180
+ </xs:complexType>
181
+ </xs:element>
182
+
183
+ <xs:element name="unit">
184
+ <xs:complexType mixed="false">
185
+ <xs:sequence>
186
+ <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
187
+ processContents="lax"/>
188
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
189
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:originalData"/>
190
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
191
+ <xs:element ref="xlf:segment"/>
192
+ <xs:element ref="xlf:ignorable"/>
193
+ </xs:choice>
194
+ </xs:sequence>
195
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
196
+ <xs:attribute name="name" use="optional"/>
197
+ <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
198
+ <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
199
+ <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
200
+ <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
201
+ <xs:attribute ref="xml:space" use="optional"/>
202
+ <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
203
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
204
+ </xs:complexType>
205
+ </xs:element>
206
+
207
+ <xs:element name="segment">
208
+ <xs:complexType mixed="false">
209
+ <xs:sequence>
210
+ <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
211
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
212
+ </xs:sequence>
213
+ <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
214
+ <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
215
+ <xs:attribute name="state" use="optional" type="xlf:stateType" default="initial"/>
216
+ <xs:attribute name="subState" use="optional"/>
217
+ </xs:complexType>
218
+ </xs:element>
219
+
220
+ <xs:element name="ignorable">
221
+ <xs:complexType mixed="false">
222
+ <xs:sequence>
223
+ <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
224
+ <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
225
+ </xs:sequence>
226
+ <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
227
+ </xs:complexType>
228
+ </xs:element>
229
+
230
+ <xs:element name="notes">
231
+ <xs:complexType mixed="false">
232
+ <xs:sequence>
233
+ <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:note"/>
234
+ </xs:sequence>
235
+ </xs:complexType>
236
+ </xs:element>
237
+
238
+ <xs:element name="note">
239
+ <xs:complexType mixed="true">
240
+ <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
241
+ <xs:attribute name="appliesTo" use="optional" type="xlf:appliesTo"/>
242
+ <xs:attribute name="category" use="optional"/>
243
+ <xs:attribute name="priority" use="optional" type="xlf:priorityValue" default="1"/>
244
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
245
+ </xs:complexType>
246
+ </xs:element>
247
+
248
+ <xs:element name="originalData">
249
+ <xs:complexType mixed="false">
250
+ <xs:sequence>
251
+ <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:data"/>
252
+ </xs:sequence>
253
+ </xs:complexType>
254
+ </xs:element>
255
+
256
+ <xs:element name="data">
257
+ <xs:complexType mixed="true">
258
+ <xs:sequence>
259
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="xlf:cp"/>
260
+ </xs:sequence>
261
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
262
+ <xs:attribute name="dir" use="optional" type="xlf:dirValue" default="auto"/>
263
+ <xs:attribute ref="xml:space" use="optional" fixed="preserve"/>
264
+ </xs:complexType>
265
+ </xs:element>
266
+
267
+ <xs:element name="source">
268
+ <xs:complexType mixed="true">
269
+ <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
270
+ <xs:attribute ref="xml:lang" use="optional"/>
271
+ <xs:attribute ref="xml:space" use="optional"/>
272
+ </xs:complexType>
273
+ </xs:element>
274
+
275
+ <xs:element name="target">
276
+ <xs:complexType mixed="true">
277
+ <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
278
+ <xs:attribute ref="xml:lang" use="optional"/>
279
+ <xs:attribute ref="xml:space" use="optional"/>
280
+ <xs:attribute name="order" use="optional" type="xs:positiveInteger"/>
281
+ </xs:complexType>
282
+ </xs:element>
283
+
284
+ <!-- Inline Elements -->
285
+
286
+ <xs:element name="cp">
287
+ <!-- Code Point -->
288
+ <xs:complexType mixed="false">
289
+ <xs:attribute name="hex" use="required" type="xs:hexBinary"/>
290
+ </xs:complexType>
291
+ </xs:element>
292
+
293
+ <xs:element name="ph">
294
+ <!-- Placeholder -->
295
+ <xs:complexType mixed="false">
296
+ <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
297
+ <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
298
+ <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
299
+ <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
300
+ <xs:attribute name="disp" use="optional"/>
301
+ <xs:attribute name="equiv" use="optional"/>
302
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
303
+ <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
304
+ <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
305
+ <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
306
+ <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
307
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
308
+ </xs:complexType>
309
+ </xs:element>
310
+
311
+ <xs:element name="pc">
312
+ <!-- Paired Code -->
313
+ <xs:complexType mixed="true">
314
+ <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
315
+ <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
316
+ <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
317
+ <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo"/>
318
+ <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
319
+ <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
320
+ <xs:attribute name="dispEnd" use="optional"/>
321
+ <xs:attribute name="dispStart" use="optional"/>
322
+ <xs:attribute name="equivEnd" use="optional"/>
323
+ <xs:attribute name="equivStart" use="optional"/>
324
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
325
+ <xs:attribute name="dataRefEnd" use="optional" type="xs:NMTOKEN"/>
326
+ <xs:attribute name="dataRefStart" use="optional" type="xs:NMTOKEN"/>
327
+ <xs:attribute name="subFlowsEnd" use="optional" type="xs:NMTOKENS"/>
328
+ <xs:attribute name="subFlowsStart" use="optional" type="xs:NMTOKENS"/>
329
+ <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
330
+ <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
331
+ <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
332
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
333
+ </xs:complexType>
334
+ </xs:element>
335
+
336
+ <xs:element name="sc">
337
+ <!-- Start Code -->
338
+ <xs:complexType mixed="false">
339
+ <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
340
+ <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
341
+ <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
342
+ <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
343
+ <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
344
+ <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
345
+ <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
346
+ <xs:attribute name="disp" use="optional"/>
347
+ <xs:attribute name="equiv" use="optional"/>
348
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
349
+ <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
350
+ <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
351
+ <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
352
+ <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
353
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
354
+ </xs:complexType>
355
+ </xs:element>
356
+
357
+ <xs:element name="ec">
358
+ <!-- End Code -->
359
+ <xs:complexType mixed="false">
360
+ <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
361
+ <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
362
+ <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
363
+ <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
364
+ <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
365
+ <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
366
+ <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
367
+ <xs:attribute name="disp" use="optional"/>
368
+ <xs:attribute name="equiv" use="optional"/>
369
+ <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
370
+ <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
371
+ <xs:attribute name="startRef" use="optional" type="xs:NMTOKEN"/>
372
+ <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
373
+ <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
374
+ <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
375
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
376
+ </xs:complexType>
377
+ </xs:element>
378
+
379
+ <xs:element name="mrk">
380
+ <!-- Annotation Marker -->
381
+ <xs:complexType mixed="true">
382
+ <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
383
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
384
+ <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
385
+ <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
386
+ <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
387
+ <xs:attribute name="value" use="optional"/>
388
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
389
+ </xs:complexType>
390
+ </xs:element>
391
+
392
+ <xs:element name="sm">
393
+ <!-- Start Annotation Marker -->
394
+ <xs:complexType mixed="false">
395
+ <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
396
+ <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
397
+ <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
398
+ <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
399
+ <xs:attribute name="value" use="optional"/>
400
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
401
+ </xs:complexType>
402
+ </xs:element>
403
+
404
+ <xs:element name="em">
405
+ <!-- End Annotation Marker -->
406
+ <xs:complexType mixed="false">
407
+ <xs:attribute name="startRef" use="required" type="xs:NMTOKEN"/>
408
+ </xs:complexType>
409
+ </xs:element>
410
+
411
+ </xs:schema>
app/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version='1.0'?>
2
+ <?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
3
+ <xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
4
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
5
+ xmlns ="http://www.w3.org/1999/xhtml"
6
+ xml:lang="en">
7
+
8
+ <xs:annotation>
9
+ <xs:documentation>
10
+ <div>
11
+ <h1>About the XML namespace</h1>
12
+
13
+ <div class="bodytext">
14
+ <p>
15
+
16
+ This schema document describes the XML namespace, in a form
17
+ suitable for import by other schema documents.
18
+ </p>
19
+ <p>
20
+ See <a href="http://www.w3.org/XML/1998/namespace.html">
21
+ http://www.w3.org/XML/1998/namespace.html</a> and
22
+ <a href="http://www.w3.org/TR/REC-xml">
23
+ http://www.w3.org/TR/REC-xml</a> for information
24
+ about this namespace.
25
+ </p>
26
+
27
+ <p>
28
+ Note that local names in this namespace are intended to be
29
+ defined only by the World Wide Web Consortium or its subgroups.
30
+ The names currently defined in this namespace are listed below.
31
+ They should not be used with conflicting semantics by any Working
32
+ Group, specification, or document instance.
33
+ </p>
34
+ <p>
35
+ See further below in this document for more information about <a
36
+ href="#usage">how to refer to this schema document from your own
37
+ XSD schema documents</a> and about <a href="#nsversioning">the
38
+ namespace-versioning policy governing this schema document</a>.
39
+ </p>
40
+ </div>
41
+ </div>
42
+
43
+ </xs:documentation>
44
+ </xs:annotation>
45
+
46
+ <xs:attribute name="lang">
47
+ <xs:annotation>
48
+ <xs:documentation>
49
+ <div>
50
+
51
+ <h3>lang (as an attribute name)</h3>
52
+ <p>
53
+
54
+ denotes an attribute whose value
55
+ is a language code for the natural language of the content of
56
+ any element; its value is inherited. This name is reserved
57
+ by virtue of its definition in the XML specification.</p>
58
+
59
+ </div>
60
+ <div>
61
+ <h4>Notes</h4>
62
+ <p>
63
+ Attempting to install the relevant ISO 2- and 3-letter
64
+ codes as the enumerated possible values is probably never
65
+ going to be a realistic possibility.
66
+ </p>
67
+ <p>
68
+
69
+ See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
70
+ http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
71
+ and the IANA language subtag registry at
72
+ <a href="http://www.iana.org/assignments/language-subtag-registry">
73
+ http://www.iana.org/assignments/language-subtag-registry</a>
74
+ for further information.
75
+ </p>
76
+ <p>
77
+
78
+ The union allows for the 'un-declaration' of xml:lang with
79
+ the empty string.
80
+ </p>
81
+ </div>
82
+ </xs:documentation>
83
+ </xs:annotation>
84
+ <xs:simpleType>
85
+ <xs:union memberTypes="xs:language">
86
+ <xs:simpleType>
87
+ <xs:restriction base="xs:string">
88
+ <xs:enumeration value=""/>
89
+
90
+ </xs:restriction>
91
+ </xs:simpleType>
92
+ </xs:union>
93
+ </xs:simpleType>
94
+ </xs:attribute>
95
+
96
+ <xs:attribute name="space">
97
+ <xs:annotation>
98
+ <xs:documentation>
99
+
100
+ <div>
101
+
102
+ <h3>space (as an attribute name)</h3>
103
+ <p>
104
+ denotes an attribute whose
105
+ value is a keyword indicating what whitespace processing
106
+ discipline is intended for the content of the element; its
107
+ value is inherited. This name is reserved by virtue of its
108
+ definition in the XML specification.</p>
109
+
110
+ </div>
111
+ </xs:documentation>
112
+ </xs:annotation>
113
+ <xs:simpleType>
114
+
115
+ <xs:restriction base="xs:NCName">
116
+ <xs:enumeration value="default"/>
117
+ <xs:enumeration value="preserve"/>
118
+ </xs:restriction>
119
+ </xs:simpleType>
120
+ </xs:attribute>
121
+
122
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
123
+ <xs:documentation>
124
+
125
+ <div>
126
+
127
+ <h3>base (as an attribute name)</h3>
128
+ <p>
129
+ denotes an attribute whose value
130
+ provides a URI to be used as the base for interpreting any
131
+ relative URIs in the scope of the element on which it
132
+ appears; its value is inherited. This name is reserved
133
+ by virtue of its definition in the XML Base specification.</p>
134
+
135
+ <p>
136
+ See <a
137
+ href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
138
+ for information about this attribute.
139
+ </p>
140
+
141
+ </div>
142
+ </xs:documentation>
143
+ </xs:annotation>
144
+ </xs:attribute>
145
+
146
+ <xs:attribute name="id" type="xs:ID">
147
+ <xs:annotation>
148
+ <xs:documentation>
149
+ <div>
150
+
151
+ <h3>id (as an attribute name)</h3>
152
+ <p>
153
+
154
+ denotes an attribute whose value
155
+ should be interpreted as if declared to be of type ID.
156
+ This name is reserved by virtue of its definition in the
157
+ xml:id specification.</p>
158
+
159
+ <p>
160
+ See <a
161
+ href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
162
+ for information about this attribute.
163
+ </p>
164
+ </div>
165
+ </xs:documentation>
166
+ </xs:annotation>
167
+
168
+ </xs:attribute>
169
+
170
+ <xs:attributeGroup name="specialAttrs">
171
+ <xs:attribute ref="xml:base"/>
172
+ <xs:attribute ref="xml:lang"/>
173
+ <xs:attribute ref="xml:space"/>
174
+ <xs:attribute ref="xml:id"/>
175
+ </xs:attributeGroup>
176
+
177
+ <xs:annotation>
178
+
179
+ <xs:documentation>
180
+ <div>
181
+
182
+ <h3>Father (in any context at all)</h3>
183
+
184
+ <div class="bodytext">
185
+ <p>
186
+ denotes Jon Bosak, the chair of
187
+ the original XML Working Group. This name is reserved by
188
+ the following decision of the W3C XML Plenary and
189
+ XML Coordination groups:
190
+ </p>
191
+ <blockquote>
192
+ <p>
193
+
194
+ In appreciation for his vision, leadership and
195
+ dedication the W3C XML Plenary on this 10th day of
196
+ February, 2000, reserves for Jon Bosak in perpetuity
197
+ the XML name "xml:Father".
198
+ </p>
199
+ </blockquote>
200
+ </div>
201
+ </div>
202
+ </xs:documentation>
203
+ </xs:annotation>
204
+
205
+ <xs:annotation>
206
+ <xs:documentation>
207
+
208
+ <div xml:id="usage" id="usage">
209
+ <h2><a name="usage">About this schema document</a></h2>
210
+
211
+ <div class="bodytext">
212
+ <p>
213
+ This schema defines attributes and an attribute group suitable
214
+ for use by schemas wishing to allow <code>xml:base</code>,
215
+ <code>xml:lang</code>, <code>xml:space</code> or
216
+ <code>xml:id</code> attributes on elements they define.
217
+ </p>
218
+
219
+ <p>
220
+ To enable this, such a schema must import this schema for
221
+ the XML namespace, e.g. as follows:
222
+ </p>
223
+ <pre>
224
+ &lt;schema.. .>
225
+ .. .
226
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
227
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
228
+ </pre>
229
+ <p>
230
+ or
231
+ </p>
232
+ <pre>
233
+
234
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
235
+ schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
236
+ </pre>
237
+ <p>
238
+ Subsequently, qualified reference to any of the attributes or the
239
+ group defined below will have the desired effect, e.g.
240
+ </p>
241
+ <pre>
242
+ &lt;type.. .>
243
+ .. .
244
+ &lt;attributeGroup ref="xml:specialAttrs"/>
245
+ </pre>
246
+ <p>
247
+ will define a type which will schema-validate an instance element
248
+ with any of those attributes.
249
+ </p>
250
+
251
+ </div>
252
+ </div>
253
+ </xs:documentation>
254
+ </xs:annotation>
255
+
256
+ <xs:annotation>
257
+ <xs:documentation>
258
+ <div id="nsversioning" xml:id="nsversioning">
259
+ <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
260
+
261
+ <div class="bodytext">
262
+ <p>
263
+ In keeping with the XML Schema WG's standard versioning
264
+ policy, this schema document will persist at
265
+ <a href="http://www.w3.org/2009/01/xml.xsd">
266
+ http://www.w3.org/2009/01/xml.xsd</a>.
267
+ </p>
268
+ <p>
269
+ At the date of issue it can also be found at
270
+ <a href="http://www.w3.org/2001/xml.xsd">
271
+ http://www.w3.org/2001/xml.xsd</a>.
272
+ </p>
273
+
274
+ <p>
275
+ The schema document at that URI may however change in the future,
276
+ in order to remain compatible with the latest version of XML
277
+ Schema itself, or with the XML namespace itself. In other words,
278
+ if the XML Schema or XML namespaces change, the version of this
279
+ document at <a href="http://www.w3.org/2001/xml.xsd">
280
+ http://www.w3.org/2001/xml.xsd
281
+ </a>
282
+ will change accordingly; the version at
283
+ <a href="http://www.w3.org/2009/01/xml.xsd">
284
+ http://www.w3.org/2009/01/xml.xsd
285
+ </a>
286
+ will not change.
287
+ </p>
288
+ <p>
289
+
290
+ Previous dated (and unchanging) versions of this schema
291
+ document are at:
292
+ </p>
293
+ <ul>
294
+ <li><a href="http://www.w3.org/2009/01/xml.xsd">
295
+ http://www.w3.org/2009/01/xml.xsd</a></li>
296
+ <li><a href="http://www.w3.org/2007/08/xml.xsd">
297
+ http://www.w3.org/2007/08/xml.xsd</a></li>
298
+ <li><a href="http://www.w3.org/2004/10/xml.xsd">
299
+
300
+ http://www.w3.org/2004/10/xml.xsd</a></li>
301
+ <li><a href="http://www.w3.org/2001/03/xml.xsd">
302
+ http://www.w3.org/2001/03/xml.xsd</a></li>
303
+ </ul>
304
+ </div>
305
+ </div>
306
+ </xs:documentation>
307
+ </xs:annotation>
308
+
309
+ </xs:schema>
app/vendor/symfony/translation/LoggingTranslator.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ use Psr\Log\LoggerInterface;
15
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
16
+
17
+ /**
18
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
19
+ */
20
+ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface
21
+ {
22
+ /**
23
+ * @var TranslatorInterface|TranslatorBagInterface
24
+ */
25
+ private $translator;
26
+
27
+ private $logger;
28
+
29
+ /**
30
+ * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
31
+ * @param LoggerInterface $logger
32
+ */
33
+ public function __construct(TranslatorInterface $translator, LoggerInterface $logger)
34
+ {
35
+ if (!$translator instanceof TranslatorBagInterface) {
36
+ throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator)));
37
+ }
38
+
39
+ $this->translator = $translator;
40
+ $this->logger = $logger;
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ */
46
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
47
+ {
48
+ $trans = $this->translator->trans($id, $parameters, $domain, $locale);
49
+ $this->log($id, $domain, $locale);
50
+
51
+ return $trans;
52
+ }
53
+
54
+ /**
55
+ * {@inheritdoc}
56
+ */
57
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
58
+ {
59
+ $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
60
+ $this->log($id, $domain, $locale);
61
+
62
+ return $trans;
63
+ }
64
+
65
+ /**
66
+ * {@inheritdoc}
67
+ */
68
+ public function setLocale($locale)
69
+ {
70
+ $this->translator->setLocale($locale);
71
+ }
72
+
73
+ /**
74
+ * {@inheritdoc}
75
+ */
76
+ public function getLocale()
77
+ {
78
+ return $this->translator->getLocale();
79
+ }
80
+
81
+ /**
82
+ * {@inheritdoc}
83
+ */
84
+ public function getCatalogue($locale = null)
85
+ {
86
+ return $this->translator->getCatalogue($locale);
87
+ }
88
+
89
+ /**
90
+ * Gets the fallback locales.
91
+ *
92
+ * @return array $locales The fallback locales
93
+ */
94
+ public function getFallbackLocales()
95
+ {
96
+ if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
97
+ return $this->translator->getFallbackLocales();
98
+ }
99
+
100
+ return array();
101
+ }
102
+
103
+ /**
104
+ * Passes through all unknown calls onto the translator object.
105
+ */
106
+ public function __call($method, $args)
107
+ {
108
+ return call_user_func_array(array($this->translator, $method), $args);
109
+ }
110
+
111
+ /**
112
+ * Logs for missing translations.
113
+ *
114
+ * @param string $id
115
+ * @param string|null $domain
116
+ * @param string|null $locale
117
+ */
118
+ private function log($id, $domain, $locale)
119
+ {
120
+ if (null === $domain) {
121
+ $domain = 'messages';
122
+ }
123
+
124
+ $id = (string) $id;
125
+ $catalogue = $this->translator->getCatalogue($locale);
126
+ if ($catalogue->defines($id, $domain)) {
127
+ return;
128
+ }
129
+
130
+ if ($catalogue->has($id, $domain)) {
131
+ $this->logger->debug('Translation use fallback catalogue.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()));
132
+ } else {
133
+ $this->logger->warning('Translation not found.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()));
134
+ }
135
+ }
136
+ }
app/vendor/symfony/translation/MessageCatalogue.php ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ use Symfony\Component\Config\Resource\ResourceInterface;
15
+ use Symfony\Component\Translation\Exception\LogicException;
16
+
17
+ /**
18
+ * @author Fabien Potencier <fabien@symfony.com>
19
+ */
20
+ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
21
+ {
22
+ private $messages = array();
23
+ private $metadata = array();
24
+ private $resources = array();
25
+ private $locale;
26
+ private $fallbackCatalogue;
27
+ private $parent;
28
+
29
+ /**
30
+ * @param string $locale The locale
31
+ * @param array $messages An array of messages classified by domain
32
+ */
33
+ public function __construct(?string $locale, array $messages = array())
34
+ {
35
+ $this->locale = $locale;
36
+ $this->messages = $messages;
37
+ }
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ */
42
+ public function getLocale()
43
+ {
44
+ return $this->locale;
45
+ }
46
+
47
+ /**
48
+ * {@inheritdoc}
49
+ */
50
+ public function getDomains()
51
+ {
52
+ return array_keys($this->messages);
53
+ }
54
+
55
+ /**
56
+ * {@inheritdoc}
57
+ */
58
+ public function all($domain = null)
59
+ {
60
+ if (null === $domain) {
61
+ return $this->messages;
62
+ }
63
+
64
+ return isset($this->messages[$domain]) ? $this->messages[$domain] : array();
65
+ }
66
+
67
+ /**
68
+ * {@inheritdoc}
69
+ */
70
+ public function set($id, $translation, $domain = 'messages')
71
+ {
72
+ $this->add(array($id => $translation), $domain);
73
+ }
74
+
75
+ /**
76
+ * {@inheritdoc}
77
+ */
78
+ public function has($id, $domain = 'messages')
79
+ {
80
+ if (isset($this->messages[$domain][$id])) {
81
+ return true;
82
+ }
83
+
84
+ if (null !== $this->fallbackCatalogue) {
85
+ return $this->fallbackCatalogue->has($id, $domain);
86
+ }
87
+
88
+ return false;
89
+ }
90
+
91
+ /**
92
+ * {@inheritdoc}
93
+ */
94
+ public function defines($id, $domain = 'messages')
95
+ {
96
+ return isset($this->messages[$domain][$id]);
97
+ }
98
+
99
+ /**
100
+ * {@inheritdoc}
101
+ */
102
+ public function get($id, $domain = 'messages')
103
+ {
104
+ if (isset($this->messages[$domain][$id])) {
105
+ return $this->messages[$domain][$id];
106
+ }
107
+
108
+ if (null !== $this->fallbackCatalogue) {
109
+ return $this->fallbackCatalogue->get($id, $domain);
110
+ }
111
+
112
+ return $id;
113
+ }
114
+
115
+ /**
116
+ * {@inheritdoc}
117
+ */
118
+ public function replace($messages, $domain = 'messages')
119
+ {
120
+ $this->messages[$domain] = array();
121
+
122
+ $this->add($messages, $domain);
123
+ }
124
+
125
+ /**
126
+ * {@inheritdoc}
127
+ */
128
+ public function add($messages, $domain = 'messages')
129
+ {
130
+ if (!isset($this->messages[$domain])) {
131
+ $this->messages[$domain] = $messages;
132
+ } else {
133
+ $this->messages[$domain] = array_replace($this->messages[$domain], $messages);
134
+ }
135
+ }
136
+
137
+ /**
138
+ * {@inheritdoc}
139
+ */
140
+ public function addCatalogue(MessageCatalogueInterface $catalogue)
141
+ {
142
+ if ($catalogue->getLocale() !== $this->locale) {
143
+ throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale));
144
+ }
145
+
146
+ foreach ($catalogue->all() as $domain => $messages) {
147
+ $this->add($messages, $domain);
148
+ }
149
+
150
+ foreach ($catalogue->getResources() as $resource) {
151
+ $this->addResource($resource);
152
+ }
153
+
154
+ if ($catalogue instanceof MetadataAwareInterface) {
155
+ $metadata = $catalogue->getMetadata('', '');
156
+ $this->addMetadata($metadata);
157
+ }
158
+ }
159
+
160
+ /**
161
+ * {@inheritdoc}
162
+ */
163
+ public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
164
+ {
165
+ // detect circular references
166
+ $c = $catalogue;
167
+ while ($c = $c->getFallbackCatalogue()) {
168
+ if ($c->getLocale() === $this->getLocale()) {
169
+ throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
170
+ }
171
+ }
172
+
173
+ $c = $this;
174
+ do {
175
+ if ($c->getLocale() === $catalogue->getLocale()) {
176
+ throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
177
+ }
178
+
179
+ foreach ($catalogue->getResources() as $resource) {
180
+ $c->addResource($resource);
181
+ }
182
+ } while ($c = $c->parent);
183
+
184
+ $catalogue->parent = $this;
185
+ $this->fallbackCatalogue = $catalogue;
186
+
187
+ foreach ($catalogue->getResources() as $resource) {
188
+ $this->addResource($resource);
189
+ }
190
+ }
191
+
192
+ /**
193
+ * {@inheritdoc}
194
+ */
195
+ public function getFallbackCatalogue()
196
+ {
197
+ return $this->fallbackCatalogue;
198
+ }
199
+
200
+ /**
201
+ * {@inheritdoc}
202
+ */
203
+ public function getResources()
204
+ {
205
+ return array_values($this->resources);
206
+ }
207
+
208
+ /**
209
+ * {@inheritdoc}
210
+ */
211
+ public function addResource(ResourceInterface $resource)
212
+ {
213
+ $this->resources[$resource->__toString()] = $resource;
214
+ }
215
+
216
+ /**
217
+ * {@inheritdoc}
218
+ */
219
+ public function getMetadata($key = '', $domain = 'messages')
220
+ {
221
+ if ('' == $domain) {
222
+ return $this->metadata;
223
+ }
224
+
225
+ if (isset($this->metadata[$domain])) {
226
+ if ('' == $key) {
227
+ return $this->metadata[$domain];
228
+ }
229
+
230
+ if (isset($this->metadata[$domain][$key])) {
231
+ return $this->metadata[$domain][$key];
232
+ }
233
+ }
234
+ }
235
+
236
+ /**
237
+ * {@inheritdoc}
238
+ */
239
+ public function setMetadata($key, $value, $domain = 'messages')
240
+ {
241
+ $this->metadata[$domain][$key] = $value;
242
+ }
243
+
244
+ /**
245
+ * {@inheritdoc}
246
+ */
247
+ public function deleteMetadata($key = '', $domain = 'messages')
248
+ {
249
+ if ('' == $domain) {
250
+ $this->metadata = array();
251
+ } elseif ('' == $key) {
252
+ unset($this->metadata[$domain]);
253
+ } else {
254
+ unset($this->metadata[$domain][$key]);
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Adds current values with the new values.
260
+ *
261
+ * @param array $values Values to add
262
+ */
263
+ private function addMetadata(array $values)
264
+ {
265
+ foreach ($values as $domain => $keys) {
266
+ foreach ($keys as $key => $value) {
267
+ $this->setMetadata($key, $value, $domain);
268
+ }
269
+ }
270
+ }
271
+ }
app/vendor/symfony/translation/MessageCatalogueInterface.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ use Symfony\Component\Config\Resource\ResourceInterface;
15
+
16
+ /**
17
+ * MessageCatalogueInterface.
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ */
21
+ interface MessageCatalogueInterface
22
+ {
23
+ /**
24
+ * Gets the catalogue locale.
25
+ *
26
+ * @return string The locale
27
+ */
28
+ public function getLocale();
29
+
30
+ /**
31
+ * Gets the domains.
32
+ *
33
+ * @return array An array of domains
34
+ */
35
+ public function getDomains();
36
+
37
+ /**
38
+ * Gets the messages within a given domain.
39
+ *
40
+ * If $domain is null, it returns all messages.
41
+ *
42
+ * @param string $domain The domain name
43
+ *
44
+ * @return array An array of messages
45
+ */
46
+ public function all($domain = null);
47
+
48
+ /**
49
+ * Sets a message translation.
50
+ *
51
+ * @param string $id The message id
52
+ * @param string $translation The messages translation
53
+ * @param string $domain The domain name
54
+ */
55
+ public function set($id, $translation, $domain = 'messages');
56
+
57
+ /**
58
+ * Checks if a message has a translation.
59
+ *
60
+ * @param string $id The message id
61
+ * @param string $domain The domain name
62
+ *
63
+ * @return bool true if the message has a translation, false otherwise
64
+ */
65
+ public function has($id, $domain = 'messages');
66
+
67
+ /**
68
+ * Checks if a message has a translation (it does not take into account the fallback mechanism).
69
+ *
70
+ * @param string $id The message id
71
+ * @param string $domain The domain name
72
+ *
73
+ * @return bool true if the message has a translation, false otherwise
74
+ */
75
+ public function defines($id, $domain = 'messages');
76
+
77
+ /**
78
+ * Gets a message translation.
79
+ *
80
+ * @param string $id The message id
81
+ * @param string $domain The domain name
82
+ *
83
+ * @return string The message translation
84
+ */
85
+ public function get($id, $domain = 'messages');
86
+
87
+ /**
88
+ * Sets translations for a given domain.
89
+ *
90
+ * @param array $messages An array of translations
91
+ * @param string $domain The domain name
92
+ */
93
+ public function replace($messages, $domain = 'messages');
94
+
95
+ /**
96
+ * Adds translations for a given domain.
97
+ *
98
+ * @param array $messages An array of translations
99
+ * @param string $domain The domain name
100
+ */
101
+ public function add($messages, $domain = 'messages');
102
+
103
+ /**
104
+ * Merges translations from the given Catalogue into the current one.
105
+ *
106
+ * The two catalogues must have the same locale.
107
+ */
108
+ public function addCatalogue(self $catalogue);
109
+
110
+ /**
111
+ * Merges translations from the given Catalogue into the current one
112
+ * only when the translation does not exist.
113
+ *
114
+ * This is used to provide default translations when they do not exist for the current locale.
115
+ */
116
+ public function addFallbackCatalogue(self $catalogue);
117
+
118
+ /**
119
+ * Gets the fallback catalogue.
120
+ *
121
+ * @return self|null A MessageCatalogueInterface instance or null when no fallback has been set
122
+ */
123
+ public function getFallbackCatalogue();
124
+
125
+ /**
126
+ * Returns an array of resources loaded to build this collection.
127
+ *
128
+ * @return ResourceInterface[] An array of resources
129
+ */
130
+ public function getResources();
131
+
132
+ /**
133
+ * Adds a resource for this collection.
134
+ */
135
+ public function addResource(ResourceInterface $resource);
136
+ }
app/vendor/symfony/translation/MessageSelector.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ use Symfony\Component\Translation\Exception\InvalidArgumentException;
15
+
16
+ /**
17
+ * MessageSelector.
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ * @author Bernhard Schussek <bschussek@gmail.com>
21
+ */
22
+ class MessageSelector
23
+ {
24
+ /**
25
+ * Given a message with different plural translations separated by a
26
+ * pipe (|), this method returns the correct portion of the message based
27
+ * on the given number, locale and the pluralization rules in the message
28
+ * itself.
29
+ *
30
+ * The message supports two different types of pluralization rules:
31
+ *
32
+ * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
33
+ * indexed: There is one apple|There are %count% apples
34
+ *
35
+ * The indexed solution can also contain labels (e.g. one: There is one apple).
36
+ * This is purely for making the translations more clear - it does not
37
+ * affect the functionality.
38
+ *
39
+ * The two methods can also be mixed:
40
+ * {0} There are no apples|one: There is one apple|more: There are %count% apples
41
+ *
42
+ * @param string $message The message being translated
43
+ * @param int $number The number of items represented for the message
44
+ * @param string $locale The locale to use for choosing
45
+ *
46
+ * @return string
47
+ *
48
+ * @throws InvalidArgumentException
49
+ */
50
+ public function choose($message, $number, $locale)
51
+ {
52
+ $parts = array();
53
+ if (preg_match('/^\|++$/', $message)) {
54
+ $parts = explode('|', $message);
55
+ } elseif (preg_match_all('/(?:\|\||[^\|])++/', $message, $matches)) {
56
+ $parts = $matches[0];
57
+ }
58
+
59
+ $explicitRules = array();
60
+ $standardRules = array();
61
+ foreach ($parts as $part) {
62
+ $part = trim(str_replace('||', '|', $part));
63
+
64
+ if (preg_match('/^(?P<interval>'.Interval::getIntervalRegexp().')\s*(?P<message>.*?)$/xs', $part, $matches)) {
65
+ $explicitRules[$matches['interval']] = $matches['message'];
66
+ } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
67
+ $standardRules[] = $matches[1];
68
+ } else {
69
+ $standardRules[] = $part;
70
+ }
71
+ }
72
+
73
+ // try to match an explicit rule, then fallback to the standard ones
74
+ foreach ($explicitRules as $interval => $m) {
75
+ if (Interval::test($number, $interval)) {
76
+ return $m;
77
+ }
78
+ }
79
+
80
+ $position = PluralizationRules::get($number, $locale);
81
+
82
+ if (!isset($standardRules[$position])) {
83
+ // when there's exactly one rule given, and that rule is a standard
84
+ // rule, use this rule
85
+ if (1 === count($parts) && isset($standardRules[0])) {
86
+ return $standardRules[0];
87
+ }
88
+
89
+ throw new InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number));
90
+ }
91
+
92
+ return $standardRules[$position];
93
+ }
94
+ }
app/vendor/symfony/translation/MetadataAwareInterface.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ /**
15
+ * MetadataAwareInterface.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ interface MetadataAwareInterface
20
+ {
21
+ /**
22
+ * Gets metadata for the given domain and key.
23
+ *
24
+ * Passing an empty domain will return an array with all metadata indexed by
25
+ * domain and then by key. Passing an empty key will return an array with all
26
+ * metadata for the given domain.
27
+ *
28
+ * @param string $key The key
29
+ * @param string $domain The domain name
30
+ *
31
+ * @return mixed The value that was set or an array with the domains/keys or null
32
+ */
33
+ public function getMetadata($key = '', $domain = 'messages');
34
+
35
+ /**
36
+ * Adds metadata to a message domain.
37
+ *
38
+ * @param string $key The key
39
+ * @param mixed $value The value
40
+ * @param string $domain The domain name
41
+ */
42
+ public function setMetadata($key, $value, $domain = 'messages');
43
+
44
+ /**
45
+ * Deletes metadata for the given key and domain.
46
+ *
47
+ * Passing an empty domain will delete all metadata. Passing an empty key will
48
+ * delete all metadata for the given domain.
49
+ *
50
+ * @param string $key The key
51
+ * @param string $domain The domain name
52
+ */
53
+ public function deleteMetadata($key = '', $domain = 'messages');
54
+ }
app/vendor/symfony/translation/PluralizationRules.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation;
13
+
14
+ /**
15
+ * Returns the plural rules for a given locale.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class PluralizationRules
20
+ {
21
+ private static $rules = array();
22
+
23
+ /**
24
+ * Returns the plural position to use for the given locale and number.
25
+ *
26
+ * @param int $number The number
27
+ * @param string $locale The locale
28
+ *
29
+ * @return int The plural position
30
+ */
31
+ public static function get($number, $locale)
32
+ {
33
+ if ('pt_BR' === $locale) {
34
+ // temporary set a locale for brazilian
35
+ $locale = 'xbr';
36
+ }
37
+
38
+ if (strlen($locale) > 3) {
39
+ $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
40
+ }
41
+
42
+ if (isset(self::$rules[$locale])) {
43
+ $return = call_user_func(self::$rules[$locale], $number);
44
+
45
+ if (!is_int($return) || $return < 0) {
46
+ return 0;
47
+ }
48
+
49
+ return $return;
50
+ }
51
+
52
+ /*
53
+ * The plural rules are derived from code of the Zend Framework (2010-09-25),
54
+ * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
55
+ * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
56
+ */
57
+ switch ($locale) {
58
+ case 'az':
59
+ case 'bo':
60
+ case 'dz':
61
+ case 'id':
62
+ case 'ja':
63
+ case 'jv':
64
+ case 'ka':
65
+ case 'km':
66
+ case 'kn':
67
+ case 'ko':
68
+ case 'ms':
69
+ case 'th':
70
+ case 'tr':
71
+ case 'vi':
72
+ case 'zh':
73
+ return 0;
74
+
75
+ case 'af':
76
+ case 'bn':
77
+ case 'bg':
78
+ case 'ca':
79
+ case 'da':
80
+ case 'de':
81
+ case 'el':
82
+ case 'en':
83
+ case 'eo':
84
+ case 'es':
85
+ case 'et':
86
+ case 'eu':
87
+ case 'fa':
88
+ case 'fi':
89
+ case 'fo':
90
+ case 'fur':
91
+ case 'fy':
92
+ case 'gl':
93
+ case 'gu':
94
+ case 'ha':
95
+ case 'he':
96
+ case 'hu':
97
+ case 'is':
98
+ case 'it':
99
+ case 'ku':
100
+ case 'lb':
101
+ case 'ml':
102
+ case 'mn':
103
+ case 'mr':
104
+ case 'nah':
105
+ case 'nb':
106
+ case 'ne':
107
+ case 'nl':
108
+ case 'nn':
109
+ case 'no':
110
+ case 'oc':
111
+ case 'om':
112
+ case 'or':
113
+ case 'pa':
114
+ case 'pap':
115
+ case 'ps':
116
+ case 'pt':
117
+ case 'so':
118
+ case 'sq':
119
+ case 'sv':
120
+ case 'sw':
121
+ case 'ta':
122
+ case 'te':
123
+ case 'tk':
124
+ case 'ur':
125
+ case 'zu':
126
+ return (1 == $number) ? 0 : 1;
127
+
128
+ case 'am':
129
+ case 'bh':
130
+ case 'fil':
131
+ case 'fr':
132
+ case 'gun':
133
+ case 'hi':
134
+ case 'hy':
135
+ case 'ln':
136
+ case 'mg':
137
+ case 'nso':
138
+ case 'xbr':
139
+ case 'ti':
140
+ case 'wa':
141
+ return ((0 == $number) || (1 == $number)) ? 0 : 1;
142
+
143
+ case 'be':
144
+ case 'bs':
145
+ case 'hr':
146
+ case 'ru':
147
+ case 'sr':
148
+ case 'uk':
149
+ return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
150
+
151
+ case 'cs':
152
+ case 'sk':
153
+ return (1 == $number) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);
154
+
155
+ case 'ga':
156
+ return (1 == $number) ? 0 : ((2 == $number) ? 1 : 2);
157
+
158
+ case 'lt':
159
+ return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
160
+
161
+ case 'sl':
162
+ return (1 == $number % 100) ? 0 : ((2 == $number % 100) ? 1 : (((3 == $number % 100) || (4 == $number % 100)) ? 2 : 3));
163
+
164
+ case 'mk':
165
+ return (1 == $number % 10) ? 0 : 1;
166
+
167
+ case 'mt':
168
+ return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));
169
+
170
+ case 'lv':
171
+ return (0 == $number) ? 0 : (((1 == $number % 10) && (11 != $number % 100)) ? 1 : 2);
172
+
173
+ case 'pl':
174
+ return (1 == $number) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);
175
+
176
+ case 'cy':
177
+ return (1 == $number) ? 0 : ((2 == $number) ? 1 : (((8 == $number) || (11 == $number)) ? 2 : 3));
178
+
179
+ case 'ro':
180
+ return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);
181
+
182
+ case 'ar':
183
+ return (0 == $number) ? 0 : ((1 == $number) ? 1 : ((2 == $number) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));
184
+
185
+ default:
186
+ return 0;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Overrides the default plural rule for a given locale.
192
+ *
193
+ * @param callable $rule A PHP callable
194
+ * @param string $locale The locale
195
+ */
196
+ public static function set(callable $rule, $locale)
197
+ {
198
+ if ('pt_BR' === $locale) {
199
+ // temporary set a locale for brazilian
200
+ $locale = 'xbr';
201
+ }
202
+
203
+ if (strlen($locale) > 3) {
204
+ $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
205
+ }
206
+
207
+ self::$rules[$locale] = $rule;
208
+ }
209
+ }
app/vendor/symfony/translation/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Translation Component
2
+ =====================
3
+
4
+ The Translation component provides tools to internationalize your application.
5
+
6
+ Resources
7
+ ---------
8
+
9
+ * [Documentation](https://symfony.com/doc/current/components/translation/index.html)
10
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
11
+ * [Report issues](https://github.com/symfony/symfony/issues) and
12
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
13
+ in the [main Symfony repository](https://github.com/symfony/symfony)
app/vendor/symfony/translation/Reader/TranslationReader.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Reader;
13
+
14
+ use Symfony\Component\Finder\Finder;
15
+ use Symfony\Component\Translation\Loader\LoaderInterface;
16
+ use Symfony\Component\Translation\MessageCatalogue;
17
+
18
+ /**
19
+ * TranslationReader reads translation messages from translation files.
20
+ *
21
+ * @author Michel Salib <michelsalib@hotmail.com>
22
+ */
23
+ class TranslationReader implements TranslationReaderInterface
24
+ {
25
+ /**
26
+ * Loaders used for import.
27
+ *
28
+ * @var array
29
+ */
30
+ private $loaders = array();
31
+
32
+ /**
33
+ * Adds a loader to the translation extractor.
34
+ *
35
+ * @param string $format The format of the loader
36
+ * @param LoaderInterface $loader
37
+ */
38
+ public function addLoader($format, LoaderInterface $loader)
39
+ {
40
+ $this->loaders[$format] = $loader;
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ */
46
+ public function read($directory, MessageCatalogue $catalogue)
47
+ {
48
+ if (!is_dir($directory)) {
49
+ return;
50
+ }
51
+
52
+ foreach ($this->loaders as $format => $loader) {
53
+ // load any existing translation files
54
+ $finder = new Finder();
55
+ $extension = $catalogue->getLocale().'.'.$format;
56
+ $files = $finder->files()->name('*.'.$extension)->in($directory);
57
+ foreach ($files as $file) {
58
+ $domain = substr($file->getFilename(), 0, -1 * strlen($extension) - 1);
59
+ $catalogue->addCatalogue($loader->load($file->getPathname(), $catalogue->getLocale(), $domain));
60
+ }
61
+ }
62
+ }
63
+ }
app/vendor/symfony/translation/Reader/TranslationReaderInterface.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Translation\Reader;
13
+
14
+ use Symfony\Component\Translation\MessageCatalogue;
15
+
16
+ /**
17
+ * TranslationReader reads translation messages from translation files.
18
+ *
19
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
20
+ */
21
+ interface TranslationReaderInterface
22
+ {
23
+ /**
24
+ * Reads translation messages from a directory to the catalogue.
25
+ *
26
+ * @param string $directory
27
+ * @param MessageCatalogue $catalogue
28
+ */
29
+ public function read($directory, MessageCatalogue $catalogue);
30
+ }
app/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd ADDED
@@ -0,0 +1,2223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!--
4
+
5
+ May-19-2004:
6
+ - Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements
7
+ to <choice> itself.
8
+ - Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
9
+ <alt-trans>.
10
+
11
+ Oct-2005
12
+ - updated version info to 1.2
13
+ - equiv-trans attribute to <trans-unit> element
14
+ - merged-trans attribute for <group> element
15
+ - Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source>
16
+ - Create a new value "seg" for the mtype attribute of the <mrk> element
17
+ - Add mid as an optional attribute for the <alt-trans> element
18
+
19
+ Nov-14-2005
20
+ - Changed name attribute for <context-group> from required to optional
21
+ - Added extension point at <xliff>
22
+
23
+ Jan-9-2006
24
+ - Added alttranstype type attribute to <alt-trans>, and values
25
+
26
+ Jan-10-2006
27
+ - Corrected error with overwritten purposeValueList
28
+ - Corrected name="AttrType_Version", attribute should have been "name"
29
+
30
+ -->
31
+ <xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
32
+ <!-- Import for xml:lang and xml:space -->
33
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
34
+ <!-- Attributes Lists -->
35
+ <xsd:simpleType name="XTend">
36
+ <xsd:restriction base="xsd:string">
37
+ <xsd:pattern value="x-[^\s]+"/>
38
+ </xsd:restriction>
39
+ </xsd:simpleType>
40
+ <xsd:simpleType name="context-typeValueList">
41
+ <xsd:annotation>
42
+ <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
43
+ </xsd:annotation>
44
+ <xsd:restriction base="xsd:string">
45
+ <xsd:enumeration value="database">
46
+ <xsd:annotation>
47
+ <xsd:documentation>Indicates a database content.</xsd:documentation>
48
+ </xsd:annotation>
49
+ </xsd:enumeration>
50
+ <xsd:enumeration value="element">
51
+ <xsd:annotation>
52
+ <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
53
+ </xsd:annotation>
54
+ </xsd:enumeration>
55
+ <xsd:enumeration value="elementtitle">
56
+ <xsd:annotation>
57
+ <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
58
+ </xsd:annotation>
59
+ </xsd:enumeration>
60
+ <xsd:enumeration value="linenumber">
61
+ <xsd:annotation>
62
+ <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
63
+ </xsd:annotation>
64
+ </xsd:enumeration>
65
+ <xsd:enumeration value="numparams">
66
+ <xsd:annotation>
67
+ <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
68
+ </xsd:annotation>
69
+ </xsd:enumeration>
70
+ <xsd:enumeration value="paramnotes">
71
+ <xsd:annotation>
72
+ <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
73
+ </xsd:annotation>
74
+ </xsd:enumeration>
75
+ <xsd:enumeration value="record">
76
+ <xsd:annotation>
77
+ <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
78
+ </xsd:annotation>
79
+ </xsd:enumeration>
80
+ <xsd:enumeration value="recordtitle">
81
+ <xsd:annotation>
82
+ <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
83
+ </xsd:annotation>
84
+ </xsd:enumeration>
85
+ <xsd:enumeration value="sourcefile">
86
+ <xsd:annotation>
87
+ <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
88
+ </xsd:annotation>
89
+ </xsd:enumeration>
90
+ </xsd:restriction>
91
+ </xsd:simpleType>
92
+ <xsd:simpleType name="count-typeValueList">
93
+ <xsd:annotation>
94
+ <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
95
+ </xsd:annotation>
96
+ <xsd:restriction base="xsd:NMTOKEN">
97
+ <xsd:enumeration value="num-usages">
98
+ <xsd:annotation>
99
+ <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
100
+ </xsd:annotation>
101
+ </xsd:enumeration>
102
+ <xsd:enumeration value="repetition">
103
+ <xsd:annotation>
104
+ <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
105
+ </xsd:annotation>
106
+ </xsd:enumeration>
107
+ <xsd:enumeration value="total">
108
+ <xsd:annotation>
109
+ <xsd:documentation>Indicates a total count.</xsd:documentation>
110
+ </xsd:annotation>
111
+ </xsd:enumeration>
112
+ </xsd:restriction>
113
+ </xsd:simpleType>
114
+ <xsd:simpleType name="InlineDelimitersValueList">
115
+ <xsd:annotation>
116
+ <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
117
+ </xsd:annotation>
118
+ <xsd:restriction base="xsd:NMTOKEN">
119
+ <xsd:enumeration value="bold">
120
+ <xsd:annotation>
121
+ <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
122
+ </xsd:annotation>
123
+ </xsd:enumeration>
124
+ <xsd:enumeration value="italic">
125
+ <xsd:annotation>
126
+ <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
127
+ </xsd:annotation>
128
+ </xsd:enumeration>
129
+ <xsd:enumeration value="underlined">
130
+ <xsd:annotation>
131
+ <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
132
+ </xsd:annotation>
133
+ </xsd:enumeration>
134
+ <xsd:enumeration value="link">
135
+ <xsd:annotation>
136
+ <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
137
+ </xsd:annotation>
138
+ </xsd:enumeration>
139
+ </xsd:restriction>
140
+ </xsd:simpleType>
141
+ <xsd:simpleType name="InlinePlaceholdersValueList">
142
+ <xsd:annotation>
143
+ <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
144
+ </xsd:annotation>
145
+ <xsd:restriction base="xsd:NMTOKEN">
146
+ <xsd:enumeration value="image">
147
+ <xsd:annotation>
148
+ <xsd:documentation>Indicates a inline image.</xsd:documentation>
149
+ </xsd:annotation>
150
+ </xsd:enumeration>
151
+ <xsd:enumeration value="pb">
152
+ <xsd:annotation>
153
+ <xsd:documentation>Indicates a page break.</xsd:documentation>
154
+ </xsd:annotation>
155
+ </xsd:enumeration>
156
+ <xsd:enumeration value="lb">
157
+ <xsd:annotation>
158
+ <xsd:documentation>Indicates a line break.</xsd:documentation>
159
+ </xsd:annotation>
160
+ </xsd:enumeration>
161
+ </xsd:restriction>
162
+ </xsd:simpleType>
163
+ <xsd:simpleType name="mime-typeValueList">
164
+ <xsd:restriction base="xsd:string">
165
+ <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
166
+ </xsd:restriction>
167
+ </xsd:simpleType>
168
+ <xsd:simpleType name="datatypeValueList">
169
+ <xsd:annotation>
170
+ <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
171
+ </xsd:annotation>
172
+ <xsd:restriction base="xsd:NMTOKEN">
173
+ <xsd:enumeration value="asp">
174
+ <xsd:annotation>
175
+ <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
176
+ </xsd:annotation>
177
+ </xsd:enumeration>
178
+ <xsd:enumeration value="c">
179
+ <xsd:annotation>
180
+ <xsd:documentation>Indicates C source file data.</xsd:documentation>
181
+ </xsd:annotation>
182
+ </xsd:enumeration>
183
+ <xsd:enumeration value="cdf">
184
+ <xsd:annotation>
185
+ <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
186
+ </xsd:annotation>
187
+ </xsd:enumeration>
188
+ <xsd:enumeration value="cfm">
189
+ <xsd:annotation>
190
+ <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
191
+ </xsd:annotation>
192
+ </xsd:enumeration>
193
+ <xsd:enumeration value="cpp">
194
+ <xsd:annotation>
195
+ <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
196
+ </xsd:annotation>
197
+ </xsd:enumeration>
198
+ <xsd:enumeration value="csharp">
199
+ <xsd:annotation>
200
+ <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
201
+ </xsd:annotation>
202
+ </xsd:enumeration>
203
+ <xsd:enumeration value="cstring">
204
+ <xsd:annotation>
205
+ <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
206
+ </xsd:annotation>
207
+ </xsd:enumeration>
208
+ <xsd:enumeration value="csv">
209
+ <xsd:annotation>
210
+ <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
211
+ </xsd:annotation>
212
+ </xsd:enumeration>
213
+ <xsd:enumeration value="database">
214
+ <xsd:annotation>
215
+ <xsd:documentation>Indicates database data.</xsd:documentation>
216
+ </xsd:annotation>
217
+ </xsd:enumeration>
218
+ <xsd:enumeration value="documentfooter">
219
+ <xsd:annotation>
220
+ <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
221
+ </xsd:annotation>
222
+ </xsd:enumeration>
223
+ <xsd:enumeration value="documentheader">
224
+ <xsd:annotation>
225
+ <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
226
+ </xsd:annotation>
227
+ </xsd:enumeration>
228
+ <xsd:enumeration value="filedialog">
229
+ <xsd:annotation>
230
+ <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
231
+ </xsd:annotation>
232
+ </xsd:enumeration>
233
+ <xsd:enumeration value="form">
234
+ <xsd:annotation>
235
+ <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
236
+ </xsd:annotation>
237
+ </xsd:enumeration>
238
+ <xsd:enumeration value="html">
239
+ <xsd:annotation>
240
+ <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
241
+ </xsd:annotation>
242
+ </xsd:enumeration>
243
+ <xsd:enumeration value="htmlbody">
244
+ <xsd:annotation>
245
+ <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
246
+ </xsd:annotation>
247
+ </xsd:enumeration>
248
+ <xsd:enumeration value="ini">
249
+ <xsd:annotation>
250
+ <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
251
+ </xsd:annotation>
252
+ </xsd:enumeration>
253
+ <xsd:enumeration value="interleaf">
254
+ <xsd:annotation>
255
+ <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
256
+ </xsd:annotation>
257
+ </xsd:enumeration>
258
+ <xsd:enumeration value="javaclass">
259
+ <xsd:annotation>
260
+ <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
261
+ </xsd:annotation>
262
+ </xsd:enumeration>
263
+ <xsd:enumeration value="javapropertyresourcebundle">
264
+ <xsd:annotation>
265
+ <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
266
+ </xsd:annotation>
267
+ </xsd:enumeration>
268
+ <xsd:enumeration value="javalistresourcebundle">
269
+ <xsd:annotation>
270
+ <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
271
+ </xsd:annotation>
272
+ </xsd:enumeration>
273
+ <xsd:enumeration value="javascript">
274
+ <xsd:annotation>
275
+ <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
276
+ </xsd:annotation>
277
+ </xsd:enumeration>
278
+ <xsd:enumeration value="jscript">
279
+ <xsd:annotation>
280
+ <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
281
+ </xsd:annotation>
282
+ </xsd:enumeration>
283
+ <xsd:enumeration value="layout">
284
+ <xsd:annotation>
285
+ <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
286
+ </xsd:annotation>
287
+ </xsd:enumeration>
288
+ <xsd:enumeration value="lisp">
289
+ <xsd:annotation>
290
+ <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
291
+ </xsd:annotation>
292
+ </xsd:enumeration>
293
+ <xsd:enumeration value="margin">
294
+ <xsd:annotation>
295
+ <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
296
+ </xsd:annotation>
297
+ </xsd:enumeration>
298
+ <xsd:enumeration value="menufile">
299
+ <xsd:annotation>
300
+ <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
301
+ </xsd:annotation>
302
+ </xsd:enumeration>
303
+ <xsd:enumeration value="messagefile">
304
+ <xsd:annotation>
305
+ <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
306
+ </xsd:annotation>
307
+ </xsd:enumeration>
308
+ <xsd:enumeration value="mif">
309
+ <xsd:annotation>
310
+ <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
311
+ </xsd:annotation>
312
+ </xsd:enumeration>
313
+ <xsd:enumeration value="mimetype">
314
+ <xsd:annotation>
315
+ <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
316
+ </xsd:annotation>
317
+ </xsd:enumeration>
318
+ <xsd:enumeration value="mo">
319
+ <xsd:annotation>
320
+ <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
321
+ </xsd:annotation>
322
+ </xsd:enumeration>
323
+ <xsd:enumeration value="msglib">
324
+ <xsd:annotation>
325
+ <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
326
+ </xsd:annotation>
327
+ </xsd:enumeration>
328
+ <xsd:enumeration value="pagefooter">
329
+ <xsd:annotation>
330
+ <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
331
+ </xsd:annotation>
332
+ </xsd:enumeration>
333
+ <xsd:enumeration value="pageheader">
334
+ <xsd:annotation>
335
+ <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
336
+ </xsd:annotation>
337
+ </xsd:enumeration>
338
+ <xsd:enumeration value="parameters">
339
+ <xsd:annotation>
340
+ <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
341
+ </xsd:annotation>
342
+ </xsd:enumeration>
343
+ <xsd:enumeration value="pascal">
344
+ <xsd:annotation>
345
+ <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
346
+ </xsd:annotation>
347
+ </xsd:enumeration>
348
+ <xsd:enumeration value="php">
349
+ <xsd:annotation>
350
+ <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
351
+ </xsd:annotation>
352
+ </xsd:enumeration>
353
+ <xsd:enumeration value="plaintext">
354
+ <xsd:annotation>
355
+ <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
356
+ </xsd:annotation>
357
+ </xsd:enumeration>
358
+ <xsd:enumeration value="po">
359
+ <xsd:annotation>
360
+ <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
361
+ </xsd:annotation>
362
+ </xsd:enumeration>
363
+ <xsd:enumeration value="report">
364
+ <xsd:annotation>
365
+ <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
366
+ </xsd:annotation>
367
+ </xsd:enumeration>
368
+ <xsd:enumeration value="resources">
369
+ <xsd:annotation>
370
+ <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
371
+ </xsd:annotation>
372
+ </xsd:enumeration>
373
+ <xsd:enumeration value="resx">
374
+ <xsd:annotation>
375
+ <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
376
+ </xsd:annotation>
377
+ </xsd:enumeration>
378
+ <xsd:enumeration value="rtf">
379
+ <xsd:annotation>
380
+ <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
381
+ </xsd:annotation>
382
+ </xsd:enumeration>
383
+ <xsd:enumeration value="sgml">
384
+ <xsd:annotation>
385
+ <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
386
+ </xsd:annotation>
387
+ </xsd:enumeration>
388
+ <xsd:enumeration value="sgmldtd">
389
+ <xsd:annotation>
390
+ <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
391
+ </xsd:annotation>
392
+ </xsd:enumeration>
393
+ <xsd:enumeration value="svg">
394
+ <xsd:annotation>
395
+ <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
396
+ </xsd:annotation>
397
+ </xsd:enumeration>
398
+ <xsd:enumeration value="vbscript">
399
+ <xsd:annotation>
400
+ <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
401
+ </xsd:annotation>
402
+ </xsd:enumeration>
403
+ <xsd:enumeration value="warning">
404
+ <xsd:annotation>
405
+ <xsd:documentation>Indicates warning message.</xsd:documentation>
406
+ </xsd:annotation>
407
+ </xsd:enumeration>
408
+ <xsd:enumeration value="winres">
409
+ <xsd:annotation>
410
+ <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
411
+ </xsd:annotation>
412
+ </xsd:enumeration>
413
+ <xsd:enumeration value="xhtml">
414
+ <xsd:annotation>
415
+ <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
416
+ </xsd:annotation>
417
+ </xsd:enumeration>
418
+ <xsd:enumeration value="xml">
419
+ <xsd:annotation>
420
+ <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
421
+ </xsd:annotation>
422
+ </xsd:enumeration>
423
+ <xsd:enumeration value="xmldtd">
424
+ <xsd:annotation>
425
+ <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
426
+ </xsd:annotation>
427
+ </xsd:enumeration>
428
+ <xsd:enumeration value="xsl">
429
+ <xsd:annotation>
430
+ <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
431
+ </xsd:annotation>
432
+ </xsd:enumeration>
433
+ <xsd:enumeration value="xul">
434
+ <xsd:annotation>
435
+ <xsd:documentation>Indicates XUL elements.</xsd:documentation>
436
+ </xsd:annotation>
437
+ </xsd:enumeration>
438
+ </xsd:restriction>
439
+ </xsd:simpleType>
440
+ <xsd:simpleType name="mtypeValueList">
441
+ <xsd:annotation>
442
+ <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
443
+ </xsd:annotation>
444
+ <xsd:restriction base="xsd:NMTOKEN">
445
+ <xsd:enumeration value="abbrev">
446
+ <xsd:annotation>
447
+ <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
448
+ </xsd:annotation>
449
+ </xsd:enumeration>
450
+ <xsd:enumeration value="abbreviated-form">
451
+ <xsd:annotation>
452
+ <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
453
+ </xsd:annotation>
454
+ </xsd:enumeration>
455
+ <xsd:enumeration value="abbreviation">
456
+ <xsd:annotation>
457
+ <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
458
+ </xsd:annotation>
459
+ </xsd:enumeration>
460
+ <xsd:enumeration value="acronym">
461
+ <xsd:annotation>
462
+ <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
463
+ </xsd:annotation>
464
+ </xsd:enumeration>
465
+ <xsd:enumeration value="appellation">
466
+ <xsd:annotation>
467
+ <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
468
+ </xsd:annotation>
469
+ </xsd:enumeration>
470
+ <xsd:enumeration value="collocation">
471
+ <xsd:annotation>
472
+ <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
473
+ </xsd:annotation>
474
+ </xsd:enumeration>
475
+ <xsd:enumeration value="common-name">
476
+ <xsd:annotation>
477
+ <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
478
+ </xsd:annotation>
479
+ </xsd:enumeration>
480
+ <xsd:enumeration value="datetime">
481
+ <xsd:annotation>
482
+ <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
483
+ </xsd:annotation>
484
+ </xsd:enumeration>
485
+ <xsd:enumeration value="equation">
486
+ <xsd:annotation>
487
+ <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
488
+ </xsd:annotation>
489
+ </xsd:enumeration>
490
+ <xsd:enumeration value="expanded-form">
491
+ <xsd:annotation>
492
+ <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
493
+ </xsd:annotation>
494
+ </xsd:enumeration>
495
+ <xsd:enumeration value="formula">
496
+ <xsd:annotation>
497
+ <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
498
+ </xsd:annotation>
499
+ </xsd:enumeration>
500
+ <xsd:enumeration value="head-term">
501
+ <xsd:annotation>
502
+ <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
503
+ </xsd:annotation>
504
+ </xsd:enumeration>
505
+ <xsd:enumeration value="initialism">
506
+ <xsd:annotation>
507
+ <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
508
+ </xsd:annotation>
509
+ </xsd:enumeration>
510
+ <xsd:enumeration value="international-scientific-term">
511
+ <xsd:annotation>
512
+ <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
513
+ </xsd:annotation>
514
+ </xsd:enumeration>
515
+ <xsd:enumeration value="internationalism">
516
+ <xsd:annotation>
517
+ <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
518
+ </xsd:annotation>
519
+ </xsd:enumeration>
520
+ <xsd:enumeration value="logical-expression">
521
+ <xsd:annotation>
522
+ <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
523
+ </xsd:annotation>
524
+ </xsd:enumeration>
525
+ <xsd:enumeration value="materials-management-unit">
526
+ <xsd:annotation>
527
+ <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
528
+ </xsd:annotation>
529
+ </xsd:enumeration>
530
+ <xsd:enumeration value="name">
531
+ <xsd:annotation>
532
+ <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
533
+ </xsd:annotation>
534
+ </xsd:enumeration>
535
+ <xsd:enumeration value="near-synonym">
536
+ <xsd:annotation>
537
+ <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
538
+ </xsd:annotation>
539
+ </xsd:enumeration>
540
+ <xsd:enumeration value="part-number">
541
+ <xsd:annotation>
542
+ <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
543
+ </xsd:annotation>
544
+ </xsd:enumeration>
545
+ <xsd:enumeration value="phrase">
546
+ <xsd:annotation>
547
+ <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
548
+ </xsd:annotation>
549
+ </xsd:enumeration>
550
+ <xsd:enumeration value="phraseological-unit">
551
+ <xsd:annotation>
552
+ <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
553
+ </xsd:annotation>
554
+ </xsd:enumeration>
555
+ <xsd:enumeration value="protected">
556
+ <xsd:annotation>
557
+ <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
558
+ </xsd:annotation>
559
+ </xsd:enumeration>
560
+ <xsd:enumeration value="romanized-form">
561
+ <xsd:annotation>
562
+ <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
563
+ </xsd:annotation>
564
+ </xsd:enumeration>
565
+ <xsd:enumeration value="seg">
566
+ <xsd:annotation>
567
+ <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
568
+ </xsd:annotation>
569
+ </xsd:enumeration>
570
+ <xsd:enumeration value="set-phrase">
571
+ <xsd:annotation>
572
+ <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
573
+ </xsd:annotation>
574
+ </xsd:enumeration>
575
+ <xsd:enumeration value="short-form">
576
+ <xsd:annotation>
577
+ <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
578
+ </xsd:annotation>
579
+ </xsd:enumeration>
580
+ <xsd:enumeration value="sku">
581
+ <xsd:annotation>
582
+ <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
583
+ </xsd:annotation>
584
+ </xsd:enumeration>
585
+ <xsd:enumeration value="standard-text">
586
+ <xsd:annotation>
587
+ <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
588
+ </xsd:annotation>
589
+ </xsd:enumeration>
590
+ <xsd:enumeration value="symbol">
591
+ <xsd:annotation>
592
+ <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
593
+ </xsd:annotation>
594
+ </xsd:enumeration>
595
+ <xsd:enumeration value="synonym">
596
+ <xsd:annotation>
597
+ <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
598
+ </xsd:annotation>
599
+ </xsd:enumeration>
600
+ <xsd:enumeration value="synonymous-phrase">
601
+ <xsd:annotation>
602
+ <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
603
+ </xsd:annotation>
604
+ </xsd:enumeration>
605
+ <xsd:enumeration value="term">
606
+ <xsd:annotation>
607
+ <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
608
+ </xsd:annotation>
609
+ </xsd:enumeration>
610
+ <xsd:enumeration value="transcribed-form">
611
+ <xsd:annotation>
612
+ <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
613
+ </xsd:annotation>
614
+ </xsd:enumeration>
615
+ <xsd:enumeration value="transliterated-form">
616
+ <xsd:annotation>
617
+ <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
618
+ </xsd:annotation>
619
+ </xsd:enumeration>
620
+ <xsd:enumeration value="truncated-term">
621
+ <xsd:annotation>
622
+ <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
623
+ </xsd:annotation>
624
+ </xsd:enumeration>
625
+ <xsd:enumeration value="variant">
626
+ <xsd:annotation>
627
+ <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
628
+ </xsd:annotation>
629
+ </xsd:enumeration>
630
+ </xsd:restriction>
631
+ </xsd:simpleType>
632
+ <xsd:simpleType name="restypeValueList">
633
+ <xsd:annotation>
634
+ <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
635
+ </xsd:annotation>
636
+ <xsd:restriction base="xsd:NMTOKEN">
637
+ <xsd:enumeration value="auto3state">
638
+ <xsd:annotation>
639
+ <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
640
+ </xsd:annotation>
641
+ </xsd:enumeration>
642
+ <xsd:enumeration value="autocheckbox">
643
+ <xsd:annotation>
644
+ <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
645
+ </xsd:annotation>
646
+ </xsd:enumeration>
647
+ <xsd:enumeration value="autoradiobutton">
648
+ <xsd:annotation>
649
+ <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
650
+ </xsd:annotation>
651
+ </xsd:enumeration>
652
+ <xsd:enumeration value="bedit">
653
+ <xsd:annotation>
654
+ <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
655
+ </xsd:annotation>
656
+ </xsd:enumeration>
657
+ <xsd:enumeration value="bitmap">
658
+ <xsd:annotation>
659
+ <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
660
+ </xsd:annotation>
661
+ </xsd:enumeration>
662
+ <xsd:enumeration value="button">
663
+ <xsd:annotation>
664
+ <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
665
+ </xsd:annotation>
666
+ </xsd:enumeration>
667
+ <xsd:enumeration value="caption">
668
+ <xsd:annotation>
669
+ <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
670
+ </xsd:annotation>
671
+ </xsd:enumeration>
672
+ <xsd:enumeration value="cell">
673
+ <xsd:annotation>
674
+ <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
675
+ </xsd:annotation>
676
+ </xsd:enumeration>
677
+ <xsd:enumeration value="checkbox">
678
+ <xsd:annotation>
679
+ <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
680
+ </xsd:annotation>
681
+ </xsd:enumeration>
682
+ <xsd:enumeration value="checkboxmenuitem">
683
+ <xsd:annotation>
684
+ <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
685
+ </xsd:annotation>
686
+ </xsd:enumeration>
687
+ <xsd:enumeration value="checkedlistbox">
688
+ <xsd:annotation>
689
+ <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
690
+ </xsd:annotation>
691
+ </xsd:enumeration>
692
+ <xsd:enumeration value="colorchooser">
693
+ <xsd:annotation>
694
+ <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
695
+ </xsd:annotation>
696
+ </xsd:enumeration>
697
+ <xsd:enumeration value="combobox">
698
+ <xsd:annotation>
699
+ <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
700
+ </xsd:annotation>
701
+ </xsd:enumeration>
702
+ <xsd:enumeration value="comboboxexitem">
703
+ <xsd:annotation>
704
+ <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
705
+ </xsd:annotation>
706
+ </xsd:enumeration>
707
+ <xsd:enumeration value="comboboxitem">
708
+ <xsd:annotation>
709
+ <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
710
+ </xsd:annotation>
711
+ </xsd:enumeration>
712
+ <xsd:enumeration value="component">
713
+ <xsd:annotation>
714
+ <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
715
+ </xsd:annotation>
716
+ </xsd:enumeration>
717
+ <xsd:enumeration value="contextmenu">
718
+ <xsd:annotation>
719
+ <xsd:documentation>Indicates a context menu.</xsd:documentation>
720
+ </xsd:annotation>
721
+ </xsd:enumeration>
722
+ <xsd:enumeration value="ctext">
723
+ <xsd:annotation>
724
+ <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
725
+ </xsd:annotation>
726
+ </xsd:enumeration>
727
+ <xsd:enumeration value="cursor">
728
+ <xsd:annotation>
729
+ <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
730
+ </xsd:annotation>
731
+ </xsd:enumeration>
732
+ <xsd:enumeration value="datetimepicker">
733
+ <xsd:annotation>
734
+ <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
735
+ </xsd:annotation>
736
+ </xsd:enumeration>
737
+ <xsd:enumeration value="defpushbutton">
738
+ <xsd:annotation>
739
+ <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
740
+ </xsd:annotation>
741
+ </xsd:enumeration>
742
+ <xsd:enumeration value="dialog">
743
+ <xsd:annotation>
744
+ <xsd:documentation>Indicates a dialog box.</xsd:documentation>
745
+ </xsd:annotation>
746
+ </xsd:enumeration>
747
+ <xsd:enumeration value="dlginit">
748
+ <xsd:annotation>
749
+ <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
750
+ </xsd:annotation>
751
+ </xsd:enumeration>
752
+ <xsd:enumeration value="edit">
753
+ <xsd:annotation>
754
+ <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
755
+ </xsd:annotation>
756
+ </xsd:enumeration>
757
+ <xsd:enumeration value="file">
758
+ <xsd:annotation>
759
+ <xsd:documentation>Indicates a filename.</xsd:documentation>
760
+ </xsd:annotation>
761
+ </xsd:enumeration>
762
+ <xsd:enumeration value="filechooser">
763
+ <xsd:annotation>
764
+ <xsd:documentation>Indicates a file dialog.</xsd:documentation>
765
+ </xsd:annotation>
766
+ </xsd:enumeration>
767
+ <xsd:enumeration value="fn">
768
+ <xsd:annotation>
769
+ <xsd:documentation>Indicates a footnote.</xsd:documentation>
770
+ </xsd:annotation>
771
+ </xsd:enumeration>
772
+ <xsd:enumeration value="font">
773
+ <xsd:annotation>
774
+ <xsd:documentation>Indicates a font name.</xsd:documentation>
775
+ </xsd:annotation>
776
+ </xsd:enumeration>
777
+ <xsd:enumeration value="footer">
778
+ <xsd:annotation>
779
+ <xsd:documentation>Indicates a footer.</xsd:documentation>
780
+ </xsd:annotation>
781
+ </xsd:enumeration>
782
+ <xsd:enumeration value="frame">
783
+ <xsd:annotation>
784
+ <xsd:documentation>Indicates a frame object.</xsd:documentation>
785
+ </xsd:annotation>
786
+ </xsd:enumeration>
787
+ <xsd:enumeration value="grid">
788
+ <xsd:annotation>
789
+ <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
790
+ </xsd:annotation>
791
+ </xsd:enumeration>
792
+ <xsd:enumeration value="groupbox">
793
+ <xsd:annotation>
794
+ <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
795
+ </xsd:annotation>
796
+ </xsd:enumeration>
797
+ <xsd:enumeration value="header">
798
+ <xsd:annotation>
799
+ <xsd:documentation>Indicates a header item.</xsd:documentation>
800
+ </xsd:annotation>
801
+ </xsd:enumeration>
802
+ <xsd:enumeration value="heading">
803
+ <xsd:annotation>
804
+ <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
805
+ </xsd:annotation>
806
+ </xsd:enumeration>
807
+ <xsd:enumeration value="hedit">
808
+ <xsd:annotation>
809
+ <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
810
+ </xsd:annotation>
811
+ </xsd:enumeration>
812
+ <xsd:enumeration value="hscrollbar">
813
+ <xsd:annotation>
814
+ <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
815
+ </xsd:annotation>
816
+ </xsd:enumeration>
817
+ <xsd:enumeration value="icon">
818
+ <xsd:annotation>
819
+ <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
820
+ </xsd:annotation>
821
+ </xsd:enumeration>
822
+ <xsd:enumeration value="iedit">
823
+ <xsd:annotation>
824
+ <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
825
+ </xsd:annotation>
826
+ </xsd:enumeration>
827
+ <xsd:enumeration value="keywords">
828
+ <xsd:annotation>
829
+ <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
830
+ </xsd:annotation>
831
+ </xsd:enumeration>
832
+ <xsd:enumeration value="label">
833
+ <xsd:annotation>
834
+ <xsd:documentation>Indicates a label object.</xsd:documentation>
835
+ </xsd:annotation>
836
+ </xsd:enumeration>
837
+ <xsd:enumeration value="linklabel">
838
+ <xsd:annotation>
839
+ <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
840
+ </xsd:annotation>
841
+ </xsd:enumeration>
842
+ <xsd:enumeration value="list">
843
+ <xsd:annotation>
844
+ <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
845
+ </xsd:annotation>
846
+ </xsd:enumeration>
847
+ <xsd:enumeration value="listbox">
848
+ <xsd:annotation>
849
+ <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
850
+ </xsd:annotation>
851
+ </xsd:enumeration>
852
+ <xsd:enumeration value="listitem">
853
+ <xsd:annotation>
854
+ <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
855
+ </xsd:annotation>
856
+ </xsd:enumeration>
857
+ <xsd:enumeration value="ltext">
858
+ <xsd:annotation>
859
+ <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
860
+ </xsd:annotation>
861
+ </xsd:enumeration>
862
+ <xsd:enumeration value="menu">
863
+ <xsd:annotation>
864
+ <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
865
+ </xsd:annotation>
866
+ </xsd:enumeration>
867
+ <xsd:enumeration value="menubar">
868
+ <xsd:annotation>
869
+ <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
870
+ </xsd:annotation>
871
+ </xsd:enumeration>
872
+ <xsd:enumeration value="menuitem">
873
+ <xsd:annotation>
874
+ <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
875
+ </xsd:annotation>
876
+ </xsd:enumeration>
877
+ <xsd:enumeration value="menuseparator">
878
+ <xsd:annotation>
879
+ <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
880
+ </xsd:annotation>
881
+ </xsd:enumeration>
882
+ <xsd:enumeration value="message">
883
+ <xsd:annotation>
884
+ <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
885
+ </xsd:annotation>
886
+ </xsd:enumeration>
887
+ <xsd:enumeration value="monthcalendar">
888
+ <xsd:annotation>
889
+ <xsd:documentation>Indicates a calendar control.</xsd:documentation>
890
+ </xsd:annotation>
891
+ </xsd:enumeration>
892
+ <xsd:enumeration value="numericupdown">
893
+ <xsd:annotation>
894
+ <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
895
+ </xsd:annotation>
896
+ </xsd:enumeration>
897
+ <xsd:enumeration value="panel">
898
+ <xsd:annotation>
899
+ <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
900
+ </xsd:annotation>
901
+ </xsd:enumeration>
902
+ <xsd:enumeration value="popupmenu">
903
+ <xsd:annotation>
904
+ <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
905
+ </xsd:annotation>
906
+ </xsd:enumeration>
907
+ <xsd:enumeration value="pushbox">
908
+ <xsd:annotation>
909
+ <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
910
+ </xsd:annotation>
911
+ </xsd:enumeration>
912
+ <xsd:enumeration value="pushbutton">
913
+ <xsd:annotation>
914
+ <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
915
+ </xsd:annotation>
916
+ </xsd:enumeration>
917
+ <xsd:enumeration value="radio">
918
+ <xsd:annotation>
919
+ <xsd:documentation>Indicates a radio button object.</xsd:documentation>
920
+ </xsd:annotation>
921
+ </xsd:enumeration>
922
+ <xsd:enumeration value="radiobuttonmenuitem">
923
+ <xsd:annotation>
924
+ <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
925
+ </xsd:annotation>
926
+ </xsd:enumeration>
927
+ <xsd:enumeration value="rcdata">
928
+ <xsd:annotation>
929
+ <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
930
+ </xsd:annotation>
931
+ </xsd:enumeration>
932
+ <xsd:enumeration value="row">
933
+ <xsd:annotation>
934
+ <xsd:documentation>Indicates a row in a table.</xsd:documentation>
935
+ </xsd:annotation>
936
+ </xsd:enumeration>
937
+ <xsd:enumeration value="rtext">
938
+ <xsd:annotation>
939
+ <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
940
+ </xsd:annotation>
941
+ </xsd:enumeration>
942
+ <xsd:enumeration value="scrollpane">
943
+ <xsd:annotation>
944
+ <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
945
+ </xsd:annotation>
946
+ </xsd:enumeration>
947
+ <xsd:enumeration value="separator">
948
+ <xsd:annotation>
949
+ <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
950
+ </xsd:annotation>
951
+ </xsd:enumeration>
952
+ <xsd:enumeration value="shortcut">
953
+ <xsd:annotation>
954
+ <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
955
+ </xsd:annotation>
956
+ </xsd:enumeration>
957
+ <xsd:enumeration value="spinner">
958
+ <xsd:annotation>
959
+ <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
960
+ </xsd:annotation>
961
+ </xsd:enumeration>
962
+ <xsd:enumeration value="splitter">
963
+ <xsd:annotation>
964
+ <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
965
+ </xsd:annotation>
966
+ </xsd:enumeration>
967
+ <xsd:enumeration value="state3">
968
+ <xsd:annotation>
969
+ <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
970
+ </xsd:annotation>
971
+ </xsd:enumeration>
972
+ <xsd:enumeration value="statusbar">
973
+ <xsd:annotation>
974
+ <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
975
+ </xsd:annotation>
976
+ </xsd:enumeration>
977
+ <xsd:enumeration value="string">
978
+ <xsd:annotation>
979
+ <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
980
+ </xsd:annotation>
981
+ </xsd:enumeration>
982
+ <xsd:enumeration value="tabcontrol">
983
+ <xsd:annotation>
984
+ <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
985
+ </xsd:annotation>
986
+ </xsd:enumeration>
987
+ <xsd:enumeration value="table">
988
+ <xsd:annotation>
989
+ <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
990
+ </xsd:annotation>
991
+ </xsd:enumeration>
992
+ <xsd:enumeration value="textbox">
993
+ <xsd:annotation>
994
+ <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
995
+ </xsd:annotation>
996
+ </xsd:enumeration>
997
+ <xsd:enumeration value="togglebutton">
998
+ <xsd:annotation>
999
+ <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
1000
+ </xsd:annotation>
1001
+ </xsd:enumeration>
1002
+ <xsd:enumeration value="toolbar">
1003
+ <xsd:annotation>
1004
+ <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
1005
+ </xsd:annotation>
1006
+ </xsd:enumeration>
1007
+ <xsd:enumeration value="tooltip">
1008
+ <xsd:annotation>
1009
+ <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
1010
+ </xsd:annotation>
1011
+ </xsd:enumeration>
1012
+ <xsd:enumeration value="trackbar">
1013
+ <xsd:annotation>
1014
+ <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
1015
+ </xsd:annotation>
1016
+ </xsd:enumeration>
1017
+ <xsd:enumeration value="tree">
1018
+ <xsd:annotation>
1019
+ <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
1020
+ </xsd:annotation>
1021
+ </xsd:enumeration>
1022
+ <xsd:enumeration value="uri">
1023
+ <xsd:annotation>
1024
+ <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
1025
+ </xsd:annotation>
1026
+ </xsd:enumeration>
1027
+ <xsd:enumeration value="userbutton">
1028
+ <xsd:annotation>
1029
+ <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
1030
+ </xsd:annotation>
1031
+ </xsd:enumeration>
1032
+ <xsd:enumeration value="usercontrol">
1033
+ <xsd:annotation>
1034
+ <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
1035
+ </xsd:annotation>
1036
+ </xsd:enumeration>
1037
+ <xsd:enumeration value="var">
1038
+ <xsd:annotation>
1039
+ <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
1040
+ </xsd:annotation>
1041
+ </xsd:enumeration>
1042
+ <xsd:enumeration value="versioninfo">
1043
+ <xsd:annotation>
1044
+ <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
1045
+ </xsd:annotation>
1046
+ </xsd:enumeration>
1047
+ <xsd:enumeration value="vscrollbar">
1048
+ <xsd:annotation>
1049
+ <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
1050
+ </xsd:annotation>
1051
+ </xsd:enumeration>
1052
+ <xsd:enumeration value="window">
1053
+ <xsd:annotation>
1054
+ <xsd:documentation>Indicates a graphical window.</xsd:documentation>
1055
+ </xsd:annotation>
1056
+ </xsd:enumeration>
1057
+ </xsd:restriction>
1058
+ </xsd:simpleType>
1059
+ <xsd:simpleType name="size-unitValueList">
1060
+ <xsd:annotation>
1061
+ <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
1062
+ </xsd:annotation>
1063
+ <xsd:restriction base="xsd:NMTOKEN">
1064
+ <xsd:enumeration value="byte">
1065
+ <xsd:annotation>
1066
+ <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
1067
+ </xsd:annotation>
1068
+ </xsd:enumeration>
1069
+ <xsd:enumeration value="char">
1070
+ <xsd:annotation>
1071
+ <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
1072
+ </xsd:annotation>
1073
+ </xsd:enumeration>
1074
+ <xsd:enumeration value="col">
1075
+ <xsd:annotation>
1076
+ <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
1077
+ </xsd:annotation>
1078
+ </xsd:enumeration>
1079
+ <xsd:enumeration value="cm">
1080
+ <xsd:annotation>
1081
+ <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
1082
+ </xsd:annotation>
1083
+ </xsd:enumeration>
1084
+ <xsd:enumeration value="dlgunit">
1085
+ <xsd:annotation>
1086
+ <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
1087
+ </xsd:annotation>
1088
+ </xsd:enumeration>
1089
+ <xsd:enumeration value="em">
1090
+ <xsd:annotation>
1091
+ <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
1092
+ </xsd:annotation>
1093
+ </xsd:enumeration>
1094
+ <xsd:enumeration value="ex">
1095
+ <xsd:annotation>
1096
+ <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
1097
+ </xsd:annotation>
1098
+ </xsd:enumeration>
1099
+ <xsd:enumeration value="glyph">
1100
+ <xsd:annotation>
1101
+ <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
1102
+ </xsd:annotation>
1103
+ </xsd:enumeration>
1104
+ <xsd:enumeration value="in">
1105
+ <xsd:annotation>
1106
+ <xsd:documentation>Indicates a size in inches.</xsd:documentation>
1107
+ </xsd:annotation>
1108
+ </xsd:enumeration>
1109
+ <xsd:enumeration value="mm">
1110
+ <xsd:annotation>
1111
+ <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
1112
+ </xsd:annotation>
1113
+ </xsd:enumeration>
1114
+ <xsd:enumeration value="percent">
1115
+ <xsd:annotation>
1116
+ <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
1117
+ </xsd:annotation>
1118
+ </xsd:enumeration>
1119
+ <xsd:enumeration value="pixel">
1120
+ <xsd:annotation>
1121
+ <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
1122
+ </xsd:annotation>
1123
+ </xsd:enumeration>
1124
+ <xsd:enumeration value="point">
1125
+ <xsd:annotation>
1126
+ <xsd:documentation>Indicates a size in point.</xsd:documentation>
1127
+ </xsd:annotation>
1128
+ </xsd:enumeration>
1129
+ <xsd:enumeration value="row">
1130
+ <xsd:annotation>
1131
+ <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
1132
+ </xsd:annotation>
1133
+ </xsd:enumeration>
1134
+ </xsd:restriction>
1135
+ </xsd:simpleType>
1136
+ <xsd:simpleType name="stateValueList">
1137
+ <xsd:annotation>
1138
+ <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
1139
+ </xsd:annotation>
1140
+ <xsd:restriction base="xsd:NMTOKEN">
1141
+ <xsd:enumeration value="final">
1142
+ <xsd:annotation>
1143
+ <xsd:documentation>Indicates the terminating state.</xsd:documentation>
1144
+ </xsd:annotation>
1145
+ </xsd:enumeration>
1146
+ <xsd:enumeration value="needs-adaptation">
1147
+ <xsd:annotation>
1148
+ <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
1149
+ </xsd:annotation>
1150
+ </xsd:enumeration>
1151
+ <xsd:enumeration value="needs-l10n">
1152
+ <xsd:annotation>
1153
+ <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
1154
+ </xsd:annotation>
1155
+ </xsd:enumeration>
1156
+ <xsd:enumeration value="needs-review-adaptation">
1157
+ <xsd:annotation>
1158
+ <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
1159
+ </xsd:annotation>
1160
+ </xsd:enumeration>
1161
+ <xsd:enumeration value="needs-review-l10n">
1162
+ <xsd:annotation>
1163
+ <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
1164
+ </xsd:annotation>
1165
+ </xsd:enumeration>
1166
+ <xsd:enumeration value="needs-review-translation">
1167
+ <xsd:annotation>
1168
+ <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
1169
+ </xsd:annotation>
1170
+ </xsd:enumeration>
1171
+ <xsd:enumeration value="needs-translation">
1172
+ <xsd:annotation>
1173
+ <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
1174
+ </xsd:annotation>
1175
+ </xsd:enumeration>
1176
+ <xsd:enumeration value="new">
1177
+ <xsd:annotation>
1178
+ <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
1179
+ </xsd:annotation>
1180
+ </xsd:enumeration>
1181
+ <xsd:enumeration value="signed-off">
1182
+ <xsd:annotation>
1183
+ <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
1184
+ </xsd:annotation>
1185
+ </xsd:enumeration>
1186
+ <xsd:enumeration value="translated">
1187
+ <xsd:annotation>
1188
+ <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
1189
+ </xsd:annotation>
1190
+ </xsd:enumeration>
1191
+ </xsd:restriction>
1192
+ </xsd:simpleType>
1193
+ <xsd:simpleType name="state-qualifierValueList">
1194
+ <xsd:annotation>
1195
+ <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
1196
+ </xsd:annotation>
1197
+ <xsd:restriction base="xsd:NMTOKEN">
1198
+ <xsd:enumeration value="exact-match">
1199
+ <xsd:annotation>
1200
+ <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
1201
+ </xsd:annotation>
1202
+ </xsd:enumeration>
1203
+ <xsd:enumeration value="fuzzy-match">
1204
+ <xsd:annotation>
1205
+ <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
1206
+ </xsd:annotation>
1207
+ </xsd:enumeration>
1208
+ <xsd:enumeration value="id-match">
1209
+ <xsd:annotation>
1210
+ <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
1211
+ </xsd:annotation>
1212
+ </xsd:enumeration>
1213
+ <xsd:enumeration value="leveraged-glossary">
1214
+ <xsd:annotation>
1215
+ <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
1216
+ </xsd:annotation>
1217
+ </xsd:enumeration>
1218
+ <xsd:enumeration value="leveraged-inherited">
1219
+ <xsd:annotation>
1220
+ <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
1221
+ </xsd:annotation>
1222
+ </xsd:enumeration>
1223
+ <xsd:enumeration value="leveraged-mt">
1224
+ <xsd:annotation>
1225
+ <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
1226
+ </xsd:annotation>
1227
+ </xsd:enumeration>
1228
+ <xsd:enumeration value="leveraged-repository">
1229
+ <xsd:annotation>
1230
+ <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
1231
+ </xsd:annotation>
1232
+ </xsd:enumeration>
1233
+ <xsd:enumeration value="leveraged-tm">
1234
+ <xsd:annotation>
1235
+ <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
1236
+ </xsd:annotation>
1237
+ </xsd:enumeration>
1238
+ <xsd:enumeration value="mt-suggestion">
1239
+ <xsd:annotation>
1240
+ <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
1241
+ </xsd:annotation>
1242
+ </xsd:enumeration>
1243
+ <xsd:enumeration value="rejected-grammar">
1244
+ <xsd:annotation>
1245
+ <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
1246
+ </xsd:annotation>
1247
+ </xsd:enumeration>
1248
+ <xsd:enumeration value="rejected-inaccurate">
1249
+ <xsd:annotation>
1250
+ <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
1251
+ </xsd:annotation>
1252
+ </xsd:enumeration>
1253
+ <xsd:enumeration value="rejected-length">
1254
+ <xsd:annotation>
1255
+ <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
1256
+ </xsd:annotation>
1257
+ </xsd:enumeration>
1258
+ <xsd:enumeration value="rejected-spelling">
1259
+ <xsd:annotation>
1260
+ <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
1261
+ </xsd:annotation>
1262
+ </xsd:enumeration>
1263
+ <xsd:enumeration value="tm-suggestion">
1264
+ <xsd:annotation>
1265
+ <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
1266
+ </xsd:annotation>
1267
+ </xsd:enumeration>
1268
+ </xsd:restriction>
1269
+ </xsd:simpleType>
1270
+ <xsd:simpleType name="unitValueList">
1271
+ <xsd:annotation>
1272
+ <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
1273
+ </xsd:annotation>
1274
+ <xsd:restriction base="xsd:NMTOKEN">
1275
+ <xsd:enumeration value="word">
1276
+ <xsd:annotation>
1277
+ <xsd:documentation>Refers to words.</xsd:documentation>
1278
+ </xsd:annotation>
1279
+ </xsd:enumeration>
1280
+ <xsd:enumeration value="page">
1281
+ <xsd:annotation>
1282
+ <xsd:documentation>Refers to pages.</xsd:documentation>
1283
+ </xsd:annotation>
1284
+ </xsd:enumeration>
1285
+ <xsd:enumeration value="trans-unit">
1286
+ <xsd:annotation>
1287
+ <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
1288
+ </xsd:annotation>
1289
+ </xsd:enumeration>
1290
+ <xsd:enumeration value="bin-unit">
1291
+ <xsd:annotation>
1292
+ <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
1293
+ </xsd:annotation>
1294
+ </xsd:enumeration>
1295
+ <xsd:enumeration value="glyph">
1296
+ <xsd:annotation>
1297
+ <xsd:documentation>Refers to glyphs.</xsd:documentation>
1298
+ </xsd:annotation>
1299
+ </xsd:enumeration>
1300
+ <xsd:enumeration value="item">
1301
+ <xsd:annotation>
1302
+ <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
1303
+ </xsd:annotation>
1304
+ </xsd:enumeration>
1305
+ <xsd:enumeration value="instance">
1306
+ <xsd:annotation>
1307
+ <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
1308
+ </xsd:annotation>
1309
+ </xsd:enumeration>
1310
+ <xsd:enumeration value="character">
1311
+ <xsd:annotation>
1312
+ <xsd:documentation>Refers to characters.</xsd:documentation>
1313
+ </xsd:annotation>
1314
+ </xsd:enumeration>
1315
+ <xsd:enumeration value="line">
1316
+ <xsd:annotation>
1317
+ <xsd:documentation>Refers to lines.</xsd:documentation>
1318
+ </xsd:annotation>
1319
+ </xsd:enumeration>
1320
+ <xsd:enumeration value="sentence">
1321
+ <xsd:annotation>
1322
+ <xsd:documentation>Refers to sentences.</xsd:documentation>
1323
+ </xsd:annotation>
1324
+ </xsd:enumeration>
1325
+ <xsd:enumeration value="paragraph">
1326
+ <xsd:annotation>
1327
+ <xsd:documentation>Refers to paragraphs.</xsd:documentation>
1328
+ </xsd:annotation>
1329
+ </xsd:enumeration>
1330
+ <xsd:enumeration value="segment">
1331
+ <xsd:annotation>
1332
+ <xsd:documentation>Refers to segments.</xsd:documentation>
1333
+ </xsd:annotation>
1334
+ </xsd:enumeration>
1335
+ <xsd:enumeration value="placeable">
1336
+ <xsd:annotation>
1337
+ <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
1338
+ </xsd:annotation>
1339
+ </xsd:enumeration>
1340
+ </xsd:restriction>
1341
+ </xsd:simpleType>
1342
+ <xsd:simpleType name="priorityValueList">
1343
+ <xsd:annotation>
1344
+ <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
1345
+ </xsd:annotation>
1346
+ <xsd:restriction base="xsd:positiveInteger">
1347
+ <xsd:enumeration value="1">
1348
+ <xsd:annotation>
1349
+ <xsd:documentation>Highest priority.</xsd:documentation>
1350
+ </xsd:annotation>
1351
+ </xsd:enumeration>
1352
+ <xsd:enumeration value="2">
1353
+ <xsd:annotation>
1354
+ <xsd:documentation>High priority.</xsd:documentation>
1355
+ </xsd:annotation>
1356
+ </xsd:enumeration>
1357
+ <xsd:enumeration value="3">
1358
+ <xsd:annotation>
1359
+ <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
1360
+ </xsd:annotation>
1361
+ </xsd:enumeration>
1362
+ <xsd:enumeration value="4">
1363
+ <xsd:annotation>
1364
+ <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
1365
+ </xsd:annotation>
1366
+ </xsd:enumeration>
1367
+ <xsd:enumeration value="5">
1368
+ <xsd:annotation>
1369
+ <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
1370
+ </xsd:annotation>
1371
+ </xsd:enumeration>
1372
+ <xsd:enumeration value="6">
1373
+ <xsd:annotation>
1374
+ <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
1375
+ </xsd:annotation>
1376
+ </xsd:enumeration>
1377
+ <xsd:enumeration value="7">
1378
+ <xsd:annotation>
1379
+ <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
1380
+ </xsd:annotation>
1381
+ </xsd:enumeration>
1382
+ <xsd:enumeration value="8">
1383
+ <xsd:annotation>
1384
+ <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
1385
+ </xsd:annotation>
1386
+ </xsd:enumeration>
1387
+ <xsd:enumeration value="9">
1388
+ <xsd:annotation>
1389
+ <xsd:documentation>Low priority.</xsd:documentation>
1390
+ </xsd:annotation>
1391
+ </xsd:enumeration>
1392
+ <xsd:enumeration value="10">
1393
+ <xsd:annotation>
1394
+ <xsd:documentation>Lowest priority.</xsd:documentation>
1395
+ </xsd:annotation>
1396
+ </xsd:enumeration>
1397
+ </xsd:restriction>
1398
+ </xsd:simpleType>
1399
+ <xsd:simpleType name="reformatValueYesNo">
1400
+ <xsd:restriction base="xsd:string">
1401
+ <xsd:enumeration value="yes">
1402
+ <xsd:annotation>
1403
+ <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
1404
+ </xsd:annotation>
1405
+ </xsd:enumeration>
1406
+ <xsd:enumeration value="no">
1407
+ <xsd:annotation>
1408
+ <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
1409
+ </xsd:annotation>
1410
+ </xsd:enumeration>
1411
+ </xsd:restriction>
1412
+ </xsd:simpleType>
1413
+ <xsd:simpleType name="reformatValueList">
1414
+ <xsd:list>
1415
+ <xsd:simpleType>
1416
+ <xsd:union memberTypes="xlf:XTend">
1417
+ <xsd:simpleType>
1418
+ <xsd:restriction base="xsd:string">
1419
+ <xsd:enumeration value="coord">
1420
+ <xsd:annotation>
1421
+ <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
1422
+ </xsd:annotation>
1423
+ </xsd:enumeration>
1424
+ <xsd:enumeration value="coord-x">
1425
+ <xsd:annotation>
1426
+ <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
1427
+ </xsd:annotation>
1428
+ </xsd:enumeration>
1429
+ <xsd:enumeration value="coord-y">
1430
+ <xsd:annotation>
1431
+ <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
1432
+ </xsd:annotation>
1433
+ </xsd:enumeration>
1434
+ <xsd:enumeration value="coord-cx">
1435
+ <xsd:annotation>
1436
+ <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
1437
+ </xsd:annotation>
1438
+ </xsd:enumeration>
1439
+ <xsd:enumeration value="coord-cy">
1440
+ <xsd:annotation>
1441
+ <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
1442
+ </xsd:annotation>
1443
+ </xsd:enumeration>
1444
+ <xsd:enumeration value="font">
1445
+ <xsd:annotation>
1446
+ <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
1447
+ </xsd:annotation>
1448
+ </xsd:enumeration>
1449
+ <xsd:enumeration value="font-name">
1450
+ <xsd:annotation>
1451
+ <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
1452
+ </xsd:annotation>
1453
+ </xsd:enumeration>
1454
+ <xsd:enumeration value="font-size">
1455
+ <xsd:annotation>
1456
+ <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
1457
+ </xsd:annotation>
1458
+ </xsd:enumeration>
1459
+ <xsd:enumeration value="font-weight">
1460
+ <xsd:annotation>
1461
+ <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
1462
+ </xsd:annotation>
1463
+ </xsd:enumeration>
1464
+ <xsd:enumeration value="css-style">
1465
+ <xsd:annotation>
1466
+ <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
1467
+ </xsd:annotation>
1468
+ </xsd:enumeration>
1469
+ <xsd:enumeration value="style">
1470
+ <xsd:annotation>
1471
+ <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
1472
+ </xsd:annotation>
1473
+ </xsd:enumeration>
1474
+ <xsd:enumeration value="ex-style">
1475
+ <xsd:annotation>
1476
+ <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
1477
+ </xsd:annotation>
1478
+ </xsd:enumeration>
1479
+ </xsd:restriction>
1480
+ </xsd:simpleType>
1481
+ </xsd:union>
1482
+ </xsd:simpleType>
1483
+ </xsd:list>
1484
+ </xsd:simpleType>
1485
+ <xsd:simpleType name="purposeValueList">
1486
+ <xsd:restriction base="xsd:string">
1487
+ <xsd:enumeration value="information">
1488
+ <xsd:annotation>
1489
+ <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
1490
+ </xsd:annotation>
1491
+ </xsd:enumeration>
1492
+ <xsd:enumeration value="location">
1493
+ <xsd:annotation>
1494
+ <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
1495
+ </xsd:annotation>
1496
+ </xsd:enumeration>
1497
+ <xsd:enumeration value="match">
1498
+ <xsd:annotation>
1499
+ <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
1500
+ </xsd:annotation>
1501
+ </xsd:enumeration>
1502
+ </xsd:restriction>
1503
+ </xsd:simpleType>
1504
+ <xsd:simpleType name="alttranstypeValueList">
1505
+ <xsd:restriction base="xsd:string">
1506
+ <xsd:enumeration value="proposal">
1507
+ <xsd:annotation>
1508
+ <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
1509
+ </xsd:annotation>
1510
+ </xsd:enumeration>
1511
+ <xsd:enumeration value="previous-version">
1512
+ <xsd:annotation>
1513
+ <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
1514
+ </xsd:annotation>
1515
+ </xsd:enumeration>
1516
+ <xsd:enumeration value="rejected">
1517
+ <xsd:annotation>
1518
+ <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
1519
+ </xsd:annotation>
1520
+ </xsd:enumeration>
1521
+ <xsd:enumeration value="reference">
1522
+ <xsd:annotation>
1523
+ <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
1524
+ </xsd:annotation>
1525
+ </xsd:enumeration>
1526
+ <xsd:enumeration value="accepted">
1527
+ <xsd:annotation>
1528
+ <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
1529
+ </xsd:annotation>
1530
+ </xsd:enumeration>
1531
+ </xsd:restriction>
1532
+ </xsd:simpleType>
1533
+ <!-- Other Types -->
1534
+ <xsd:complexType name="ElemType_ExternalReference">
1535
+ <xsd:choice>
1536
+ <xsd:element ref="xlf:internal-file"/>
1537
+ <xsd:element ref="xlf:external-file"/>
1538
+ </xsd:choice>
1539
+ </xsd:complexType>
1540
+ <xsd:simpleType name="AttrType_purpose">
1541
+ <xsd:list>
1542
+ <xsd:simpleType>
1543
+ <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
1544
+ </xsd:simpleType>
1545
+ </xsd:list>
1546
+ </xsd:simpleType>
1547
+ <xsd:simpleType name="AttrType_datatype">
1548
+ <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
1549
+ </xsd:simpleType>
1550
+ <xsd:simpleType name="AttrType_restype">
1551
+ <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
1552
+ </xsd:simpleType>
1553
+ <xsd:simpleType name="AttrType_alttranstype">
1554
+ <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
1555
+ </xsd:simpleType>
1556
+ <xsd:simpleType name="AttrType_context-type">
1557
+ <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
1558
+ </xsd:simpleType>
1559
+ <xsd:simpleType name="AttrType_state">
1560
+ <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
1561
+ </xsd:simpleType>
1562
+ <xsd:simpleType name="AttrType_state-qualifier">
1563
+ <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
1564
+ </xsd:simpleType>
1565
+ <xsd:simpleType name="AttrType_count-type">
1566
+ <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
1567
+ </xsd:simpleType>
1568
+ <xsd:simpleType name="AttrType_InlineDelimiters">
1569
+ <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
1570
+ </xsd:simpleType>
1571
+ <xsd:simpleType name="AttrType_InlinePlaceholders">
1572
+ <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
1573
+ </xsd:simpleType>
1574
+ <xsd:simpleType name="AttrType_size-unit">
1575
+ <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
1576
+ </xsd:simpleType>
1577
+ <xsd:simpleType name="AttrType_mtype">
1578
+ <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
1579
+ </xsd:simpleType>
1580
+ <xsd:simpleType name="AttrType_unit">
1581
+ <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
1582
+ </xsd:simpleType>
1583
+ <xsd:simpleType name="AttrType_priority">
1584
+ <xsd:union memberTypes="xlf:priorityValueList"/>
1585
+ </xsd:simpleType>
1586
+ <xsd:simpleType name="AttrType_reformat">
1587
+ <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
1588
+ </xsd:simpleType>
1589
+ <xsd:simpleType name="AttrType_YesNo">
1590
+ <xsd:restriction base="xsd:NMTOKEN">
1591
+ <xsd:enumeration value="yes"/>
1592
+ <xsd:enumeration value="no"/>
1593
+ </xsd:restriction>
1594
+ </xsd:simpleType>
1595
+ <xsd:simpleType name="AttrType_Position">
1596
+ <xsd:restriction base="xsd:NMTOKEN">
1597
+ <xsd:enumeration value="open"/>
1598
+ <xsd:enumeration value="close"/>
1599
+ </xsd:restriction>
1600
+ </xsd:simpleType>
1601
+ <xsd:simpleType name="AttrType_assoc">
1602
+ <xsd:restriction base="xsd:NMTOKEN">
1603
+ <xsd:enumeration value="preceding"/>
1604
+ <xsd:enumeration value="following"/>
1605
+ <xsd:enumeration value="both"/>
1606
+ </xsd:restriction>
1607
+ </xsd:simpleType>
1608
+ <xsd:simpleType name="AttrType_annotates">
1609
+ <xsd:restriction base="xsd:NMTOKEN">
1610
+ <xsd:enumeration value="source"/>
1611
+ <xsd:enumeration value="target"/>
1612
+ <xsd:enumeration value="general"/>
1613
+ </xsd:restriction>
1614
+ </xsd:simpleType>
1615
+ <xsd:simpleType name="AttrType_Coordinates">
1616
+ <xsd:annotation>
1617
+ <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
1618
+ </xsd:annotation>
1619
+ <xsd:restriction base="xsd:string">
1620
+ <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
1621
+ </xsd:restriction>
1622
+ </xsd:simpleType>
1623
+ <xsd:simpleType name="AttrType_Version">
1624
+ <xsd:annotation>
1625
+ <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
1626
+ </xsd:annotation>
1627
+ <xsd:restriction base="xsd:string">
1628
+ <xsd:enumeration value="1.2"/>
1629
+ <xsd:enumeration value="1.1"/>
1630
+ <xsd:enumeration value="1.0"/>
1631
+ </xsd:restriction>
1632
+ </xsd:simpleType>
1633
+ <!-- Groups -->
1634
+ <xsd:group name="ElemGroup_TextContent">
1635
+ <xsd:choice>
1636
+ <xsd:element ref="xlf:g"/>
1637
+ <xsd:element ref="xlf:bpt"/>
1638
+ <xsd:element ref="xlf:ept"/>
1639
+ <xsd:element ref="xlf:ph"/>
1640
+ <xsd:element ref="xlf:it"/>
1641
+ <xsd:element ref="xlf:mrk"/>
1642
+ <xsd:element ref="xlf:x"/>
1643
+ <xsd:element ref="xlf:bx"/>
1644
+ <xsd:element ref="xlf:ex"/>
1645
+ </xsd:choice>
1646
+ </xsd:group>
1647
+ <xsd:attributeGroup name="AttrGroup_TextContent">
1648
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
1649
+ <xsd:attribute name="xid" type="xsd:string" use="optional"/>
1650
+ <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
1651
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1652
+ </xsd:attributeGroup>
1653
+ <!-- XLIFF Structure -->
1654
+ <xsd:element name="xliff">
1655
+ <xsd:complexType>
1656
+ <xsd:sequence maxOccurs="unbounded">
1657
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1658
+ <xsd:element ref="xlf:file"/>
1659
+ </xsd:sequence>
1660
+ <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
1661
+ <xsd:attribute ref="xml:lang" use="optional"/>
1662
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1663
+ </xsd:complexType>
1664
+ </xsd:element>
1665
+ <xsd:element name="file">
1666
+ <xsd:complexType>
1667
+ <xsd:sequence>
1668
+ <xsd:element minOccurs="0" ref="xlf:header"/>
1669
+ <xsd:element ref="xlf:body"/>
1670
+ </xsd:sequence>
1671
+ <xsd:attribute name="original" type="xsd:string" use="required"/>
1672
+ <xsd:attribute name="source-language" type="xsd:language" use="required"/>
1673
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
1674
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
1675
+ <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
1676
+ <xsd:attribute ref="xml:space" use="optional"/>
1677
+ <xsd:attribute name="category" type="xsd:string" use="optional"/>
1678
+ <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
1679
+ <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
1680
+ <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
1681
+ <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
1682
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1683
+ </xsd:complexType>
1684
+ <xsd:unique name="U_group_id">
1685
+ <xsd:selector xpath=".//xlf:group"/>
1686
+ <xsd:field xpath="@id"/>
1687
+ </xsd:unique>
1688
+ <xsd:key name="K_unit_id">
1689
+ <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
1690
+ <xsd:field xpath="@id"/>
1691
+ </xsd:key>
1692
+ <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
1693
+ <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
1694
+ <xsd:field xpath="@xid"/>
1695
+ </xsd:keyref>
1696
+ <xsd:key name="K_tool-id">
1697
+ <xsd:selector xpath="xlf:header/xlf:tool"/>
1698
+ <xsd:field xpath="@tool-id"/>
1699
+ </xsd:key>
1700
+ <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
1701
+ <xsd:selector xpath="."/>
1702
+ <xsd:field xpath="@tool-id"/>
1703
+ </xsd:keyref>
1704
+ <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
1705
+ <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
1706
+ <xsd:field xpath="@tool-id"/>
1707
+ </xsd:keyref>
1708
+ <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
1709
+ <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
1710
+ <xsd:field xpath="@tool-id"/>
1711
+ </xsd:keyref>
1712
+ <xsd:key name="K_count-group_name">
1713
+ <xsd:selector xpath=".//xlf:count-group"/>
1714
+ <xsd:field xpath="@name"/>
1715
+ </xsd:key>
1716
+ <xsd:unique name="U_context-group_name">
1717
+ <xsd:selector xpath=".//xlf:context-group"/>
1718
+ <xsd:field xpath="@name"/>
1719
+ </xsd:unique>
1720
+ <xsd:key name="K_phase-name">
1721
+ <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
1722
+ <xsd:field xpath="@phase-name"/>
1723
+ </xsd:key>
1724
+ <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
1725
+ <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
1726
+ <xsd:field xpath="@phase-name"/>
1727
+ </xsd:keyref>
1728
+ <xsd:unique name="U_uid">
1729
+ <xsd:selector xpath=".//xlf:external-file"/>
1730
+ <xsd:field xpath="@uid"/>
1731
+ </xsd:unique>
1732
+ </xsd:element>
1733
+ <xsd:element name="header">
1734
+ <xsd:complexType>
1735
+ <xsd:sequence>
1736
+ <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
1737
+ <xsd:element minOccurs="0" ref="xlf:phase-group"/>
1738
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
1739
+ <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
1740
+ <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
1741
+ <xsd:element ref="xlf:count-group"/>
1742
+ <xsd:element ref="xlf:note"/>
1743
+ <xsd:element ref="xlf:tool"/>
1744
+ </xsd:choice>
1745
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1746
+ </xsd:sequence>
1747
+ </xsd:complexType>
1748
+ </xsd:element>
1749
+ <xsd:element name="internal-file">
1750
+ <xsd:complexType>
1751
+ <xsd:simpleContent>
1752
+ <xsd:extension base="xsd:string">
1753
+ <xsd:attribute name="form" type="xsd:string"/>
1754
+ <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
1755
+ </xsd:extension>
1756
+ </xsd:simpleContent>
1757
+ </xsd:complexType>
1758
+ </xsd:element>
1759
+ <xsd:element name="external-file">
1760
+ <xsd:complexType>
1761
+ <xsd:attribute name="href" type="xsd:string" use="required"/>
1762
+ <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
1763
+ <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
1764
+ </xsd:complexType>
1765
+ </xsd:element>
1766
+ <xsd:element name="note">
1767
+ <xsd:complexType>
1768
+ <xsd:simpleContent>
1769
+ <xsd:extension base="xsd:string">
1770
+ <xsd:attribute ref="xml:lang" use="optional"/>
1771
+ <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
1772
+ <xsd:attribute name="from" type="xsd:string" use="optional"/>
1773
+ <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
1774
+ </xsd:extension>
1775
+ </xsd:simpleContent>
1776
+ </xsd:complexType>
1777
+ </xsd:element>
1778
+ <xsd:element name="phase-group">
1779
+ <xsd:complexType>
1780
+ <xsd:sequence maxOccurs="unbounded">
1781
+ <xsd:element ref="xlf:phase"/>
1782
+ </xsd:sequence>
1783
+ </xsd:complexType>
1784
+ </xsd:element>
1785
+ <xsd:element name="phase">
1786
+ <xsd:complexType>
1787
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
1788
+ <xsd:element ref="xlf:note"/>
1789
+ </xsd:sequence>
1790
+ <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
1791
+ <xsd:attribute name="process-name" type="xsd:string" use="required"/>
1792
+ <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
1793
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
1794
+ <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
1795
+ <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
1796
+ <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
1797
+ <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
1798
+ <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
1799
+ </xsd:complexType>
1800
+ </xsd:element>
1801
+ <xsd:element name="count-group">
1802
+ <xsd:complexType>
1803
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
1804
+ <xsd:element ref="xlf:count"/>
1805
+ </xsd:sequence>
1806
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
1807
+ </xsd:complexType>
1808
+ </xsd:element>
1809
+ <xsd:element name="count">
1810
+ <xsd:complexType>
1811
+ <xsd:simpleContent>
1812
+ <xsd:extension base="xsd:string">
1813
+ <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
1814
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
1815
+ <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
1816
+ </xsd:extension>
1817
+ </xsd:simpleContent>
1818
+ </xsd:complexType>
1819
+ </xsd:element>
1820
+ <xsd:element name="context-group">
1821
+ <xsd:complexType>
1822
+ <xsd:sequence maxOccurs="unbounded">
1823
+ <xsd:element ref="xlf:context"/>
1824
+ </xsd:sequence>
1825
+ <xsd:attribute name="name" type="xsd:string" use="optional"/>
1826
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
1827
+ <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
1828
+ </xsd:complexType>
1829
+ </xsd:element>
1830
+ <xsd:element name="context">
1831
+ <xsd:complexType>
1832
+ <xsd:simpleContent>
1833
+ <xsd:extension base="xsd:string">
1834
+ <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
1835
+ <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
1836
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
1837
+ </xsd:extension>
1838
+ </xsd:simpleContent>
1839
+ </xsd:complexType>
1840
+ </xsd:element>
1841
+ <xsd:element name="tool">
1842
+ <xsd:complexType mixed="true">
1843
+ <xsd:sequence>
1844
+ <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
1845
+ </xsd:sequence>
1846
+ <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
1847
+ <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
1848
+ <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
1849
+ <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
1850
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1851
+ </xsd:complexType>
1852
+ </xsd:element>
1853
+ <xsd:element name="body">
1854
+ <xsd:complexType>
1855
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
1856
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
1857
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
1858
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
1859
+ </xsd:choice>
1860
+ </xsd:complexType>
1861
+ </xsd:element>
1862
+ <xsd:element name="group">
1863
+ <xsd:complexType>
1864
+ <xsd:sequence>
1865
+ <xsd:sequence>
1866
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
1867
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
1868
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
1869
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1870
+ </xsd:sequence>
1871
+ <xsd:choice maxOccurs="unbounded">
1872
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
1873
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
1874
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
1875
+ </xsd:choice>
1876
+ </xsd:sequence>
1877
+ <xsd:attribute name="id" type="xsd:string" use="optional"/>
1878
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
1879
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
1880
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
1881
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
1882
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
1883
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
1884
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
1885
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
1886
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
1887
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
1888
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
1889
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
1890
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
1891
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
1892
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
1893
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
1894
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
1895
+ <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
1896
+ <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
1897
+ <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
1898
+ <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
1899
+ <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
1900
+ <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
1901
+ <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
1902
+ <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
1903
+ <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
1904
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1905
+ </xsd:complexType>
1906
+ </xsd:element>
1907
+ <xsd:element name="trans-unit">
1908
+ <xsd:complexType>
1909
+ <xsd:sequence>
1910
+ <xsd:element ref="xlf:source"/>
1911
+ <xsd:element minOccurs="0" ref="xlf:seg-source"/>
1912
+ <xsd:element minOccurs="0" ref="xlf:target"/>
1913
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
1914
+ <xsd:element ref="xlf:context-group"/>
1915
+ <xsd:element ref="xlf:count-group"/>
1916
+ <xsd:element ref="xlf:note"/>
1917
+ <xsd:element ref="xlf:alt-trans"/>
1918
+ </xsd:choice>
1919
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
1920
+ </xsd:sequence>
1921
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
1922
+ <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
1923
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
1924
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
1925
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
1926
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
1927
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
1928
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
1929
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
1930
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
1931
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
1932
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
1933
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
1934
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
1935
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
1936
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
1937
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
1938
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
1939
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
1940
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
1941
+ <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
1942
+ <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
1943
+ <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
1944
+ <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
1945
+ <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
1946
+ <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
1947
+ <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
1948
+ <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
1949
+ <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
1950
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1951
+ </xsd:complexType>
1952
+ <xsd:unique name="U_tu_segsrc_mid">
1953
+ <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
1954
+ <xsd:field xpath="@mid"/>
1955
+ </xsd:unique>
1956
+ <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
1957
+ <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
1958
+ <xsd:field xpath="@mid"/>
1959
+ </xsd:keyref>
1960
+ </xsd:element>
1961
+ <xsd:element name="source">
1962
+ <xsd:complexType mixed="true">
1963
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
1964
+ <xsd:attribute ref="xml:lang" use="optional"/>
1965
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1966
+ </xsd:complexType>
1967
+ <xsd:unique name="U_source_bpt_rid">
1968
+ <xsd:selector xpath=".//xlf:bpt"/>
1969
+ <xsd:field xpath="@rid"/>
1970
+ </xsd:unique>
1971
+ <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
1972
+ <xsd:selector xpath=".//xlf:ept"/>
1973
+ <xsd:field xpath="@rid"/>
1974
+ </xsd:keyref>
1975
+ <xsd:unique name="U_source_bx_rid">
1976
+ <xsd:selector xpath=".//xlf:bx"/>
1977
+ <xsd:field xpath="@rid"/>
1978
+ </xsd:unique>
1979
+ <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
1980
+ <xsd:selector xpath=".//xlf:ex"/>
1981
+ <xsd:field xpath="@rid"/>
1982
+ </xsd:keyref>
1983
+ </xsd:element>
1984
+ <xsd:element name="seg-source">
1985
+ <xsd:complexType mixed="true">
1986
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
1987
+ <xsd:attribute ref="xml:lang" use="optional"/>
1988
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
1989
+ </xsd:complexType>
1990
+ <xsd:unique name="U_segsrc_bpt_rid">
1991
+ <xsd:selector xpath=".//xlf:bpt"/>
1992
+ <xsd:field xpath="@rid"/>
1993
+ </xsd:unique>
1994
+ <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
1995
+ <xsd:selector xpath=".//xlf:ept"/>
1996
+ <xsd:field xpath="@rid"/>
1997
+ </xsd:keyref>
1998
+ <xsd:unique name="U_segsrc_bx_rid">
1999
+ <xsd:selector xpath=".//xlf:bx"/>
2000
+ <xsd:field xpath="@rid"/>
2001
+ </xsd:unique>
2002
+ <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
2003
+ <xsd:selector xpath=".//xlf:ex"/>
2004
+ <xsd:field xpath="@rid"/>
2005
+ </xsd:keyref>
2006
+ </xsd:element>
2007
+ <xsd:element name="target">
2008
+ <xsd:complexType mixed="true">
2009
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2010
+ <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
2011
+ <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
2012
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
2013
+ <xsd:attribute ref="xml:lang" use="optional"/>
2014
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2015
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
2016
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
2017
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
2018
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
2019
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
2020
+ <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
2021
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2022
+ </xsd:complexType>
2023
+ <xsd:unique name="U_target_bpt_rid">
2024
+ <xsd:selector xpath=".//xlf:bpt"/>
2025
+ <xsd:field xpath="@rid"/>
2026
+ </xsd:unique>
2027
+ <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
2028
+ <xsd:selector xpath=".//xlf:ept"/>
2029
+ <xsd:field xpath="@rid"/>
2030
+ </xsd:keyref>
2031
+ <xsd:unique name="U_target_bx_rid">
2032
+ <xsd:selector xpath=".//xlf:bx"/>
2033
+ <xsd:field xpath="@rid"/>
2034
+ </xsd:unique>
2035
+ <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
2036
+ <xsd:selector xpath=".//xlf:ex"/>
2037
+ <xsd:field xpath="@rid"/>
2038
+ </xsd:keyref>
2039
+ </xsd:element>
2040
+ <xsd:element name="alt-trans">
2041
+ <xsd:complexType>
2042
+ <xsd:sequence>
2043
+ <xsd:element minOccurs="0" ref="xlf:source"/>
2044
+ <xsd:element minOccurs="0" ref="xlf:seg-source"/>
2045
+ <xsd:element maxOccurs="1" ref="xlf:target"/>
2046
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
2047
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
2048
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
2049
+ </xsd:sequence>
2050
+ <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
2051
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
2052
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
2053
+ <xsd:attribute ref="xml:lang" use="optional"/>
2054
+ <xsd:attribute name="origin" type="xsd:string" use="optional"/>
2055
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
2056
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
2057
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
2058
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2059
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
2060
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
2061
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
2062
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
2063
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
2064
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
2065
+ <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
2066
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
2067
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
2068
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
2069
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
2070
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
2071
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
2072
+ <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
2073
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2074
+ </xsd:complexType>
2075
+ <xsd:unique name="U_at_segsrc_mid">
2076
+ <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
2077
+ <xsd:field xpath="@mid"/>
2078
+ </xsd:unique>
2079
+ <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
2080
+ <xsd:selector xpath="./xlf:target/xlf:mrk"/>
2081
+ <xsd:field xpath="@mid"/>
2082
+ </xsd:keyref>
2083
+ </xsd:element>
2084
+ <xsd:element name="bin-unit">
2085
+ <xsd:complexType>
2086
+ <xsd:sequence>
2087
+ <xsd:element ref="xlf:bin-source"/>
2088
+ <xsd:element minOccurs="0" ref="xlf:bin-target"/>
2089
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
2090
+ <xsd:element ref="xlf:context-group"/>
2091
+ <xsd:element ref="xlf:count-group"/>
2092
+ <xsd:element ref="xlf:note"/>
2093
+ <xsd:element ref="xlf:trans-unit"/>
2094
+ </xsd:choice>
2095
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
2096
+ </xsd:sequence>
2097
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
2098
+ <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
2099
+ <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
2100
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
2101
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
2102
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
2103
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2104
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
2105
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2106
+ </xsd:complexType>
2107
+ </xsd:element>
2108
+ <xsd:element name="bin-source">
2109
+ <xsd:complexType>
2110
+ <xsd:choice>
2111
+ <xsd:element ref="xlf:internal-file"/>
2112
+ <xsd:element ref="xlf:external-file"/>
2113
+ </xsd:choice>
2114
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2115
+ </xsd:complexType>
2116
+ </xsd:element>
2117
+ <xsd:element name="bin-target">
2118
+ <xsd:complexType>
2119
+ <xsd:choice>
2120
+ <xsd:element ref="xlf:internal-file"/>
2121
+ <xsd:element ref="xlf:external-file"/>
2122
+ </xsd:choice>
2123
+ <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
2124
+ <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
2125
+ <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
2126
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
2127
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
2128
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
2129
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2130
+ </xsd:complexType>
2131
+ </xsd:element>
2132
+ <!-- Element for inline codes -->
2133
+ <xsd:element name="g">
2134
+ <xsd:complexType mixed="true">
2135
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2136
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2137
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
2138
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2139
+ </xsd:complexType>
2140
+ </xsd:element>
2141
+ <xsd:element name="x">
2142
+ <xsd:complexType>
2143
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
2144
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
2145
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2146
+ </xsd:complexType>
2147
+ </xsd:element>
2148
+ <xsd:element name="bx">
2149
+ <xsd:complexType>
2150
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2151
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2152
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
2153
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2154
+ </xsd:complexType>
2155
+ </xsd:element>
2156
+ <xsd:element name="ex">
2157
+ <xsd:complexType>
2158
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2159
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2160
+ </xsd:complexType>
2161
+ </xsd:element>
2162
+ <xsd:element name="ph">
2163
+ <xsd:complexType mixed="true">
2164
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2165
+ <xsd:element ref="xlf:sub"/>
2166
+ </xsd:sequence>
2167
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
2168
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2169
+ <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
2170
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2171
+ </xsd:complexType>
2172
+ </xsd:element>
2173
+ <xsd:element name="bpt">
2174
+ <xsd:complexType mixed="true">
2175
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2176
+ <xsd:element ref="xlf:sub"/>
2177
+ </xsd:sequence>
2178
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2179
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2180
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2181
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2182
+ </xsd:complexType>
2183
+ </xsd:element>
2184
+ <xsd:element name="ept">
2185
+ <xsd:complexType mixed="true">
2186
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2187
+ <xsd:element ref="xlf:sub"/>
2188
+ </xsd:sequence>
2189
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2190
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2191
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2192
+ </xsd:complexType>
2193
+ </xsd:element>
2194
+ <xsd:element name="it">
2195
+ <xsd:complexType mixed="true">
2196
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
2197
+ <xsd:element ref="xlf:sub"/>
2198
+ </xsd:sequence>
2199
+ <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
2200
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
2201
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2202
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
2203
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
2204
+ </xsd:complexType>
2205
+ </xsd:element>
2206
+ <xsd:element name="sub">
2207
+ <xsd:complexType mixed="true">
2208
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2209
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
2210
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
2211
+ <xsd:attribute name="xid" type="xsd:string" use="optional"/>
2212
+ </xsd:complexType>
2213
+ </xsd:element>
2214
+ <xsd:element name="mrk">
2215
+ <xsd:complexType mixed="true">
2216
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
2217
+ <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
2218
+ <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
2219
+ <xsd:attribute name="comment" type="xsd:string" use="optional"/>
2220
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
2221
+ </xsd:complexType>
2222
+ </xsd:element>
2223
+ </xsd:schema>
app/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php ADDED
File without changes