Visual Portfolio, Photo Gallery & Post Grid - Version 1.4.0

Version Description

Download this release

Release Info

Developer nko
Plugin Icon 128x128 Visual Portfolio, Photo Gallery & Post Grid
Version 1.4.0
Comparing to
See all releases

Version 1.4.0

Files changed (49) hide show
  1. LICENSE.txt +339 -0
  2. assets/admin/css/gutenberg-block.min.css +1 -0
  3. assets/admin/css/style.min.css +5 -0
  4. assets/admin/images/icon-black.svg +13 -0
  5. assets/admin/images/icon-gray.svg +13 -0
  6. assets/admin/images/icon-mce.svg +13 -0
  7. assets/admin/images/icon-vc.png +0 -0
  8. assets/admin/images/icon.svg +13 -0
  9. assets/admin/images/layouts/tiles-1-1.svg +13 -0
  10. assets/admin/images/layouts/tiles-2-1.svg +14 -0
  11. assets/admin/images/layouts/tiles-2-2.svg +16 -0
  12. assets/admin/images/layouts/tiles-2-3.svg +14 -0
  13. assets/admin/images/layouts/tiles-2-4.svg +14 -0
  14. assets/admin/images/layouts/tiles-2-5.svg +15 -0
  15. assets/admin/images/layouts/tiles-3-1.svg +21 -0
  16. assets/admin/images/layouts/tiles-3-10.svg +17 -0
  17. assets/admin/images/layouts/tiles-3-11.svg +17 -0
  18. assets/admin/images/layouts/tiles-3-2.svg +25 -0
  19. assets/admin/images/layouts/tiles-3-3.svg +21 -0
  20. assets/admin/images/layouts/tiles-3-4.svg +20 -0
  21. assets/admin/images/layouts/tiles-3-5.svg +20 -0
  22. assets/admin/images/layouts/tiles-3-6.svg +20 -0
  23. assets/admin/images/layouts/tiles-3-7.svg +19 -0
  24. assets/admin/images/layouts/tiles-3-8.svg +23 -0
  25. assets/admin/images/layouts/tiles-3-9.svg +22 -0
  26. assets/admin/images/layouts/tiles-4-1.svg +29 -0
  27. assets/admin/images/layouts/tiles-4-2.svg +25 -0
  28. assets/admin/images/layouts/tiles-4-3.svg +23 -0
  29. assets/admin/images/layouts/tiles-4-4.svg +17 -0
  30. assets/admin/js/gutenberg-block.min.js +6 -0
  31. assets/admin/js/mce-dropdown.min.js +6 -0
  32. assets/admin/js/mce-localize.min.js +1 -0
  33. assets/admin/js/script.min.js +1 -0
  34. assets/admin/js/vc-frontend.min.js +8 -0
  35. assets/css/style.min.css +5 -0
  36. assets/images/no-image.png +0 -0
  37. assets/js/script-preview.min.js +6 -0
  38. assets/js/script.min.js +1 -0
  39. assets/vendor/codemirror/addon/comment/comment.js +209 -0
  40. assets/vendor/codemirror/addon/comment/continuecomment.js +78 -0
  41. assets/vendor/codemirror/addon/dialog/dialog.css +32 -0
  42. assets/vendor/codemirror/addon/dialog/dialog.js +161 -0
  43. assets/vendor/codemirror/addon/edit/closebrackets.js +194 -0
  44. assets/vendor/codemirror/addon/edit/closetag.js +175 -0
  45. assets/vendor/codemirror/addon/edit/continuelist.js +89 -0
  46. assets/vendor/codemirror/addon/edit/matchbrackets.js +145 -0
  47. assets/vendor/codemirror/addon/edit/matchtags.js +66 -0
  48. assets/vendor/codemirror/addon/edit/trailingspace.js +27 -0
  49. assets/vendor/codemirror/addon/emmet/emmet.js +38227 -0
LICENSE.txt ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ <signature of Ty Coon>, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
assets/admin/css/gutenberg-block.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .wp-block-nk-visual-portfolio{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;min-height:0;padding:14px;background-color:#f8f9f9}.wp-block-nk-visual-portfolio .components-placeholder__label{-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;margin-right:14px;margin-bottom:0}.wp-block-nk-visual-portfolio .components-placeholder__label ~ *{width:auto}.wp-block-nk-visual-portfolio .visual-portfolio-gutenberg-icon{width:23px;height:23px;margin-right:10px;margin-bottom:0}.wp-block-nk-visual-portfolio .components-placeholder__fieldset{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.wp-block-nk-visual-portfolio .components-placeholder__fieldset>a{margin-right:10px}.wp-block-nk-visual-portfolio .spinner,.wp-block-nk-visual-portfolio .components-base-control{margin:0}img.visual-portfolio-gutenberg-icon{pointer-events:none}.editor-default-block-appender .editor-inserter-with-shortcuts .components-icon-button img.visual-portfolio-gutenberg-icon{opacity:.4;-webkit-transition:.2s opacity;transition:.2s opacity}.editor-default-block-appender:hover .editor-inserter-with-shortcuts .components-icon-button img.visual-portfolio-gutenberg-icon{opacity:1}.editor-inserter__block img.visual-portfolio-gutenberg-icon{opacity:.6}.editor-block-inspector__card-icon img.visual-portfolio-gutenberg-icon{width:100%;opacity:.6}.editor-inserter__block:not(:disabled):hover img.visual-portfolio-gutenberg-icon,.editor-inserter__block:not(:disabled).is-active img.visual-portfolio-gutenberg-icon,.editor-inserter__block:not(:disabled):active img.visual-portfolio-gutenberg-icon,.editor-inserter__block:not(:disabled):focus img.visual-portfolio-gutenberg-icon{opacity:1}
assets/admin/css/style.min.css ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /*!
2
+ * Name : Visual Portfolio
3
+ * Version : 1.4.0
4
+ * Author : nK https://nkdev.info
5
+ */.dashicons-visual-portfolio,.dashicons-visual-portfolio-gray,.mce-widget .mce-i-visual-portfolio{background-image:url("../images/icon.svg");background-repeat:no-repeat;background-position:center center;background-size:15px;opacity:.6}.mce-widget .mce-i-visual-portfolio{background-image:url("../images/icon-mce.svg");opacity:1}.menu-top.current .dashicons-visual-portfolio,.menu-top:hover .dashicons-visual-portfolio,.wp-has-current-submenu .dashicons-visual-portfolio{opacity:1}.dashicons-visual-portfolio-gray,.mce-i-visual-portfolio-gray{background-image:url("../images/icon-gray.svg")}.vc_element-icon[data-is-container="true"].icon-visual-portfolio,.vc_element-icon.icon-visual-portfolio{background-position:50% 50%}.vc_element-icon.icon-visual-portfolio,.vc_control-visual-portfolio{position:relative;overflow:hidden;background-image:url("../images/icon-vc.png");background-position:50% 50%;background-size:cover;border-radius:3px}.vc_add-element-container .icon-visual-portfolio{position:absolute}.vc_control-visual-portfolio{display:inline-block;width:18px;height:18px;margin:0 2px;cursor:pointer}.vc_controls-row .vc_control-visual-portfolio{float:right;margin:4px}.vc_control-visual-portfolio-overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2}.vp-row{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-sizing:border-box;box-sizing:border-box;margin-right:-15px;margin-left:-15px}.vp-col-1,.vp-col-2,.vp-col-3,.vp-col-4,.vp-col-5,.vp-col-6,.vp-col-7,.vp-col-8,.vp-col-9,.vp-col-10,.vp-col-11,.vp-col-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-box-sizing:border-box;box-sizing:border-box;padding-right:15px;padding-left:15px}.vp-col-1{-ms-flex-preferred-size:8.33333%;flex-basis:8.33333%;max-width:8.33333%}.vp-col-2{-ms-flex-preferred-size:16.66667%;flex-basis:16.66667%;max-width:16.66667%}.vp-col-3{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.vp-col-4{-ms-flex-preferred-size:33.33333%;flex-basis:33.33333%;max-width:33.33333%}.vp-col-5{-ms-flex-preferred-size:41.66667%;flex-basis:41.66667%;max-width:41.66667%}.vp-col-6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.vp-col-7{-ms-flex-preferred-size:58.33333%;flex-basis:58.33333%;max-width:58.33333%}.vp-col-8{-ms-flex-preferred-size:66.66667%;flex-basis:66.66667%;max-width:66.66667%}.vp-col-9{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.vp-col-10{-ms-flex-preferred-size:83.33333%;flex-basis:83.33333%;max-width:83.33333%}.vp-col-11{-ms-flex-preferred-size:91.66667%;flex-basis:91.66667%;max-width:91.66667%}.vp-col-12{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.vp-col-clearfix{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.post-type-vp_lists.post-php,.post-type-vp_lists.post-new-php{background-color:#edeff0}.post-type-vp_lists.post-php #wpcontent,.post-type-vp_lists.post-new-php #wpcontent{padding-left:0}.post-type-vp_lists.post-php .wrap,.post-type-vp_lists.post-new-php .wrap{margin:0}.post-type-vp_lists.post-php #poststuff,.post-type-vp_lists.post-new-php #poststuff{padding-top:0}.post-type-vp_lists.post-php #wpfooter,.post-type-vp_lists.post-new-php #wpfooter{display:none}.post-type-vp_lists.post-php #wpbody-content,.post-type-vp_lists.post-new-php #wpbody-content{padding-bottom:0}.post-type-vp_lists.post-php #post-body.columns-2 #postbox-container-1,.post-type-vp_lists.post-new-php #post-body.columns-2 #postbox-container-1{position:fixed;top:0;right:300px;bottom:0;width:300px;overflow:auto;-webkit-overflow-scrolling:touch}html.wp-toolbar .post-type-vp_lists.post-php #post-body.columns-2 #postbox-container-1,html.wp-toolbar .post-type-vp_lists.post-new-php #post-body.columns-2 #postbox-container-1{top:32px}@media only screen and (max-width: 850px){.post-type-vp_lists.post-php #post-body.columns-2 #postbox-container-1,.post-type-vp_lists.post-new-php #post-body.columns-2 #postbox-container-1{position:relative;top:auto;right:auto;bottom:auto;width:100%;margin-right:0}}.post-type-vp_lists.post-php #postbox-container-2,.post-type-vp_lists.post-new-php #postbox-container-2{position:absolute;top:0;right:0;bottom:0;left:0;width:calc(100% - 300px);min-height:calc(100vh - 32px);overflow:auto;-webkit-overflow-scrolling:touch}@media only screen and (max-width: 850px){.post-type-vp_lists.post-php #postbox-container-2,.post-type-vp_lists.post-new-php #postbox-container-2{right:0;bottom:auto;width:100%}}.post-type-vp_lists.post-php .columns-2 #side-sortables,.post-type-vp_lists.post-new-php .columns-2 #side-sortables{width:auto}.post-type-vp_lists.post-php .notice,.post-type-vp_lists.post-new-php .notice{margin:0;margin-right:300px;margin-bottom:1px}@media only screen and (max-width: 850px){.post-type-vp_lists.post-php .notice,.post-type-vp_lists.post-new-php .notice{margin-right:0}}.post-type-vp_lists.post-php #poststuff .postbox,.post-type-vp_lists.post-new-php #poststuff .postbox{margin-bottom:0;border-color:#e2e4e7;border-top:0;border-right:0}.post-type-vp_lists.post-php #poststuff .postbox>h2,.post-type-vp_lists.post-new-php #poststuff .postbox>h2{padding:15px;border-bottom:none}.post-type-vp_lists.post-php #poststuff .postbox>.handlediv,.post-type-vp_lists.post-new-php #poststuff .postbox>.handlediv{height:50px}.post-type-vp_lists.post-php #poststuff .postbox>.inside,.post-type-vp_lists.post-new-php #poststuff .postbox>.inside{padding:15px;padding-top:0}.vp-control{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:19px}.vp-control>label{width:100%;margin-bottom:5px}.vp-control>.vp-control-description{width:100%;margin:2px 0 5px;font-size:13px;font-style:italic;color:#666}.vp-control.vp-control-checkbox,.vp-control.vp-control-toggle{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.vp-control.vp-control-checkbox>label,.vp-control.vp-control-toggle>label{margin-bottom:0}.vp-control.vp-control-textarea textarea{width:100%}.vp-image-picker{display:none}.vp-image-picker,.vp-image-picker *{-webkit-box-sizing:border-box;box-sizing:border-box}.vp-image-picker+ul.thumbnails.image_picker_selector li{margin:0 10px 10px 0}.vp-image-picker+ul.thumbnails.image_picker_selector li .thumbnail{padding:0;cursor:pointer;border:none}.vp-image-picker+ul.thumbnails.image_picker_selector li .thumbnail img{display:block;border:2px solid transparent}.vp-image-picker+ul.thumbnails.image_picker_selector li .thumbnail.selected{background-color:transparent}.vp-image-picker+ul.thumbnails.image_picker_selector li .thumbnail.selected img{border-color:#0073aa}.vp-image-picker+ul.thumbnails.image_picker_selector .group_title{padding-top:5px;padding-left:5px;font-weight:500}.vp-control-range [type="number"]{width:50px;margin-left:10px}.vp-control-range [type="range"]{-webkit-box-flex:1;-ms-flex:1;flex:1;width:100%;padding:0;margin-left:10px;background:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vp-control-range [type="range"]::-webkit-slider-thumb{-webkit-box-sizing:border-box;box-sizing:border-box;width:18px;height:18px;margin-top:-7px;cursor:pointer;background:#555d66;background-clip:padding-box;border:4px solid transparent;border-radius:50%;-webkit-appearance:none;appearance:none}.vp-control-range [type="range"]::-moz-range-thumb{box-sizing:border-box;width:18px;height:18px;cursor:pointer;background:#555d66;background-clip:padding-box;border:4px solid transparent;border-radius:50%}.vp-control-range [type="range"]::-ms-thumb{box-sizing:border-box;width:14px;height:14px;margin-top:0;cursor:pointer;background:#555d66;background-clip:padding-box;border:2px solid transparent;border-radius:50%}.vp-control-range [type="range"]:focus{outline:none}.vp-control-range [type="range"]:focus::-webkit-slider-thumb{color:#191e23;background-color:#fff;outline:2px solid transparent;outline-offset:-2px;-webkit-box-shadow:inset 0 0 0 1px #6c7781, inset 0 0 0 2px #fff;box-shadow:inset 0 0 0 1px #6c7781, inset 0 0 0 2px #fff}.vp-control-range [type="range"]:focus::-moz-range-thumb{color:#191e23;background-color:#fff;outline:2px solid transparent;outline-offset:-2px;box-shadow:inset 0 0 0 1px #6c7781, inset 0 0 0 2px #fff}.vp-control-range [type="range"]:focus::-ms-thumb{color:#191e23;background-color:#fff;outline:2px solid transparent;outline-offset:-2px;box-shadow:inset 0 0 0 1px #6c7781, inset 0 0 0 2px #fff}.vp-control-range [type="range"]::-webkit-slider-runnable-track{height:3px;margin-top:-4px;cursor:pointer;background:#e2e4e7;border-radius:1.5px}.vp-control-range [type="range"]::-moz-range-track{height:3px;cursor:pointer;background:#e2e4e7;border-radius:1.5px}.vp-control-range [type="range"]::-ms-track{height:3px;margin-top:-4px;color:transparent;cursor:pointer;background:#e2e4e7;border-color:transparent;border-radius:1.5px}.vp-control-toggle,.vp-control-toggle *{-webkit-box-sizing:border-box;box-sizing:border-box}.vp-control-toggle .vp-toggle{position:relative}.vp-control-toggle .vp-toggle .vp-toggle__track{content:"";display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;width:36px;height:18px;vertical-align:top;background-color:#fff;border:2px solid #6c7781;border-radius:9px;-webkit-transition:background .2s ease;transition:background .2s ease}.vp-control-toggle .vp-toggle .vp-toggle__track::after{content:"";position:absolute;display:block;top:50%;right:5px;width:3px;height:3px;margin-top:-3px;border:1.5px solid #6c7781;border-radius:3px}.vp-control-toggle .vp-toggle:hover .vp-toggle__track{background-color:#e2e4e7}.vp-control-toggle .vp-toggle [type="checkbox"]:checked ~ .vp-toggle__track{background-color:#33b3db;border:2px solid #33b3db}.vp-control-toggle .vp-toggle [type="checkbox"]:checked ~ .vp-toggle__track::after{top:50%;right:auto;left:8px;width:0;height:5px;margin-top:-3px;border:0;border-right:2px solid #fff;border-radius:0}.vp-control-toggle .vp-toggle .vp-toggle__thumb{position:absolute;display:block;top:4px;left:4px;width:10px;height:10px;background-color:#6c7781;border:5px solid #6c7781;border-radius:50%;-webkit-transition:-webkit-transform .1s ease;transition:-webkit-transform .1s ease;transition:transform .1s ease;transition:transform .1s ease, -webkit-transform .1s ease}.vp-control-toggle .vp-toggle [type="checkbox"]:focus ~ .vp-toggle__track{-webkit-box-shadow:0 0 0 2px #fff, 0 0 0 3px #6c7781;box-shadow:0 0 0 2px #fff, 0 0 0 3px #6c7781}.vp-control-toggle .vp-toggle [type="checkbox"]:checked ~ .vp-toggle__thumb{background-color:#fff;border-width:0;-webkit-transform:translateX(18px);transform:translateX(18px)}.vp-control-toggle .vp-toggle [type="checkbox"]{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;margin:0;opacity:0;z-index:1}.vp-control-image-dropdown{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;padding:5px 7px;cursor:pointer;background-color:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.07);box-shadow:inset 0 1px 2px rgba(0,0,0,0.07)}.vp-control-image-dropdown,.vp-control-image-dropdown *{-webkit-box-sizing:border-box;box-sizing:border-box}.vp-control-image-dropdown::before{content:"";position:absolute;display:block;top:50%;right:6px;width:0;height:0;margin-top:-2px;border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px}.vp-control-image-dropdown.active::before{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.vp-control-image-dropdown .vp-control-image-dropdown__preview{display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:32px}.vp-control-image-dropdown .vp-control-image-dropdown__preview img{display:block;width:100%;height:auto}.vp-control-image-dropdown .vp-control-image-dropdown__title{-webkit-box-flex:1;-ms-flex:1;flex:1;padding-left:10px}.vp-control-image-dropdown .vp-control-image-dropdown__content{position:absolute;display:none;top:100%;left:0;width:100%;max-width:285px;margin-top:7px;margin-left:-1px;cursor:default;background-color:#fff;border:1px solid #e5e5e5;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04);z-index:1}.vp-control-image-dropdown .vp-control-image-dropdown__content>div{width:100%;max-height:250px;padding:4px;overflow:auto}.vp-control-image-dropdown .vp-control-image-dropdown__content::before{content:"";position:absolute;display:block;top:-5px;left:10px;width:0;height:0;border-right:5px solid transparent;border-bottom:5px solid #e5e5e5;border-left:5px solid transparent}.vp-control-image-dropdown .vp-control-image-dropdown__content::after{content:"";position:absolute;display:block;top:-7px;right:0;left:0;height:7px}.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector,.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector .group>ul{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector li{display:block;-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;float:none;max-width:25%;margin:0}.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector li.group,.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector li.group_title{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector li .thumbnail{padding:3px}.vp-control-image-dropdown .vp-control-image-dropdown__content .vp-image-picker+ul.thumbnails.image_picker_selector li img{width:100%;height:auto}.vp-control-image-dropdown.active .vp-control-image-dropdown__content{display:block}.vp-oembed-preview{position:relative;width:100%;padding-top:56.25%;color:#a2a2a2;background-color:#f1f1f1;border:1px solid #e8e8e8}.vp-oembed-preview::after{content:"\f126";position:absolute;display:block;top:50%;left:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:dashicons;font-size:20px;font-style:normal;font-weight:400;line-height:1;text-align:center;text-decoration:inherit;vertical-align:top;z-index:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.vp-oembed-preview>iframe{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}.vp-portfolio__thumbnail{position:relative;display:block;max-width:70px;padding-top:100%;overflow:hidden;border-radius:3px}.vp-portfolio__thumbnail img{position:absolute;display:block;top:0;left:0;width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.vp-portfolio__thumbnail:empty{background-color:#f1f1f1;border:1px solid #e8e8e8}.vp-portfolio__thumbnail:empty,.vp-portfolio__thumbnail:empty:hover,.vp-portfolio__thumbnail:empty:active,.vp-portfolio__thumbnail:empty:focus{color:#a2a2a2}.vp-portfolio__thumbnail:empty::after{content:"\f128";position:absolute;display:block;top:50%;left:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:dashicons;font-size:20px;font-style:normal;font-weight:400;line-height:1;text-align:center;text-decoration:inherit;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wp-list-table th.column-portfolio_post_thumbs{width:70px}.wp-list-table th.column-vp_lists_post_shortcode{width:250px}@media screen and (max-width: 782px){.wp-list-table th.column-portfolio_post_thumbs{display:none}.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-portfolio_post_thumbs{float:left;width:70px !important;min-width:70px}.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-portfolio_post_thumbs::before{content:none}.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-title{overflow:hidden;clear:right}}.vp-portfolio-list .vp-portfolio-list__icon span{display:block;width:120px;height:120px;margin:0 auto;margin-top:60px;background-size:105px}.vp-portfolio-list .vp-portfolio-list__text{text-align:center}.vp-portfolio-list .vp-portfolio-list__text p{margin-top:30px;margin-bottom:30px;font-size:15px;font-weight:500;color:#8e8e8e}.vp-portfolio-list .vp-portfolio-list__text .button-hero{display:inline-block}.vp_list_preview{padding:0 12px;margin-right:-12px;margin-left:-12px}.vp_list_preview iframe{width:100%;min-height:120px;-webkit-transition:height .3s;transition:height .3s}.vp-content-source{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-right:9px;padding-left:9px;margin-right:-15px;margin-left:-15px}.vp-content-source .vp-content-source__item{position:relative;width:70px;height:50px;padding:12px;margin:0 5px;color:#6c7781;text-align:center;cursor:pointer;border:1px solid transparent;border-radius:3px}.vp-content-source .vp-content-source__item.active,.vp-content-source .vp-content-source__item:hover{color:#555;background-color:#ecf0f4}.vp-content-source .vp-content-source__item.active{color:#fff;background-color:#6c7781;border-color:#6c7781}.vp-content-source .vp-content-source__item .vp-content-source__item-icon>span{width:24px;height:24px;margin-top:2px;font-size:24px}.vp-content-source .vp-content-source__item .vp-content-source__item-title{position:absolute;top:58%;right:8px;left:8px;font-weight:500}.vp-content-source .vp-content-source__item-content{-webkit-box-flex:1;-ms-flex:1;flex:1;min-width:100%}.vp-content-source .vp-content-source__item-content>div{position:relative;display:none;padding:0 15px;padding-bottom:1px;margin-top:12px;margin-right:-9px;margin-bottom:-14px;margin-left:-9px;overflow:hidden;background-color:#f9f9fa;border-top:1px solid #eee}.vp-content-source .vp-content-source__item-content>div:empty{display:none !important}.vp-content-source .vp-content-source__item-content>div.active{display:block}.vp-select2{width:100%}.vp-select2+.select2{width:100%}.post-attributes-label+.vp-select2+.select2{margin-top:5px}.vp-select2+.select2 ul,.vp-select2+.select2 li{margin-bottom:0}.vp-select2+.select2 .select2-selection{border:1px solid #ddd;border-radius:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.07);box-shadow:inset 0 1px 2px rgba(0,0,0,0.07)}.vp-select2+.select2.select2-container--open .select2-selection{outline:none}.vp-select2+.select2 .select2-selection--multiple{min-height:27px}.vp-select2+.select2 .select2-selection--multiple .select2-selection__choice{padding:3px 8px;margin-top:3px;color:#fff;background-color:#6c7781;border-color:#6c7781}.vp-select2+.select2 .select2-selection--multiple .select2-selection__choice__remove{float:right;margin-right:0;margin-left:3px;color:inherit;opacity:.5}.select2-vp-container ul,.select2-vp-container li{margin-bottom:0}.select2-vp-container .select2-dropdown{border-color:#ddd}.select2-vp-container .select2-search--dropdown .select2-search__field{padding:3px 4px;border:1px solid #ddd;outline:none;-webkit-box-shadow:none;box-shadow:none}.select2-vp-container .select2-results__option[aria-selected="true"]{background-color:#efeeee}.select2-vp-container .select2-results__option--highlighted[aria-selected]{background-color:#33b3db}.vp-select2-ajax__result{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap}.vp-select2-ajax__result .vp-select2-ajax__result-img{position:relative;-webkit-box-flex:0;-ms-flex:0 0 35px;flex:0 0 35px;background-color:rgba(0,0,0,0.1);background-position:center center;background-size:cover;border-radius:3px}.vp-select2-ajax__result .vp-select2-ajax__result-img::after{content:"";display:block;width:100%;padding-top:100%}.vp-select2-ajax__result .vp-select2-ajax__result-data{padding-left:10px}.vp-select2-ajax__result .vp-select2-ajax__result-title{font-size:16px;font-weight:500;line-height:1}.vp-select2-ajax__result .vp-select2-ajax__result-post-type{font-size:12px;opacity:.5}.vp-control-gallery .vp-control-gallery-additional-data{position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;top:0;right:-350px;bottom:0;width:350px;padding:15px 13px;overflow:auto;background-color:#fff;border-left:1px solid #eaeaea;-webkit-transition:.15s right;transition:.15s right}.vp-control-gallery .vp-control-gallery-additional-data.active{right:0}.vp-control-gallery .vp-control-gallery-additional-data.active+.vp-control-gallery-items{margin-right:335px}@media (max-width: 910px){.vp-control-gallery .vp-control-gallery-additional-data{position:relative;display:none;right:0;width:120%;height:auto;margin-bottom:30px;border:1px solid #eaeaea}.vp-control-gallery .vp-control-gallery-additional-data.active{display:block}.vp-control-gallery .vp-control-gallery-additional-data.active+.vp-control-gallery-items{margin-right:-15px}}.vp-control-gallery .vp-control-gallery-additional-data .vp-control-gallery-additional-data-preview{display:-webkit-box;display:-ms-flexbox;display:flex;padding:15px 13px;margin:-15px -13px;margin-bottom:15px;border-bottom:1px solid #eaeaea}.vp-control-gallery .vp-control-gallery-additional-data .vp-control-gallery-additional-data-preview .vp-control-gallery-additional-data-preview-image{margin-right:15px}.vp-control-gallery .vp-control-gallery-additional-data .vp-control-gallery-additional-data-preview .vp-control-gallery-additional-data-preview-image img{display:block;width:70px;border-radius:3px;-webkit-box-shadow:0 0 0 1px #fff, 0 0 0 2px #eaeaea;box-shadow:0 0 0 1px #fff, 0 0 0 2px #eaeaea}.vp-control-gallery .vp-control-gallery-additional-data .vp-control-gallery-additional-data-preview .vp-control-gallery-additional-data-preview-size{color:#8f9498}.vp-control-gallery .vp-control-gallery-items{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-line-pack:start;align-content:flex-start;width:120%;height:325px;padding:7px;margin:-12px;margin-bottom:-25px;overflow:auto;-webkit-transition:.15s margin-right;transition:.15s margin-right}.vp-control-gallery .vp-control-gallery-items::after{content:"";display:block;width:100%}.vp-control-gallery .vp-control-gallery-items>div{position:relative;display:block;width:calc(12.5% - 10px);margin:5px;cursor:move;cursor:-webkit-grab;cursor:grab;border-radius:3px}@media (max-width: 1350px){.vp-control-gallery .vp-control-gallery-items>div{width:calc(14.22% - 10px)}}@media (max-width: 1250px){.vp-control-gallery .vp-control-gallery-items>div{width:calc(16.66% - 10px)}}@media (max-width: 1100px){.vp-control-gallery .vp-control-gallery-items>div{width:calc(25% - 10px)}}.vp-control-gallery .vp-control-gallery-items>div::after{content:"";display:block;padding-top:100%}.vp-control-gallery .vp-control-gallery-items>div.sortable-ghost{opacity:.4}.vp-control-gallery .vp-control-gallery-items>div img{position:absolute;display:block;top:0;left:0;width:100%;height:100%;border-radius:3px}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-img .vp-control-gallery-items-remove{position:absolute;top:-5px;right:-5px;width:20px;height:20px;color:#fff;cursor:pointer;visibility:hidden;background-color:#dc3232;border-radius:50%;opacity:0;-webkit-transition:.15s visibility, .15s opacity;transition:.15s visibility, .15s opacity}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-img .vp-control-gallery-items-remove span{width:20px;height:20px;font-size:10px;line-height:20px}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-img:hover .vp-control-gallery-items-remove{visibility:visible;opacity:1}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-img.active{-webkit-box-shadow:0 0 0 1px #fff, 0 0 0 4px #33b3db;box-shadow:0 0 0 1px #fff, 0 0 0 4px #33b3db}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-add{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-sizing:border-box;box-sizing:border-box;color:#6c7781;text-align:center;cursor:pointer;background-color:#fff;border:1px solid #ccd3da;border-radius:3px}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-add>span{position:absolute;top:50%;left:50%;width:24px;height:24px;margin-top:-12px;margin-left:-12px;line-height:24px}.vp-control-gallery .vp-control-gallery-items>.vp-control-gallery-items-add:hover{color:#555;background-color:#f7f7f7}.vp-input{width:100%}.post-type-vp_lists .CodeMirror{text-align:left;border:1px solid #ddd}.post-type-vp_lists .CodeMirror .CodeMirror-matchingbracket{color:inherit;background:rgba(255,150,0,0.3)}.post-type-vp_lists [class*="CodeMirror-lint-message"],.post-type-vp_lists .CodeMirror-lint-marker-multiple,.post-type-vp_lists [class*="CodeMirror-lint-marker"]{background-image:none}.post-type-vp_lists .CodeMirror-lint-marker-error,.post-type-vp_lists .CodeMirror-lint-marker-warning{cursor:help}.post-type-vp_lists .CodeMirror-lint-marker-multiple{position:absolute;top:0}.post-type-vp_lists [class*="CodeMirror-lint-marker"]::before{position:relative;top:-2px;font:400 18px/1 dashicons}.post-type-vp_lists [class*="CodeMirror-lint-message"]::before{position:absolute;left:16px;font:400 16px/1 dashicons}.post-type-vp_lists .CodeMirror-lint-message-error,.post-type-vp_lists .CodeMirror-lint-message-warning{padding:3px 12px 3px 28px;margin:5px 0 2px;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1)}.post-type-vp_lists .CodeMirror-lint-message-warning{background-color:#fff8e5;border-left:4px solid #ffb900}.post-type-vp_lists .CodeMirror-lint-message-warning::before,.post-type-vp_lists .CodeMirror-lint-marker-warning::before{content:"\f534";color:#f6a306}.post-type-vp_lists .CodeMirror-lint-message-error{background-color:#fbeaea;border-left:4px solid #dc3232}.post-type-vp_lists .CodeMirror-lint-message-error::before,.post-type-vp_lists .CodeMirror-lint-marker-error::before{content:"\f153";color:#dc3232}.post-type-vp_lists .CodeMirror-lint-tooltip{background:0 0;border:none;border-radius:0;direction:ltr}@media (max-width: 850px){.vp-steps__right,.vp-steps__step{float:none;width:100%}}
assets/admin/images/icon-black.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #000;
6
+ }
7
+ </style>
8
+ </defs>
9
+ <rect id="BR" class="cls-1" y="6" width="7" height="9"/>
10
+ <rect id="BL" class="cls-1" x="8" y="10" width="7" height="5"/>
11
+ <rect id="TR" class="cls-1" width="7" height="5"/>
12
+ <rect id="TL" class="cls-1" x="8" width="7" height="9"/>
13
+ </svg>
assets/admin/images/icon-gray.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #bbbbbb;
6
+ }
7
+ </style>
8
+ </defs>
9
+ <rect id="BR" class="cls-1" y="6" width="7" height="9"/>
10
+ <rect id="BL" class="cls-1" x="8" y="10" width="7" height="5"/>
11
+ <rect id="TR" class="cls-1" width="7" height="5"/>
12
+ <rect id="TL" class="cls-1" x="8" width="7" height="9"/>
13
+ </svg>
assets/admin/images/icon-mce.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #555d66;
6
+ }
7
+ </style>
8
+ </defs>
9
+ <rect id="BR" class="cls-1" y="6" width="7" height="9"/>
10
+ <rect id="BL" class="cls-1" x="8" y="10" width="7" height="5"/>
11
+ <rect id="TR" class="cls-1" width="7" height="5"/>
12
+ <rect id="TL" class="cls-1" x="8" width="7" height="9"/>
13
+ </svg>
assets/admin/images/icon-vc.png ADDED
Binary file
assets/admin/images/icon.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #fff;
6
+ }
7
+ </style>
8
+ </defs>
9
+ <rect id="BR" class="cls-1" y="6" width="7" height="9"/>
10
+ <rect id="BL" class="cls-1" x="8" y="10" width="7" height="5"/>
11
+ <rect id="TR" class="cls-1" width="7" height="5"/>
12
+ <rect id="TL" class="cls-1" x="8" width="7" height="9"/>
13
+ </svg>
assets/admin/images/layouts/tiles-1-1.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="65" height="19" />
11
+ <rect class="cls-1" x="0" y="23" width="65" height="19" />
12
+ <rect class="cls-1" x="0" y="46" width="65" height="19" />
13
+ </svg>
assets/admin/images/layouts/tiles-2-1.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="30" height="31" />
11
+ <rect class="cls-1" x="34" y="0" width="31" height="31" />
12
+ <rect class="cls-1" x="0" y="35" width="30" height="30" />
13
+ <rect class="cls-1" x="34" y="35" width="31" height="30" />
14
+ </svg>
assets/admin/images/layouts/tiles-2-2.svg ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="30" height="21" />
11
+ <rect class="cls-1" x="34" y="0" width="31" height="21" />
12
+ <rect class="cls-1" x="0" y="25" width="30" height="21" />
13
+ <rect class="cls-1" x="34" y="25" width="31" height="21" />
14
+ <rect class="cls-1" x="0" y="50" width="30" height="21" />
15
+ <rect class="cls-1" x="34" y="50" width="31" height="21" />
16
+ </svg>
assets/admin/images/layouts/tiles-2-3.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="30" height="40" />
11
+ <rect class="cls-1" x="34" y="0" width="31" height="40" />
12
+ <rect class="cls-1" x="0" y="44" width="30" height="21" />
13
+ <rect class="cls-1" x="34" y="44" width="31" height="21" />
14
+ </svg>
assets/admin/images/layouts/tiles-2-4.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="30" height="40" />
11
+ <rect class="cls-1" x="34" y="0" width="31" height="21" />
12
+ <rect class="cls-1" x="0" y="44" width="30" height="21" />
13
+ <rect class="cls-1" x="34" y="25" width="31" height="40" />
14
+ </svg>
assets/admin/images/layouts/tiles-2-5.svg ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="31" height="21" />
11
+ <rect class="cls-1" x="34" y="0" width="30" height="33" />
12
+ <rect class="cls-1" x="0" y="25" width="30" height="33" />
13
+ <rect class="cls-1" x="34" y="37" width="30" height="28" />
14
+ <rect class="cls-1" x="0" y="62" width="30" height="3" />
15
+ </svg>
assets/admin/images/layouts/tiles-3-1.svg ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="19" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="19" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="19" />
13
+
14
+ <rect class="cls-1" x="0" y="23" width="19" height="19" />
15
+ <rect class="cls-1" x="23" y="23" width="19" height="19" />
16
+ <rect class="cls-1" x="46" y="23" width="19" height="19" />
17
+
18
+ <rect class="cls-1" x="0" y="46" width="19" height="19" />
19
+ <rect class="cls-1" x="23" y="46" width="19" height="19" />
20
+ <rect class="cls-1" x="46" y="46" width="19" height="19" />
21
+ </svg>
assets/admin/images/layouts/tiles-3-10.svg ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="19" />
11
+ <rect class="cls-1" x="23" y="0" width="42" height="42" />
12
+
13
+ <rect class="cls-1" x="0" y="23" width="19" height="19" />
14
+
15
+ <rect class="cls-1" x="0" y="46" width="42" height="19" />
16
+ <rect class="cls-1" x="46" y="46" width="19" height="19" />
17
+ </svg>
assets/admin/images/layouts/tiles-3-11.svg ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="42" />
11
+ <rect class="cls-1" x="23" y="0" width="42" height="19" />
12
+
13
+ <rect class="cls-1" x="23" y="23" width="19" height="19" />
14
+ <rect class="cls-1" x="46" y="23" width="19" height="42" />
15
+
16
+ <rect class="cls-1" x="0" y="46" width="42" height="19" />
17
+ </svg>
assets/admin/images/layouts/tiles-3-2.svg ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="15" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="15" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="15" />
13
+
14
+ <rect class="cls-1" x="0" y="19" width="19" height="15" />
15
+ <rect class="cls-1" x="23" y="19" width="19" height="15" />
16
+ <rect class="cls-1" x="46" y="19" width="19" height="15" />
17
+
18
+ <rect class="cls-1" x="0" y="38" width="19" height="15" />
19
+ <rect class="cls-1" x="23" y="38" width="19" height="15" />
20
+ <rect class="cls-1" x="46" y="38" width="19" height="15" />
21
+
22
+ <rect class="cls-1" x="0" y="57" width="19" height="15" />
23
+ <rect class="cls-1" x="23" y="57" width="19" height="15" />
24
+ <rect class="cls-1" x="46" y="57" width="19" height="15" />
25
+ </svg>
assets/admin/images/layouts/tiles-3-3.svg ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="15" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="15" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="15" />
13
+
14
+ <rect class="cls-1" x="0" y="19" width="19" height="27" />
15
+ <rect class="cls-1" x="23" y="19" width="19" height="27" />
16
+ <rect class="cls-1" x="46" y="19" width="19" height="27" />
17
+
18
+ <rect class="cls-1" x="0" y="50" width="19" height="15" />
19
+ <rect class="cls-1" x="23" y="50" width="19" height="15" />
20
+ <rect class="cls-1" x="46" y="50" width="19" height="15" />
21
+ </svg>
assets/admin/images/layouts/tiles-3-4.svg ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="19" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="19" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="42" />
13
+
14
+ <rect class="cls-1" x="0" y="23" width="19" height="19" />
15
+ <rect class="cls-1" x="23" y="23" width="19" height="19" />
16
+
17
+ <rect class="cls-1" x="0" y="46" width="19" height="19" />
18
+ <rect class="cls-1" x="23" y="46" width="19" height="19" />
19
+ <rect class="cls-1" x="46" y="46" width="19" height="19" />
20
+ </svg>
assets/admin/images/layouts/tiles-3-5.svg ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="42" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="19" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="19" />
13
+
14
+ <rect class="cls-1" x="23" y="23" width="19" height="19" />
15
+ <rect class="cls-1" x="46" y="23" width="19" height="19" />
16
+
17
+ <rect class="cls-1" x="0" y="46" width="19" height="19" />
18
+ <rect class="cls-1" x="23" y="46" width="19" height="19" />
19
+ <rect class="cls-1" x="46" y="46" width="19" height="19" />
20
+ </svg>
assets/admin/images/layouts/tiles-3-6.svg ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="19" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="42" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="19" />
13
+
14
+ <rect class="cls-1" x="0" y="23" width="19" height="19" />
15
+ <rect class="cls-1" x="46" y="23" width="19" height="19" />
16
+
17
+ <rect class="cls-1" x="0" y="46" width="19" height="19" />
18
+ <rect class="cls-1" x="23" y="46" width="19" height="19" />
19
+ <rect class="cls-1" x="46" y="46" width="19" height="19" />
20
+ </svg>
assets/admin/images/layouts/tiles-3-7.svg ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="19" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="42" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="19" />
13
+
14
+ <rect class="cls-1" x="0" y="23" width="19" height="19" />
15
+ <rect class="cls-1" x="46" y="23" width="19" height="19" />
16
+
17
+ <rect class="cls-1" x="0" y="46" width="19" height="19" />
18
+ <rect class="cls-1" x="23" y="46" width="42" height="19" />
19
+ </svg>
assets/admin/images/layouts/tiles-3-8.svg ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="16" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="36" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="16" />
13
+
14
+ <rect class="cls-1" x="0" y="20" width="19" height="16" />
15
+ <rect class="cls-1" x="46" y="20" width="19" height="36" />
16
+
17
+ <rect class="cls-1" x="0" y="40" width="19" height="16" />
18
+ <rect class="cls-1" x="23" y="40" width="19" height="16" />
19
+
20
+ <rect class="cls-1" x="0" y="59" width="19" height="16" />
21
+ <rect class="cls-1" x="23" y="59" width="19" height="16" />
22
+ <rect class="cls-1" x="46" y="59" width="19" height="16" />
23
+ </svg>
assets/admin/images/layouts/tiles-3-9.svg ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="19" height="16" />
11
+ <rect class="cls-1" x="23" y="0" width="19" height="16" />
12
+ <rect class="cls-1" x="46" y="0" width="19" height="36" />
13
+
14
+ <rect class="cls-1" x="0" y="20" width="19" height="16" />
15
+ <rect class="cls-1" x="23" y="20" width="19" height="16" />
16
+
17
+ <rect class="cls-1" x="0" y="40" width="19" height="16" />
18
+ <rect class="cls-1" x="23" y="40" width="19" height="36" />
19
+ <rect class="cls-1" x="46" y="40" width="19" height="36" />
20
+
21
+ <rect class="cls-1" x="0" y="59" width="19" height="16" />
22
+ </svg>
assets/admin/images/layouts/tiles-4-1.svg ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="13" height="13" />
11
+ <rect class="cls-1" x="17" y="0" width="13" height="13" />
12
+ <rect class="cls-1" x="34" y="0" width="13" height="13" />
13
+ <rect class="cls-1" x="51" y="0" width="13" height="13" />
14
+
15
+ <rect class="cls-1" x="0" y="17" width="13" height="13" />
16
+ <rect class="cls-1" x="17" y="17" width="13" height="13" />
17
+ <rect class="cls-1" x="34" y="17" width="13" height="13" />
18
+ <rect class="cls-1" x="51" y="17" width="13" height="13" />
19
+
20
+ <rect class="cls-1" x="0" y="34" width="13" height="13" />
21
+ <rect class="cls-1" x="17" y="34" width="13" height="13" />
22
+ <rect class="cls-1" x="34" y="34" width="13" height="13" />
23
+ <rect class="cls-1" x="51" y="34" width="13" height="13" />
24
+
25
+ <rect class="cls-1" x="0" y="51" width="13" height="13" />
26
+ <rect class="cls-1" x="17" y="51" width="13" height="13" />
27
+ <rect class="cls-1" x="34" y="51" width="13" height="13" />
28
+ <rect class="cls-1" x="51" y="51" width="13" height="13" />
29
+ </svg>
assets/admin/images/layouts/tiles-4-2.svg ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="13" height="13" />
11
+ <rect class="cls-1" x="17" y="0" width="13" height="30" />
12
+ <rect class="cls-1" x="34" y="0" width="13" height="13" />
13
+ <rect class="cls-1" x="51" y="0" width="13" height="30" />
14
+
15
+ <rect class="cls-1" x="0" y="17" width="13" height="30" />
16
+ <rect class="cls-1" x="34" y="17" width="13" height="30" />
17
+
18
+ <rect class="cls-1" x="17" y="34" width="13" height="13" />
19
+ <rect class="cls-1" x="51" y="34" width="13" height="13" />
20
+
21
+ <rect class="cls-1" x="0" y="51" width="13" height="13" />
22
+ <rect class="cls-1" x="17" y="51" width="13" height="13" />
23
+ <rect class="cls-1" x="34" y="51" width="13" height="13" />
24
+ <rect class="cls-1" x="51" y="51" width="13" height="13" />
25
+ </svg>
assets/admin/images/layouts/tiles-4-3.svg ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="13" height="13" />
11
+ <rect class="cls-1" x="17" y="0" width="13" height="13" />
12
+ <rect class="cls-1" x="34" y="0" width="30" height="30" />
13
+
14
+ <rect class="cls-1" x="0" y="17" width="13" height="13" />
15
+ <rect class="cls-1" x="17" y="17" width="13" height="13" />
16
+
17
+ <rect class="cls-1" x="0" y="34" width="30" height="30" />
18
+ <rect class="cls-1" x="34" y="34" width="13" height="13" />
19
+ <rect class="cls-1" x="51" y="34" width="13" height="13" />
20
+
21
+ <rect class="cls-1" x="34" y="51" width="13" height="13" />
22
+ <rect class="cls-1" x="51" y="51" width="13" height="13" />
23
+ </svg>
assets/admin/images/layouts/tiles-4-4.svg ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="65" height="65" viewBox="0 0 65 65">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ fill: #cfcfcf;
6
+ fill-rule: evenodd;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <rect class="cls-1" x="0" y="0" width="30" height="30" />
11
+ <rect class="cls-1" x="34" y="0" width="30" height="13" />
12
+ <rect class="cls-1" x="34" y="17" width="30" height="13" />
13
+
14
+ <rect class="cls-1" x="34" y="34" width="30" height="30" />
15
+ <rect class="cls-1" x="0" y="34" width="30" height="13" />
16
+ <rect class="cls-1" x="0" y="51" width="30" height="13" />
17
+ </svg>
assets/admin/js/gutenberg-block.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ !function(t){function e(n){if(o[n])return o[n].exports;var r=o[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var o={};e.m=t,e.c=o,e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=13)}([function(t,e){(function(e){t.exports=e}).call(e,{})},,,,,,,,,,,,,function(t,e,o){t.exports=o(14)},function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=o(15),r=o.n(n),l=o(16),a=o.n(l),s=o(17),i=o.n(s),c=wp.i18n.__,u=wp.element,p=u.Fragment,f=u.RawHTML,d=wp.blocks.registerBlockType,v=wp.components,m=v.Placeholder,y=v.Spinner,h=v.SelectControl,g=v.withAPIData;d("nk/visual-portfolio",{title:"Visual Portfolio",icon:wp.element.createElement("img",{className:"visual-portfolio-gutenberg-icon",src:a.a,alt:"visual-portfolio-icon"}),category:"common",keywords:["visual portfolio","vp","portfolio"],supports:{anchor:!0,className:!0,html:!1,ghostkitIndents:!0,ghostkitDisplay:!0},attributes:{id:{type:"string"}},edit:g(function(){return{portfolioLayouts:"/visual-portfolio/v1/get_layouts/"}})(function(t){var e=t.portfolioLayouts,o=t.attributes,n=t.className,l=t.setAttributes,a=o.id,s=o.ghostkitClassname,u=!1,f=!1;return s&&(n=r()(n,s)),e&&e.data&&e.data.success?(u=[{label:c("--- Select layout ---"),value:""}],Object.keys(e.data.response).map(function(t){var o=e.data.response[t];u.push({label:"#"+o.id+" - "+o.title,value:o.id}),a&&parseInt(a,10)===o.id&&(f=o.edit_url)})):a&&(u=[{label:"#"+a,value:a}]),wp.element.createElement(m,{icon:wp.element.createElement("img",{className:"visual-portfolio-gutenberg-icon",src:i.a,alt:"visual-portfolio-icon"}),label:c("Visual Portfolio"),className:n},!Array.isArray(u)&&wp.element.createElement(y,null),Array.isArray(u)&&u.length&&wp.element.createElement(p,null,f&&wp.element.createElement("a",{href:f,target:"_blank"},c("Edit Layout")),wp.element.createElement(h,{value:a,onChange:function(t){return l({id:t})},options:u})),Array.isArray(u)&&!u.length&&c("No portfolio layouts found."))}),save:function(t){var e=t.attributes,o=t.className,n=e.id,r="[visual_portfolio";return n&&(r+=' id="'+n+'"'),o&&(r+=' class="'+o+'"'),r+="]",wp.element.createElement(f,null,r)}})},function(t,e,o){var n,r,l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};/*!
2
+ Copyright (c) 2016 Jed Watson.
3
+ Licensed under the MIT License (MIT), see
4
+ http://jedwatson.github.io/classnames
5
+ */
6
+ !function(){"use strict";var a=function(){function t(){}function e(t,e){for(var o=e.length,n=0;n<o;++n)a(t,e[n])}function o(t,e){t[e]=!0}function n(t,e){for(var o in e)i.call(e,o)&&(t[o]=!!e[o])}function r(t,e){for(var o=e.split(c),n=o.length,r=0;r<n;++r)t[o[r]]=!0}function a(t,a){if(a){var s=void 0===a?"undefined":l(a);"string"===s?r(t,a):Array.isArray(a)?e(t,a):"object"===s?n(t,a):"number"===s&&o(t,a)}}function s(){for(var o=arguments.length,n=Array(o),r=0;r<o;r++)n[r]=arguments[r];var l=new t;e(l,n);var a=[];for(var s in l)l[s]&&a.push(s);return a.join(" ")}t.prototype=Object.create(null);var i={}.hasOwnProperty,c=/\s+/;return s}();void 0!==t&&t.exports?t.exports=a:"object"===l(o(0))&&o(0)?(n=[],void 0!==(r=function(){return a}.apply(e,n))&&(t.exports=r)):window.classNames=a}()},function(t,e){t.exports="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23000%7D%3C/style%3E%3C/defs%3E%3Cpath id='BR' class='cls-1' d='M0 6h7v9H0z'/%3E%3Cpath id='BL' class='cls-1' d='M8 10h7v5H8z'/%3E%3Cpath id='TR' class='cls-1' d='M0 0h7v5H0z'/%3E%3Cpath id='TL' class='cls-1' d='M8 0h7v9H8z'/%3E%3C/svg%3E"},function(t,e){t.exports="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23bbb%7D%3C/style%3E%3C/defs%3E%3Cpath id='BR' class='cls-1' d='M0 6h7v9H0z'/%3E%3Cpath id='BL' class='cls-1' d='M8 10h7v5H8z'/%3E%3Cpath id='TR' class='cls-1' d='M0 0h7v5H0z'/%3E%3Cpath id='TL' class='cls-1' d='M8 0h7v9H8z'/%3E%3C/svg%3E"}]);
assets/admin/js/mce-dropdown.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ !function(t){function i(n){if(o[n])return o[n].exports;var e=o[n]={i:n,l:!1,exports:{}};return t[n].call(e.exports,e,e.exports,i),e.l=!0,e.exports}var o={};i.m=t,i.c=o,i.d=function(t,o,n){i.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},i.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(o,"a",o),o},i.o=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},i.p="",i(i.s=5)}({5:function(t,i,o){t.exports=o(6)},6:function(t,i){/*!
2
+ * Name : Visual Portfolio
3
+ * Version : 1.4.0
4
+ * Author : nK https://nkdev.info
5
+ */
6
+ var o=window,n=o.tinymce,e=o.VPTinyMCEOptions;if(void 0!==e&&e.length){var u=[{text:"",value:""}];Object.keys(e).forEach(function(t){u.push({text:e[t].title,value:e[t].id})}),n.create("tinymce.plugins.visual_portfolio",{init:function(t){t.addButton("visual_portfolio",{type:"listbox",title:"Visual Portfolio",icon:"visual-portfolio",classes:"visual-portfolio-btn",onclick:function(){this.menu&&this.menu.$el.find(".mce-first").hide()},onselect:function(){this.value()&&t.insertContent('[visual_portfolio id="'+this.value()+'"]'),this.value("")},values:u,value:""})}}),n.PluginManager.add("visual_portfolio",n.plugins.visual_portfolio)}}});
assets/admin/js/mce-localize.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(n){function t(e){if(r[e])return r[e].exports;var o=r[e]={i:e,l:!1,exports:{}};return n[e].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};t.m=n,t.c=r,t.d=function(n,r,e){t.o(n,r)||Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:e})},t.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(r,"a",r),r},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=7)}({7:function(n,t,r){n.exports=r(8)},8:function(n,t){}});
assets/admin/js/script.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){function t(n){if(a[n])return a[n].exports;var i=a[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var a={};t.m=e,t.c=a,t.d=function(e,a,n){t.o(e,a)||Object.defineProperty(e,a,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(a,"a",a),a},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=9)}({10:function(e,t){function a(e){if(Array.isArray(e)){for(var t=0,a=Array(e.length);t<e.length;t++)a[t]=e[t];return a}return Array.from(e)}function n(){h[_.is(":checked")?"show":"hide"]()}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=jQuery,r=window,l=r.ajaxurl,c=r.VPAdminVariables,s=r.Tooltip,d=r.CodeMirror,p=r.emmetCodeMirror,v=o("body"),m=o(window),u=o('form[name="post"]'),f=o('[name="post_type"]'),g=o("#postID").val();v.on("focus",'[name="vp_list_shortcode"], [name="vp_filter_shortcode"]',function(){this.select()}),v.on("click",".vp-onclick-selection",function(){window.getSelection().selectAllChildren(this)});var h=o("#vp_format_video"),_=o("#post-format-video");h.length&&_.length&&(n(),v.on("change","[name=post_format]",function(){n()}));var y=null,b=void 0;v.on("change input",'.vp-input[name="video_url"]',function(){null!==y&&y.abort();var e=o(this);e.next(".vp-oembed-preview").html(""),clearTimeout(b),b=setTimeout(function(){y=o.ajax({url:l,method:"GET",dataType:"json",data:{action:"vp_find_oembed",q:e.val(),nonce:c.nonce},complete:function(t){var a=t.responseJSON;a&&void 0!==a.html&&e.next(".vp-oembed-preview").html(a.html)}})},250)}),void 0!==s&&o('[data-hint]:not([data-hint=""]):not([data-hint="false"])').each(function(){var e=o(this);new s(this,{placement:e.attr("data-hint-place")||"top",title:e.attr("data-hint"),container:o("body")[0],boundariesElement:"viewport"})}),function(){function e(e,t){var a=e.find('[data-image-id="'+t+'"]'),n={id:t};return a.find("[data-additional]").each(function(){var e=o(this),t=e.attr("data-additional");if(n[t]=e.html(),"true"===e.attr("data-to-json"))try{n[t]=JSON.parse(n[t])}catch(e){n[t]=""}}),n}function t(e,t){var a=e.find('[data-image-id="'+t+'"]'),n={};return a.find("[data-meta]").each(function(){n[o(this).attr("data-meta")]=o(this).html()}),n}function n(t){var a=[];t.children(".vp-control-gallery-items").find(".vp-control-gallery-items-img").each(function(){a.push(e(t,o(this).attr("data-image-id")))});var n=JSON.stringify(a),i=t.children("textarea");n!==i.val()&&i.val(n).change()}function r(n,i){var r=n.children("textarea").attr("name"),l=n.children(".vp-control-gallery-additional-data"),c=l.children(".vp-control-gallery-additional-data-preview"),s=n.children(".vp-control-gallery-items").find('.vp-control-gallery-items-img[data-image-id="'+i+'"]'),d=e(n,i),p=t(n,i);d&&Object.keys(d).forEach(function(t){var i=l.find('[name="'+r+"_additional_"+t+'"], [name="'+r+"_additional_"+t+'[]"]').val(d[t]||"");if(i.hasClass("vp-select2")){if(i.hasClass("vp-select2-tags")){var c=[],s=[];n.children(".vp-control-gallery-items").find(".vp-control-gallery-items-img").each(function(){var i=e(n,o(this).attr("data-image-id"));i&&void 0!==i[t]&&i[t]&&(c=[].concat(a(new Set([].concat(a(c),a(i[t]))))))}),c.forEach(function(e){s.push(new window.Option(e,e,!1,!1))}),i.html(s.length?s:""),i.val(void 0!==d[t]&&d[t]?d[t]:"")}i.trigger("change")}}),c.find(".vp-control-gallery-additional-data-preview-image img").attr("src",s.children("img").attr("src")||""),c.find(".vp-control-gallery-additional-data-preview-name").html(p.filename),c.find(".vp-control-gallery-additional-data-preview-size").html(p.width+"x"+p.height+" ("+p.filesizeHumanReadable+")"),c.find(".vp-control-gallery-additional-data-preview-edit a").attr("href",p.editLink.replace("&amp;","&")),s.siblings().removeClass("active"),s.addClass("active"),l.addClass("active"),S=T.find(".vp-control-gallery-additional-data.active").length}function s(e,t){if(L&&(t=!1,L=!1),c&&c.css_editor_error_notice){var a=!1;if(1===e.length?a=c.css_editor_error_notice.singular.replace("%d","1"):e.length>1&&(a=c.css_editor_error_notice.plural.replace("%d",String(e.length))),a){var n=z.prev("#vp_custom_css_notice");if(n.length||t||(n=o('<div class="notice notice-error inline" id="vp_custom_css_notice"></div>'),z.before(n)),!n.length)return;var i='<p class="notification-message">'+a+'</p><p><input id="vp_custom_css_notice_prevent" type="checkbox"><label for="vp_custom_css_notice_prevent">'+c.css_editor_error_checkbox+"</label></p>";n.html(i)}else z.prev("#vp_custom_css_notice").remove()}}if("vp_lists"===f.val()&&u.length){var h=o(".vp-content-source"),_=h.find('[name="vp_content_source"]');h.on("click",".vp-content-source__item",function(){var e=o(this).attr("data-content");h.find('[data-content="'+e+'"]').addClass("active").siblings().removeClass("active"),_.val(e).change()}),h.children('[data-content="'+_.val()+'"]').click(),o.fn.conditionize&&u.conditionize(),o(".vp-control-range").each(function(){var e=o(this).find("input"),t=e.filter('[type="hidden"]');e.on("change input",function(a){e.val(o(this).val()),t.trigger("vp-fake-"+a.type)})}),o.fn.wpColorPicker&&o(".vp-color-picker").each(function(){function e(e){if(a)return void(a=!1);clearTimeout(t),t=setTimeout(function(){o(e.target).change()},300)}var t=void 0,a=!0;o(this).data("change",e).wpColorPicker()}),o.fn.imagepicker&&o(".vp-image-picker").imagepicker();var y=o(".vp_list_preview iframe"),b=!1,w=!1,k=o('<form target="vp_list_preview_iframe" method="post" style="display: none">').attr("action",y.attr("src")).insertAfter(u);o.fn.iFrameResize&&y.iFrameResize({interval:10});var C=void 0;u.on("change input vp-fake-change vp-fake-input",'[name*="vp_"]',function(e){var t=o(this);if(!t.closest(".vp-no-reload").length){var a={name:t.attr("name"),value:t.is("[type=checkbox], [type=radio]")?t.is(":checked"):t.val(),reload:"change"===e.type||"vp-fake-change"===e.type,jQuery:w,$portfolio:b},n=k.find('[name="'+a.name+'"]');n.length||(n=o('<input type="hidden" name="'+a.name+'" />').appendTo(k)),n.attr("value",a.value),m.trigger("vp-preview-change",a),!a.reload&&b||(clearTimeout(C),C=setTimeout(function(){w=!1,b=!1,k.submit()},400))}}),y.on("load",function(){w=this.contentWindow.jQuery,b=w(".vp-portfolio")}),m.on("vp-preview-change",function(e,t){if(t.$portfolio)switch(t.name){case"vp_layout":case"vp_tiles_type":case"vp_masonry_columns":case"vp_items_gap":var a=t.name;a=a.substring(3),a=a.replace("_","-"),t.$portfolio.attr("data-vp-"+a,t.value),t.$portfolio.vp("init"),t.reload=!1;break;case"vp_filter_align":t.$portfolio.find(".vp-filter").removeClass("vp-filter__align-center vp-filter__align-left vp-filter__align-right").addClass("vp-filter__align-"+t.value),t.reload=!1;break;case"vp_pagination_align":t.$portfolio.find(".vp-pagination").removeClass("vp-pagination__align-center vp-pagination__align-left vp-pagination__align-right").addClass("vp-pagination__align-"+t.value),t.reload=!1;break;case"vp_custom_css":var n=t.$portfolio.closest("html"),i="vp-custom-css-"+g+"-inline-css",o=n.find("#"+i);o.length||(o=t.jQuery('<style id="'+i+'">'),n.find("body").prepend(o)),o.html(t.value),t.reload=!1;break;case"vp_list_name":case"vp_stretch":t.reload=!1}}),v.on("click",".vp-control-image-dropdown",function(e){o(e.target).closest(".vp-control-image-dropdown__content").length||o(this).toggleClass("active")}),v.on("mousedown",function(e){var t=o(e.target).closest(".vp-control-image-dropdown");o(".vp-control-image-dropdown.active").each(function(){this!==t[0]&&o(this).removeClass("active")})}),v.on("change",".vp-control-image-dropdown .vp-image-picker",function(){var e=o(this),t=e.data("picker");if(t){var a=t.select.find('option[value="'+t.select.val()+'"]'),n=a.parent("optgroup"),i=e.closest(".vp-control-image-dropdown"),r=a.attr("data-img-src");i.length&&(i.children(".vp-control-image-dropdown__preview").html('<img src="'+r+'" alt="">'),n.length&&i.children(".vp-control-image-dropdown__title").html(n.attr("label")))}});var x=o('[name="vp_list_name"]'),j=o('[name="post_title"]');x.length&&j.length&&(x.on("input",function(){j.val()!==x.val()&&j.val(x.val()).change()}),j.on("input",function(){x.val(j.val())})),o.fn.select2&&o(".vp-select2").each(function(){var e=o(this),t={width:"100%",minimumResultsForSearch:e.hasClass("vp-select2-nosearch")?-1:1,tags:e.hasClass("vp-select2-tags")},a=!!e.attr("data-post-type")&&o(e.attr("data-post-type"));e.closest(".vp-select2-posts-ajax").length&&(t=o.extend({minimumInputLength:1,ajax:{url:l,dataType:"json",delay:250,data:function(e){return{action:"vp_find_posts",q:e.term,post_type:!!a&&a.val(),nonce:c.nonce}},processResults:function(e){return{results:!(!e||!e.length)&&e}},cache:!0},escapeMarkup:function(e){return e},templateResult:function(e){if(e.loading)return e.text;var t="";e.title&&(t=e.title);var a="";e.post_type&&(a=e.post_type);var n="";return e.img&&(n="style=\"background-image: url('"+e.img+"');\""),'<div class="vp-select2-ajax__result"><div class="vp-select2-ajax__result-img" '+n+'></div><div class="vp-select2-ajax__result-data"><div class="vp-select2-ajax__result-title">'+t+'</div><div class="vp-select2-ajax__result-post-type">'+a+"</div></div></div>"},templateSelection:function(e){return e.title||e.text}},t)),e.closest(".vp-select2-taxonomies-ajax").length&&(t=o.extend({minimumInputLength:1,ajax:{url:l,dataType:"json",delay:250,data:function(e){return{action:"vp_find_taxonomies",q:e.term,post_type:!!a&&a.val(),nonce:c.nonce}},processResults:function(e){var t=[];return e&&Object.keys(e).forEach(function(a){t.push({text:a,children:e[a]})}),{results:t}},cache:!0}},t)),e.select2(t).data("select2").$dropdown.addClass("select2-vp-container")});var T=o(".vp-control-gallery"),S=0;if(o.fn.sortable&&(T.each(function(){var e=o(this),t=e.children(".vp-control-gallery-items-default");e.children(".vp-control-gallery-items").sortable({animation:150,draggable:".vp-control-gallery-items-img",onUpdate:function(){n(e)}}),e.on("click",".vp-control-gallery-items-remove",function(t){t.preventDefault(),o(this).parent().remove(),n(e)}),e.on("click",".vp-control-gallery-items-add",function(a){a.preventDefault();var i=e.data("wp-frame");return i?void i.open():wp.media?(i=wp.media({title:"Select or Upload Images",button:{text:"Use this images"},multiple:!0,library:{type:"image"}}),e.data("wp-frame",i),i.on("select",function(){var a=i.state().get("selection").models;a&&a.length&&(a.forEach(function(a){var n=a.changed.url;a.changed.sizes&&a.changed.sizes.thumbnail&&(n=a.changed.sizes.thumbnail.url);var i=t.children().clone();i.attr("data-image-id",a.id),i.children("img").attr("src",n),i.find('[data-meta="width"]').html(a.changed.width),i.find('[data-meta="height"]').html(a.changed.height),i.find('[data-meta="filename"]').html(a.changed.filename),i.find('[data-meta="editLink"]').html(a.changed.editLink),i.find('[data-meta="filesizeHumanReadable"]').html(a.changed.filesizeHumanReadable),e.find(".vp-control-gallery-items-add").before(i)}),n(e))}),void i.open()):void console.error("Can't access wp.media object.")}),e.on("click",".vp-control-gallery-items-img",function(t){t.preventDefault(),r(e,o(this).attr("data-image-id"))});var a=void 0;e.on("change input",".vp-control-gallery-additional-data [name]",function(){clearTimeout(a),a=setTimeout(function(){var t=e.children(".vp-control-gallery-additional-data"),a=e.children("textarea").attr("name"),r=e.children(".vp-control-gallery-items").find(".vp-control-gallery-items-img.active").attr("data-image-id");if(r){var l=e.children(".vp-control-gallery-items").find('[data-image-id="'+r+'"]');t.find('[name*="'+a+'_additional_"]').each(function(){var e=o(this).attr("name").replace(a+"_additional_","").replace("[]",""),t=o(this).val()||"";"object"===(void 0===t?"undefined":i(t))&&(t=JSON.stringify(t)),l.find('[data-additional="'+e+'"]').html(t||"")}),n(e)}},200)})}),T.length)){var E=T.children(".vp-control-gallery-additional-data");o(document).on("mousedown",function(e){if(S){var t=e.target;o(t).closest(".vp-control-gallery-additional-data, .vp-control-gallery-items-img, .select2-vp-container").length||(E.removeClass("active"),T.children(".vp-control-gallery-items").find(".vp-control-gallery-items-img.active").removeClass("active"),S=T.find(".vp-control-gallery-additional-data.active").length)}})}var z=o('[name="vp_custom_css"]'),A=!1,L=!0;if(void 0!==d&&z.length){if(c&&c.classnames){var O=d.hint.css;d.hint.css=function(e){var t=e.getCursor(),a=O(e)||{from:t,to:e.getCursor(),list:[]},n=e.getTokenAt(t);return"top"===n.state.state&&0===n.string.indexOf(".")&&(a={from:d.Pos(t.line,n.start),to:d.Pos(t.line,n.end),list:[]},c.classnames.forEach(function(e){-1!==e.indexOf(n.string)&&a.list.push(e)})),a}}var $=d.fromTextArea(z[0],{mode:"css",theme:"eclipse",indentUnit:4,autoCloseTags:!0,autoCloseBrackets:!0,matchBrackets:!0,foldGutter:!0,lint:{options:{errors:!0,"box-model":!0,"display-property-grouping":!0,"duplicate-properties":!0,"known-properties":!0,"outline-none":!0},onUpdateLinting:function(e,t,a){var n=[];e.forEach(function(e){"error"===e.severity&&n.push(e)}),a.vcLintErrors=n,A||s(a.vcLintErrors,!0)}},lineNumbers:!0,lineWrapping:!0,scrollPastEnd:!0,emmet_active:!0,emmet:!0,styleActiveLine:!0,continueComments:!0,scrollbarStyle:"simple",extraKeys:{"Ctrl-Space":"autocomplete","Ctrl-/":"toggleComment","Cmd-/":"toggleComment","Alt-F":"findPersistent"},gutters:["CodeMirror-lint-markers","CodeMirror-linenumbers","CodeMirror-foldgutter"]});p($),z.data("CodeMirrorInstance",$),$.on("change",function(){$.save(),z.change()}),$.on("keyup",function(e,t){var a=/^[a-zA-Z]$/.test(t.key);if(!e.state.completionActive||!a){var n=e.getTokenAt(e.getCursor());if("string"!==n.type&&"comment"!==n.type){var i=e.doc.getLine(e.doc.getCursor().line).substr(0,e.doc.getCursor().ch);(a||":"===t.key||" "===t.key&&/:\s+$/.test(i))&&e.showHint({completeSingle:!1})}}})}var M=!1;v.on("click","#publish:not(.disabled)",function(e){if(M=!0,!A){var t=o(this),a=z.length&&z.data("CodeMirrorInstance");a&&a.vcLintErrors&&a.vcLintErrors.length&&(e.preventDefault(),t.addClass("disabled button-disabled button-primary-disabled"),setTimeout(function(){t.removeClass("disabled button-disabled button-primary-disabled")},1500),s(a.vcLintErrors,!1),o("html,body").animate({scrollTop:o("#vp_custom_css").offset().top-100},300),a.focus(),a.setCursor(a.vcLintErrors[0].from.line))}});var P=u.serialize();o(window).on("beforeunload",function(){return M?void(M=!1):P!==u.serialize()}),v.on("change","#vp_custom_css_notice_prevent",function(){A=!0,o(this).closest(".notice").slideUp()})}}()},9:function(e,t,a){e.exports=a(10)}});
assets/admin/js/vc-frontend.min.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ !function(e){function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:o})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=11)}({11:function(e,n,t){e.exports=t(12)},12:function(e,n){/*!
2
+ * Additional js for frontend VC
3
+ *
4
+ * Name : Visual Portfolio
5
+ * Version : 1.4.0
6
+ * Author : nK https://nkdev.info
7
+ */
8
+ var t=window,o=t.vc;jQuery(function(){void 0!==o&&o.events.on("shortcodes:add shortcodeView:updated",function(e){if("visual_portfolio"===e.settings.base){var n=o.$frame[0].contentWindow,t=!!n&&n.jQuery;if(t){var r=t(e.view.el).children(".vp-portfolio");r.length&&void 0!==r.vp&&r.vp()}}})})}});
assets/css/style.min.css ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /*!
2
+ * Name : Visual Portfolio
3
+ * Version : 1.4.0
4
+ * Author : nK https://nkdev.info
5
+ */.vp-portfolio{position:relative;min-height:114px}.vp-portfolio,.vp-portfolio *{-webkit-box-sizing:border-box;box-sizing:border-box}.vp-portfolio__items{-webkit-transition:.3s height ease-in-out;transition:.3s height ease-in-out}.vp-portfolio::after,.vp-portfolio__items::after{content:"";display:block;clear:both}.vp-portfolio__items-wrap,.vp-portfolio__filter-wrap,.vp-portfolio__pagination-wrap,.vp-portfolio__item{position:relative;overflow:hidden}.vp-portfolio__items-wrap,.vp-portfolio__filter-wrap,.vp-portfolio__pagination-wrap{visibility:hidden;opacity:0;-webkit-transition:.7s opacity, .7s visibility;transition:.7s opacity, .7s visibility}.vp-portfolio__item-wrap{position:relative;float:left;width:33.333%}.vp-portfolio__item .vp-portfolio__item-img img,.vp-portfolio__item .vp-portfolio__item-img a{display:block;width:100%;height:auto}.vp-portfolio__preloader-wrap{visibility:visible;opacity:1;-webkit-transition:.7s opacity, .7s visibility;transition:.7s opacity, .7s visibility}.vp-portfolio__preloader{position:absolute;left:50%;width:23px;height:24px;margin-top:45px;margin-left:-11px;-webkit-animation:vp-preloader 2s linear infinite;animation:vp-preloader 2s linear infinite}.vp-portfolio__preloader span{position:absolute;display:block;top:0;left:0;width:10px;height:7px;background-color:#8a8a8a}.vp-portfolio__preloader span:nth-of-type(1){height:14px}.vp-portfolio__preloader span:nth-of-type(2){left:12px}.vp-portfolio__preloader span:nth-of-type(3){top:16px}.vp-portfolio__preloader span:nth-of-type(4){top:9px;left:12px;height:14px}@-webkit-keyframes vp-preloader{0%,100%{opacity:.5}40%,60%{opacity:1}}@keyframes vp-preloader{0%,100%{opacity:.5}40%,60%{opacity:1}}[data-vp-layout="tiles"] .vp-portfolio__item-img img,[data-vp-layout="tiles"] .vp-portfolio__item-img{position:absolute;top:0;right:0;bottom:0;left:0}[data-vp-layout="tiles"] .vp-portfolio__item-img-wrap{position:relative;display:block;overflow:hidden}[data-vp-layout="tiles"] .vp-portfolio__item-img-wrap::before{content:"";display:block;margin-top:56%}[data-vp-layout="tiles"] .vp-portfolio__item-img img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;-o-object-position:50% 50%;object-position:50% 50%;font-family:"object-fit: cover; object-position: 50% 50%;"}[data-vp-layout="justified"] .vp-portfolio__items{-webkit-transition:.2s height ease-in-out;transition:.2s height ease-in-out}[data-vp-layout="justified"] .vp-portfolio__item-wrap{float:left;top:0;left:0;-webkit-transition:.2s transform ease-in-out, .2s width ease-in-out, .2s height ease-in-out;transition:.2s transform ease-in-out, .2s width ease-in-out, .2s height ease-in-out}.vp-portfolio.vp-portfolio__ready{min-height:initial}.vp-portfolio.vp-portfolio__ready .vp-portfolio__items-wrap,.vp-portfolio.vp-portfolio__ready .vp-portfolio__filter-wrap,.vp-portfolio.vp-portfolio__ready .vp-portfolio__pagination-wrap{visibility:visible;opacity:1}.vp-portfolio.vp-portfolio__ready .vp-portfolio__preloader-wrap{visibility:hidden;opacity:0}.vp-portfolio.vp-portfolio__ready .vp-portfolio__preloader-wrap .vp-portfolio__preloader{-webkit-animation:none;animation:none}.vp-single-filter.vp-single-filter__ready .vp-portfolio__filter-wrap{visibility:visible;opacity:1}.vp-portfolio.vp-portfolio__loading::before{content:"";position:absolute;display:block;top:0;right:0;bottom:0;left:0;z-index:1}.vp-portfolio.vp-portfolio__loading .vp-portfolio__items-wrap,.vp-portfolio.vp-portfolio__loading .vp-portfolio__filter-wrap,.vp-portfolio.vp-portfolio__loading .vp-portfolio__pagination-wrap{opacity:.5}.vp-portfolio__item-popup{display:none}.vp-pswp{z-index:100000}.vp-pswp .pswp__caption{background-color:rgba(0,0,0,0.75)}.vp-pswp .pswp__caption>div{max-width:600px;font-size:12px;color:#fff}.vp-pswp .pswp__caption a{color:inherit}.vp-pswp .pswp__caption a:hover{opacity:.8}.vp-pswp .pswp__caption .vp-portfolio__item-meta-title{margin-top:0;margin-bottom:3px;font-size:14px;color:inherit}.vp-pswp .pswp__caption .vp-portfolio__item-meta-title a{text-decoration:none}.vp-pswp .pswp__preloader{position:absolute;right:0;bottom:0;z-index:1}.vp-pswp .vp-pswp-video{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;max-width:1920px;height:100%;margin:0 auto;line-height:0;text-align:left;vertical-align:middle;z-index:1045}.vp-pswp .vp-pswp-video>div{position:relative;width:100%;height:0;padding-bottom:56.25%}.vp-pswp .vp-pswp-video>div iframe{position:absolute;top:0;left:0;width:100%;height:100%;margin:0}.vp-pswp .vp-pswp-video>div video{width:100% !important;height:auto !important;margin:0}
assets/images/no-image.png ADDED
Binary file
assets/js/script-preview.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ !function(t){function e(n){if(o[n])return o[n].exports;var r=o[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var o={};e.m=t,e.c=o,e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=1)}([,function(t,e,o){t.exports=o(2)},function(t,e){/*!
2
+ * Name : Visual Portfolio
3
+ * Version : 1.4.0
4
+ * Author : nK https://nkdev.info
5
+ */
6
+ !function(t){var e=t("#vp_preview > .vp-portfolio");e.on("click",".vp-portfolio__item, .vp-portfolio__item a",function(t){t.preventDefault(),t.stopPropagation()}),window.iFrameResizer={heightCalculationMethod:function(){return e.outerHeight(!0)}}}(jQuery)}]);
assets/js/script.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){function e(o){if(i[o])return i[o].exports;var s=i[o]={i:o,l:!1,exports:{}};return t[o].call(s.exports,s,s.exports,e),s.l=!0,s.exports}var i={};e.m=t,e.c=i,e.d=function(t,i,o){e.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=3)}([,,,function(t,e,i){t.exports=i(4)},function(t,e){function i(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(){y=m.width(),_=m.height()}var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=function(){function t(t,e){for(var i=0;i<e.length;i++){var o=e[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,i,o){return i&&t(e.prototype,i),o&&t(e,o),e}}(),a=jQuery,p=window,l=p.VPData,d=p.objectFitImages,v=p.PhotoSwipe,f=p.PhotoSwipeUI_Default,u=l.__,c=l.settingsPopupGallery,m=a(window),y=0,_=0;s(),m.on("resize load orientationchange",s),void 0!==d&&d();var h=function(){function t(e,i){o(this,t);var s=this;s.$item=e;for(var n=e[0].className.split(/\s+/),r=0;r<n.length;r++)n[r]&&/^vp-uid-/.test(n[r])&&(s.uid=n[r].replace(/^vp-uid-/,"")),n[r]&&/^vp-id-/.test(n[r])&&(s.id=n[r].replace(/^vp-id-/,""));if(!s.uid)return void console.error(u.couldnt_retrieve_vp);s.$items_wrap=e.find(".vp-portfolio__items"),s.$pagination=e.find(".vp-portfolio__pagination-wrap"),s.$filter=e.find(".vp-portfolio__filter-wrap"),s.id&&(s.$filter=s.$filter.add(".vp-single-filter.vp-id-"+s.id+" .vp-portfolio__filter-wrap")),s.userOptions=i,s.firstRun=!0,s.init()}return r(t,[{key:"emitEvent",value:function(t,e){e=e?[this].concat(e):[this],this.$item.trigger(t+".vp.vp-uid-"+this.uid,e)}},{key:"init",value:function(){var t=this;t.firstRun||t.destroy(),t.destroyed=!1,t.initOptions(),t.initEvents(),t.initLayout(),t.initCustomColors(),t.initPhotoswipe(),t.$items_wrap.imagesLoaded(function(){t.$item.addClass("vp-portfolio__ready"),t.id&&a(".vp-single-filter.vp-id-"+t.id).addClass("vp-single-filter__ready"),t.initIsotope(),t.initFjGallery(),t.emitEvent("imagesLoaded")}),t.emitEvent("init"),t.firstRun=!1}},{key:"destroy",value:function(){var t=this;t.$item.removeClass("vp-portfolio__ready"),t.id&&a(".vp-single-filter.vp-id-"+t.id).removeClass("vp-single-filter__ready"),t.destroyEvents(),t.removeStyle(),t.renderStyle(),t.destroyPhotoswipe(),t.destroyIsotope(),t.destroyFjGallery(),t.emitEvent("destroy"),t.destroyed=!0}},{key:"addStyle",value:function(t,e,i){i=i||"";var o=this,s=o.uid;o.stylesList||(o.stylesList={}),void 0===o.stylesList[s]&&(o.stylesList[s]={}),void 0===o.stylesList[s][i]&&(o.stylesList[s][i]={}),void 0===o.stylesList[s][i][t]&&(o.stylesList[s][i][t]={}),o.stylesList[s][i][t]=a.extend(o.stylesList[s][i][t],e),o.emitEvent("addStyle",[t,e,i,o.stylesList])}},{key:"removeStyle",value:function(t,e,i){i=i||"";var o=this,s=o.uid;o.stylesList||(o.stylesList={}),void 0===o.stylesList[s]||t||(o.stylesList[s]={}),void 0!==o.stylesList[s]&&void 0!==o.stylesList[s][i]&&void 0!==o.stylesList[s][i][t]&&t&&delete o.stylesList[s][i][t],o.emitEvent("removeStyle",[t,e,o.stylesList])}},{key:"renderStyle",value:function(){var t=this,e=t.uid,i="";t.stylesList||(t.stylesList={}),void 0!==t.stylesList[e]&&Object.keys(t.stylesList[e]).forEach(function(o){o&&(i+="@media "+o+" {"),Object.keys(t.stylesList[e][o]).forEach(function(s){i+=".vp-uid-"+e+" "+s+" {",Object.keys(t.stylesList[e][o][s]).forEach(function(n){i+=n+":"+t.stylesList[e][o][s][n]+";"}),i+="}"}),o&&(i+="}")});var o=a("#vp-style-"+e);o.length||(o=a("<style>").attr("id","vp-style-"+e).appendTo("head")),o.html(i),t.emitEvent("renderStyle",[i,t.stylesList,o])}},{key:"firstToLowerCase",value:function(t){return t.substr(0,1).toLowerCase()+t.substr(1)}},{key:"initOptions",value:function(t){var e=this;e.defaults={layout:"tile",itemsGap:0,tilesType:"3|1,1|",masonryColumns:3,justifiedRowHeight:250,justifiedRowHeightTolerance:.25,pagination:"load-more"},t&&(e.userOptions=t);var i=e.$item[0].dataset,o={};Object.keys(i).forEach(function(t){t&&"vp"===t.substring(0,2)&&(o[e.firstToLowerCase(t.substring(2))]=i[t])}),e.options=a.extend({},e.defaults,o,e.userOptions),e.emitEvent("initOptions")}},{key:"isCrossLine",value:function(t,e,i,o){var s=(o.x-i.x)*(t.y-i.y)-(o.y-i.y)*(t.x-i.x),n=(o.x-i.x)*(e.y-i.y)-(o.y-i.y)*(e.x-i.x),r=(e.x-t.x)*(i.y-t.y)-(e.y-t.y)*(i.x-t.x),a=(e.x-t.x)*(o.y-t.y)-(e.y-t.y)*(o.x-t.x);return s*n<=0&&r*a<=0}},{key:"initEvents",value:function(){function t(){var t=i.$item[0].getBoundingClientRect(),e=t.left,o=y-t.right,s=parseFloat(i.$item.css("margin-left")||0),n=parseFloat(i.$item.css("margin-right")||0);i.$item.css({"margin-left":s-e,"margin-right":n-o})}function e(){var t=i.$item[0].getBoundingClientRect();t.bottom>0&&t.bottom-r<=_&&i.loadNewItems(i.options.nextPageUrl,!1,function(){e()})}var i=this,o=".vp.vp-uid-"+i.uid;if(i.$item.hasClass("vp-portfolio__stretch")&&(m.on("load"+o+" resize"+o+" orientationchange"+o,function(){t()}),t()),"fly"===i.options.itemsStyle){var s={};m.on("mousemove"+o,function(t){s={x:t.clientX,y:t.clientY}}),i.$item.on("mouseenter"+o+" mouseleave"+o,".vp-portfolio__item",function(t){var e=a(this),o=e[0].getBoundingClientRect(),n=e.find(".vp-portfolio__item-overlay"),r="mouseenter"===t.type,p="0%",l="0%",d={x:t.clientX,y:t.clientY},v=i.isCrossLine({x:o.left,y:o.top},{x:o.left+o.width,y:o.top},d,s),f=i.isCrossLine({x:o.left,y:o.top+o.height},{x:o.left+o.width,y:o.top+o.height},d,s),u=i.isCrossLine({x:o.left,y:o.top},{x:o.left,y:o.top+o.height},d,s),c=i.isCrossLine({x:o.left+o.width,y:o.top},{x:o.left+o.width,y:o.top+o.height},d,s);if(!(v||f||u||c)){var m=(o.width/2-d.x+o.left)/(o.width/2),y=(o.height/2-d.y+o.top)/(o.height/2);Math.abs(m)>Math.abs(y)?m>0?u=!0:c=!0:y>0?v=!0:f=!0}v?l="-10"+l:f?l="10"+l:u?p="-10"+p:c&&(p="10"+p),r&&(n.css({transition:"none",transform:"translateX("+p+") translateY("+l+") translateZ(0)"}),n[0].offsetHeight),n.css({transition:".2s transform ease-in-out",transform:"translateX("+(r?"0%":p)+") translateY("+(r?"0%":l)+") translateZ(0)"})})}i.$filter.on("click"+o,".vp-filter .vp-filter__item a",function(t){t.preventDefault();var e=a(this);i.loading||e.closest(".vp-filter__item").addClass("vp-filter__item-active").siblings().removeClass("vp-filter__item-active"),i.loadNewItems(e.attr("href"),!0)}),i.$item.on("click"+o,".vp-pagination .vp-pagination__item a",function(t){t.preventDefault();var e=a(this);e.hasClass("vp-pagination__no-more")&&"paged"!==i.options.pagination||i.loadNewItems(e.attr("href"),"paged"===i.options.pagination)}),i.$item.on("click"+o,".vp-portfolio__items .vp-portfolio__item-meta-category a",function(t){t.preventDefault(),t.stopPropagation(),i.loadNewItems(a(this).attr("href"),!0)});var n=void 0,r=250;"infinite"===i.options.pagination&&(m.on("load"+o+" scroll"+o+" resize"+o+" orientationchange"+o,function(){clearTimeout(n),n=setTimeout(function(){e()},60)}),e()),i.emitEvent("initEvents")}},{key:"destroyEvents",value:function(){var t=this,e=".vp.vp-uid-"+t.uid;t.$item.off(e),t.$filter.off(e),m.off(e),t.emitEvent("destroyEvents")}},{key:"getTilesSettings",value:function(){var t=this,e=t.options.tilesType.split(/[:|]/);return void 0===e[e.length-1]||e[e.length-1]||e.pop(),e}},{key:"initLayout",value:function(){var t=this,e=[576,768,992,1200];if(t.options.layout)switch(t.options.layout){case"tiles":var i=t.getTilesSettings(),o=parseInt(i[0],10)||1;if(i.shift(),t.addStyle(".vp-portfolio__item-wrap",{width:100/o+"%"}),i&&i.length)for(var s=0;s<i.length;s++){var n=i[s].split(","),r=parseFloat(n[0])||1,a=parseFloat(n[1])||1,p=".vp-portfolio__item-wrap";i.length>1&&(p+=":nth-of-type("+i.length+"n+"+(s+1)+")"),r&&1!==r&&t.addStyle(p,{width:100*r/o+"%"}),t.addStyle(p+" .vp-portfolio__item-img-wrap:before",{"margin-top":100*a+"%"})}for(var l=o;l>0;l--)void 0!==e[l-1]&&(t.addStyle(".vp-portfolio__item-wrap",{width:100/l+"%"},"screen and (max-width: "+e[l-1]+"px)"),t.addStyle(".vp-portfolio__item-wrap:nth-of-type(n)",{width:100/l+"%"},"screen and (max-width: "+e[l-1]+"px)"));break;case"masonry":t.addStyle(".vp-portfolio__item-wrap",{width:100/t.options.masonryColumns+"%"});for(var d=t.options.masonryColumns;d>0;d--)void 0!==e[d-1]&&t.addStyle(".vp-portfolio__item-wrap",{width:100/d+"%"},"screen and (max-width: "+e[d-1]+"px)")}var v=parseInt(t.options.itemsGap,10);if(v&&("tiles"===t.options.layout||"masonry"===t.options.layout)){t.addStyle(".vp-portfolio__items",{"margin-left":"-"+v+"px","margin-top":"-"+v+"px"});var f=v+"px";t.addStyle(".vp-portfolio__item-wrap .vp-portfolio__item",{"margin-left":f,"margin-top":f}),"tiles"===t.options.layout&&(t.addStyle(".vp-portfolio__item-wrap .vp-portfolio__item-img-wrap",{"margin-left":"-"+f,"margin-top":"-"+f}),t.addStyle(".vp-portfolio__item-wrap .vp-portfolio__item-img",{left:f,top:f}))}t.renderStyle(),t.emitEvent("initLayout")}},{key:"initCustomColors",value:function(){var t=this;t.$item.find("[data-vp-bg-color]").each(function(){var e=a(this).attr("data-vp-bg-color");t.addStyle('[data-vp-bg-color="'+e+'"]',{"background-color":e+" !important"})}),t.$item.find("[data-vp-text-color]").each(function(){var e=a(this).attr("data-vp-text-color");t.addStyle('[data-vp-text-color="'+e+'"]',{color:e+" !important"})}),t.renderStyle(),t.emitEvent("initCustomColors")}},{key:"initIsotope",value:function(t){var e=this;"tiles"!==e.options.layout&&"masonry"!==e.options.layout||(e.$items_wrap.isotope(t||{itemSelector:".vp-portfolio__item-wrap",layoutMode:"masonry",transitionDuration:"0.3s",percentPosition:!0}),e.emitEvent("initIsotope",[t]))}},{key:"destroyIsotope",value:function(){var t=this;t.$items_wrap.data("isotope")&&(t.$items_wrap.isotope("destroy"),t.emitEvent("destroyIsotope"))}},{key:"initFjGallery",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=this;"justified"===i.options.layout&&(i.$items_wrap.fjGallery(!1!==t?t:{gutter:parseFloat(i.options.itemsGap)||0,rowHeight:parseFloat(i.options.justifiedRowHeight)||200,rowHeightTolerance:parseFloat(i.options.justifiedRowHeightTolerance)||0,itemSelector:".vp-portfolio__item-wrap",imageSelector:".vp-portfolio__item-img img"},e),i.emitEvent("initFjGallery"))}},{key:"destroyFjGallery",value:function(){var t=this;t.$items_wrap.fjGallery&&(t.$items_wrap.fjGallery("destroy"),t.emitEvent("destroyFjGallery"))}},{key:"initPhotoswipe",value:function(){function t(e,i){if(void 0===i)return void(e&&e.itemHolders.length&&e.itemHolders.forEach(function(i){i.item&&i.item.html&&t(e,i.item)}));var o=e.viewportSize.x*window.devicePixelRatio,s=e.viewportSize.y*window.devicePixelRatio,n=i.vw/i.vh,r=void 0,p=a(i.container),l=e.options.barsSize,d=0,v=0;l&&(d=l.top&&"auto"!==l.top?l.top:0,v=l.bottom&&"auto"!==l.bottom?l.bottom:0),s-=d+v,r=n>o/s?o:s*n,p.find(".vp-pswp-video").css("max-width",r),p.css({top:d,bottom:v})}var e=this;if(void 0!==v&&e.options.itemsClickAction&&"popup_gallery"===e.options.itemsClickAction&&!e.$item.closest("#vp_preview").length){if(!a(".vp-pswp").length){var i="\n <div class=\"pswp vp-pswp vp-pswp-uid-'}"+e.uid+'" tabindex="-1" role="dialog" aria-hidden="true">\n <div class="pswp__bg"></div>\n <div class="pswp__scroll-wrap">\n <div class="pswp__container">\n <div class="pswp__item"></div>\n <div class="pswp__item"></div>\n <div class="pswp__item"></div>\n </div>\n <div class="pswp__ui pswp__ui--hidden">\n <div class="pswp__top-bar">\n <div class="pswp__counter"></div>\n <a class="pswp__button pswp__button--close" title="'+u.pswp_close+'"></a>\n <a class="pswp__button pswp__button--share" title="'+u.pswp_share+'"></a>\n <a class="pswp__button pswp__button--fs" title="'+u.pswp_fs+'"></a>\n <a class="pswp__button pswp__button--zoom" title="'+u.pswp_zoom+'"></a>\n </div>\n <div class="pswp__preloader">\n <div class="pswp__preloader__icn">\n <div class="pswp__preloader__cut">\n <div class="pswp__preloader__donut"></div>\n </div>\n </div>\n </div>\n <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">\n <div class="pswp__share-tooltip"></div>\n </div>\n <a class="pswp__button pswp__button--arrow--left" title="'+u.pswp_prev+'"></a>\n <a class="pswp__button pswp__button--arrow--right" title="'+u.pswp_next+'"></a>\n <div class="pswp__caption">\n <div class="pswp__caption__center"></div>\n </div>\n </div>\n </div>\n </div>\n ';a("body").append(i)}var o=function(t){var e=a(t).find(".vp-portfolio__item-wrap"),i=[],o=void 0,s=void 0,n=void 0,r=void 0,p=void 0;return e.each(function(){if(o=a(this).find(".vp-portfolio__item-popup"),s=(o.attr("data-vp-popup-img-size")||"1920x1080").split("x"),n=(o.attr("data-vp-popup-video-size")||"1920x1080").split("x"),p=o.attr("data-vp-popup-video"))r={html:p,vw:parseInt(n[0],10),vh:parseInt(n[1],10)};else{r={src:o.attr("data-vp-popup-img"),w:parseInt(s[0],10),h:parseInt(s[1],10)};var t=o.html();t&&(r.title=t),r.el=this;var e=o.attr("data-vp-popup-md-img")||r.src;e&&(s=(o.attr("data-vp-popup-md-img-size")||o.attr("data-vp-popup-img-size")||"1920x1080").split("x"),r.m={src:e,w:parseInt(s[0],10),h:parseInt(s[1],10)}),r.o={src:r.src,w:r.w,h:r.h}}i.push(r)}),i},s=function(i,s,n,r){var p=a(".vp-pswp")[0],l=o(s),d={captionAndToolbarShowEmptyCaptions:!1,closeEl:c.show_close_button,captionEl:c.show_caption,fullscreenEl:c.show_fullscreen_button,zoomEl:c.show_zoom_button,shareEl:c.show_share_button,counterEl:c.show_counter,arrowEl:c.show_arrows,shareButtons:[{id:"facebook",label:u.pswp_share_fb,url:"https://www.facebook.com/sharer/sharer.php?u={{url}}"},{id:"twitter",label:u.pswp_share_tw,url:"https://twitter.com/intent/tweet?text={{text}}&url={{url}}"},{id:"pinterest",label:u.pswp_share_pin,url:"https://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}"}],bgOpacity:1,tapToClose:!0,tapToToggleControls:!1,showHideOpacity:!0,galleryUID:e.uid};if(r)if(d.galleryPIDs){for(var m=0;m<l.length;m++)if(l[m].pid===i){d.index=m;break}}else d.index=parseInt(i,10)-1;else d.index=parseInt(i,10);if(!Number.isNaN(d.index)){n&&(d.showAnimationDuration=0);var y=new v(p,f,l,d),_=void 0,h=!1,w=!0,g=void 0;y.listen("beforeResize",function(){_=y.viewportSize.x*window.devicePixelRatio,h&&_<1e3?(h=!1,g=!0):!h&&_>=1e3&&(h=!0,g=!0),g&&!w&&y.invalidateCurrItems(),w&&(w=!1),g=!1}),y.listen("gettingData",function(t,e){e.html||(h?(e.src=e.o.src,e.w=e.o.w,e.h=e.o.h):(e.src=e.m.src,e.w=e.m.w,e.h=e.m.h))}),y.listen("resize",function(){t(this)}),y.listen("afterChange",function(){t(this)}),y.listen("destroy",function(){var t=this;t&&t.itemHolders.length&&t.itemHolders.forEach(function(t){t.el&&a(t.el).find(".vp-pswp-video").remove()})}),y.init()}};e.$item.on("click.vp.vp-uid-"+e.uid,".vp-portfolio__item",function(t){t.preventDefault();var i=0,o=this;e.$item.find(".vp-portfolio__item").each(function(t){return this!==o||(i=t,!1)}),s(i,e.$item[0])});var n=function(){var t=window.location.hash.substring(1),e={};if(t.length<5)return e;for(var i=t.split("&"),o=0;o<i.length;o++)if(i[o]){var s=i[o].split("=");s.length<2||(e[s[0]]=s[1])}return e}();n.pid&&n.gid===e.uid&&s(n.pid,e.$item[0],!0,!0)}}},{key:"destroyPhotoswipe",value:function(){var t=this;t.$item.off("click.vp.vp-uid-"+t.uid),a(".vp-pswp-uid-"+t.uid).remove()}},{key:"addItems",value:function(t,e){var i=this,o=i.$items_wrap.data("isotope"),s=i.$items_wrap.fjGallery;if(o){if(e){var n=i.$items_wrap.find(".vp-portfolio__item-wrap");i.$items_wrap.isotope("remove",n),i.$items_wrap.prepend(t).isotope("prepended",t)}else i.$items_wrap.append(t).isotope("appended",t);i.$items_wrap.imagesLoaded(function(){i.initIsotope("layout")})}s&&(e?(i.destroyFjGallery(),i.$items_wrap.find(".vp-portfolio__item-wrap").remove(),i.$items_wrap.prepend(t),i.initFjGallery()):(i.$items_wrap.append(t),i.initFjGallery("appendImages",t))),i.emitEvent("addItems",[t,e])}},{key:"removeItems",value:function(t){var e=this;e.$items_wrap.data("isotope")&&e.$items_wrap.isotope("remove",t),e.emitEvent("removeItems",[t])}},{key:"loadNewItems",value:function(t,e,i){var o=this;!o.loading&&t&&(o.loading=!0,o.$item.addClass("vp-portfolio__loading"),o.emitEvent("startLoadingNewItems",[t]),a.get(t,{},function(t){t=t.replace("<body",'<body><div id="vp-infinite-load-body"').replace("</body>","</div></body>");var s=a(t).filter("#vp-infinite-load-body"),n=s.find(".vp-portfolio.vp-uid-"+o.uid);if(n.length){var r=n.find(".vp-portfolio__items").html();o.$filter.length&&o.$filter.each(function(){var t=a(this),e="";e=t.parent().hasClass("vp-single-filter")?s.find('[class="'+t.parent().attr("class").replace(" vp-single-filter__ready","")+'"] .vp-portfolio__filter-wrap').html():n.find(".vp-portfolio__filter-wrap").html(),t.html(e)}),o.$pagination.length&&o.$pagination.html(n.find(".vp-portfolio__pagination-wrap").html()),o.addItems(a(r),e),o.emitEvent("loadedNewItems",[n,n,t])}var p=n.attr("data-vp-next-page-url");o.options.nextPageUrl=p,o.$item.attr("data-vp-next-page-url",p),o.$item.removeClass("vp-portfolio__loading"),o.loading=!1,o.emitEvent("endLoadingNewItems"),o.initCustomColors(),i&&i()}))}}]),t}(),w=function(t){var e=Array.prototype.slice.call(arguments,1),o=void 0;return this.each(function(){if(void 0===o)if("object"===(void 0===t?"undefined":n(t))||void 0===t)this.vp||(this.vp=new h(a(this),t));else if(this.vp){var s;o=(s=this.vp)[t].apply(s,i(e))}}),void 0!==o?o:this};w.constructor=h;var g=jQuery.fn.vp;jQuery.fn.vp=w,jQuery.fn.vp.noConflict=function(){return jQuery.fn.vp=g,this},a(function(){a(".vp-portfolio").vp()})}]);
assets/vendor/codemirror/addon/comment/comment.js ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ var noOptions = {};
15
+ var nonWS = /[^\s\u00a0]/;
16
+ var Pos = CodeMirror.Pos;
17
+
18
+ function firstNonWS(str) {
19
+ var found = str.search(nonWS);
20
+ return found == -1 ? 0 : found;
21
+ }
22
+
23
+ CodeMirror.commands.toggleComment = function(cm) {
24
+ cm.toggleComment();
25
+ };
26
+
27
+ CodeMirror.defineExtension("toggleComment", function(options) {
28
+ if (!options) options = noOptions;
29
+ var cm = this;
30
+ var minLine = Infinity, ranges = this.listSelections(), mode = null;
31
+ for (var i = ranges.length - 1; i >= 0; i--) {
32
+ var from = ranges[i].from(), to = ranges[i].to();
33
+ if (from.line >= minLine) continue;
34
+ if (to.line >= minLine) to = Pos(minLine, 0);
35
+ minLine = from.line;
36
+ if (mode == null) {
37
+ if (cm.uncomment(from, to, options)) mode = "un";
38
+ else { cm.lineComment(from, to, options); mode = "line"; }
39
+ } else if (mode == "un") {
40
+ cm.uncomment(from, to, options);
41
+ } else {
42
+ cm.lineComment(from, to, options);
43
+ }
44
+ }
45
+ });
46
+
47
+ // Rough heuristic to try and detect lines that are part of multi-line string
48
+ function probablyInsideString(cm, pos, line) {
49
+ return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
50
+ }
51
+
52
+ function getMode(cm, pos) {
53
+ var mode = cm.getMode()
54
+ return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
55
+ }
56
+
57
+ CodeMirror.defineExtension("lineComment", function(from, to, options) {
58
+ if (!options) options = noOptions;
59
+ var self = this, mode = getMode(self, from);
60
+ var firstLine = self.getLine(from.line);
61
+ if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
62
+
63
+ var commentString = options.lineComment || mode.lineComment;
64
+ if (!commentString) {
65
+ if (options.blockCommentStart || mode.blockCommentStart) {
66
+ options.fullLines = true;
67
+ self.blockComment(from, to, options);
68
+ }
69
+ return;
70
+ }
71
+
72
+ var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
73
+ var pad = options.padding == null ? " " : options.padding;
74
+ var blankLines = options.commentBlankLines || from.line == to.line;
75
+
76
+ self.operation(function() {
77
+ if (options.indent) {
78
+ var baseString = null;
79
+ for (var i = from.line; i < end; ++i) {
80
+ var line = self.getLine(i);
81
+ var whitespace = line.slice(0, firstNonWS(line));
82
+ if (baseString == null || baseString.length > whitespace.length) {
83
+ baseString = whitespace;
84
+ }
85
+ }
86
+ for (var i = from.line; i < end; ++i) {
87
+ var line = self.getLine(i), cut = baseString.length;
88
+ if (!blankLines && !nonWS.test(line)) continue;
89
+ if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
90
+ self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
91
+ }
92
+ } else {
93
+ for (var i = from.line; i < end; ++i) {
94
+ if (blankLines || nonWS.test(self.getLine(i)))
95
+ self.replaceRange(commentString + pad, Pos(i, 0));
96
+ }
97
+ }
98
+ });
99
+ });
100
+
101
+ CodeMirror.defineExtension("blockComment", function(from, to, options) {
102
+ if (!options) options = noOptions;
103
+ var self = this, mode = getMode(self, from);
104
+ var startString = options.blockCommentStart || mode.blockCommentStart;
105
+ var endString = options.blockCommentEnd || mode.blockCommentEnd;
106
+ if (!startString || !endString) {
107
+ if ((options.lineComment || mode.lineComment) && options.fullLines != false)
108
+ self.lineComment(from, to, options);
109
+ return;
110
+ }
111
+ if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
112
+
113
+ var end = Math.min(to.line, self.lastLine());
114
+ if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
115
+
116
+ var pad = options.padding == null ? " " : options.padding;
117
+ if (from.line > end) return;
118
+
119
+ self.operation(function() {
120
+ if (options.fullLines != false) {
121
+ var lastLineHasText = nonWS.test(self.getLine(end));
122
+ self.replaceRange(pad + endString, Pos(end));
123
+ self.replaceRange(startString + pad, Pos(from.line, 0));
124
+ var lead = options.blockCommentLead || mode.blockCommentLead;
125
+ if (lead != null) for (var i = from.line + 1; i <= end; ++i)
126
+ if (i != end || lastLineHasText)
127
+ self.replaceRange(lead + pad, Pos(i, 0));
128
+ } else {
129
+ self.replaceRange(endString, to);
130
+ self.replaceRange(startString, from);
131
+ }
132
+ });
133
+ });
134
+
135
+ CodeMirror.defineExtension("uncomment", function(from, to, options) {
136
+ if (!options) options = noOptions;
137
+ var self = this, mode = getMode(self, from);
138
+ var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
139
+
140
+ // Try finding line comments
141
+ var lineString = options.lineComment || mode.lineComment, lines = [];
142
+ var pad = options.padding == null ? " " : options.padding, didSomething;
143
+ lineComment: {
144
+ if (!lineString) break lineComment;
145
+ for (var i = start; i <= end; ++i) {
146
+ var line = self.getLine(i);
147
+ var found = line.indexOf(lineString);
148
+ if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
149
+ if (found == -1 && nonWS.test(line)) break lineComment;
150
+ if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
151
+ lines.push(line);
152
+ }
153
+ self.operation(function() {
154
+ for (var i = start; i <= end; ++i) {
155
+ var line = lines[i - start];
156
+ var pos = line.indexOf(lineString), endPos = pos + lineString.length;
157
+ if (pos < 0) continue;
158
+ if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
159
+ didSomething = true;
160
+ self.replaceRange("", Pos(i, pos), Pos(i, endPos));
161
+ }
162
+ });
163
+ if (didSomething) return true;
164
+ }
165
+
166
+ // Try block comments
167
+ var startString = options.blockCommentStart || mode.blockCommentStart;
168
+ var endString = options.blockCommentEnd || mode.blockCommentEnd;
169
+ if (!startString || !endString) return false;
170
+ var lead = options.blockCommentLead || mode.blockCommentLead;
171
+ var startLine = self.getLine(start), open = startLine.indexOf(startString)
172
+ if (open == -1) return false
173
+ var endLine = end == start ? startLine : self.getLine(end)
174
+ var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
175
+ var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
176
+ if (close == -1 ||
177
+ !/comment/.test(self.getTokenTypeAt(insideStart)) ||
178
+ !/comment/.test(self.getTokenTypeAt(insideEnd)) ||
179
+ self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
180
+ return false;
181
+
182
+ // Avoid killing block comments completely outside the selection.
183
+ // Positions of the last startString before the start of the selection, and the first endString after it.
184
+ var lastStart = startLine.lastIndexOf(startString, from.ch);
185
+ var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
186
+ if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
187
+ // Positions of the first endString after the end of the selection, and the last startString before it.
188
+ firstEnd = endLine.indexOf(endString, to.ch);
189
+ var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
190
+ lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
191
+ if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
192
+
193
+ self.operation(function() {
194
+ self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
195
+ Pos(end, close + endString.length));
196
+ var openEnd = open + startString.length;
197
+ if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
198
+ self.replaceRange("", Pos(start, open), Pos(start, openEnd));
199
+ if (lead) for (var i = start + 1; i <= end; ++i) {
200
+ var line = self.getLine(i), found = line.indexOf(lead);
201
+ if (found == -1 || nonWS.test(line.slice(0, found))) continue;
202
+ var foundEnd = found + lead.length;
203
+ if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
204
+ self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
205
+ }
206
+ });
207
+ return true;
208
+ });
209
+ });
assets/vendor/codemirror/addon/comment/continuecomment.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ function continueComment(cm) {
13
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
14
+ var ranges = cm.listSelections(), mode, inserts = [];
15
+ for (var i = 0; i < ranges.length; i++) {
16
+ var pos = ranges[i].head
17
+ if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass;
18
+ var modeHere = cm.getModeAt(pos)
19
+ if (!mode) mode = modeHere;
20
+ else if (mode != modeHere) return CodeMirror.Pass;
21
+
22
+ var insert = null;
23
+ if (mode.blockCommentStart && mode.blockCommentContinue) {
24
+ var line = cm.getLine(pos.line).slice(0, pos.ch)
25
+ var end = line.lastIndexOf(mode.blockCommentEnd), found
26
+ if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) {
27
+ // Comment ended, don't continue it
28
+ } else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) {
29
+ insert = line.slice(0, found)
30
+ if (/\S/.test(insert)) {
31
+ insert = ""
32
+ for (var j = 0; j < found; ++j) insert += " "
33
+ }
34
+ } else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && !/\S/.test(line.slice(0, found))) {
35
+ insert = line.slice(0, found)
36
+ }
37
+ if (insert != null) insert += mode.blockCommentContinue
38
+ }
39
+ if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
40
+ var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
41
+ if (found > -1) {
42
+ insert = line.slice(0, found);
43
+ if (/\S/.test(insert)) insert = null;
44
+ else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
45
+ }
46
+ }
47
+ if (insert == null) return CodeMirror.Pass;
48
+ inserts[i] = "\n" + insert;
49
+ }
50
+
51
+ cm.operation(function() {
52
+ for (var i = ranges.length - 1; i >= 0; i--)
53
+ cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
54
+ });
55
+ }
56
+
57
+ function continueLineCommentEnabled(cm) {
58
+ var opt = cm.getOption("continueComments");
59
+ if (opt && typeof opt == "object")
60
+ return opt.continueLineComment !== false;
61
+ return true;
62
+ }
63
+
64
+ CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
65
+ if (prev && prev != CodeMirror.Init)
66
+ cm.removeKeyMap("continueComment");
67
+ if (val) {
68
+ var key = "Enter";
69
+ if (typeof val == "string")
70
+ key = val;
71
+ else if (typeof val == "object" && val.key)
72
+ key = val.key;
73
+ var map = {name: "continueComment"};
74
+ map[key] = continueComment;
75
+ cm.addKeyMap(map);
76
+ }
77
+ });
78
+ });
assets/vendor/codemirror/addon/dialog/dialog.css ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .CodeMirror-dialog {
2
+ position: absolute;
3
+ left: 0; right: 0;
4
+ background: inherit;
5
+ z-index: 15;
6
+ padding: .1em .8em;
7
+ overflow: hidden;
8
+ color: inherit;
9
+ }
10
+
11
+ .CodeMirror-dialog-top {
12
+ border-bottom: 1px solid #eee;
13
+ top: 0;
14
+ }
15
+
16
+ .CodeMirror-dialog-bottom {
17
+ border-top: 1px solid #eee;
18
+ bottom: 0;
19
+ }
20
+
21
+ .CodeMirror-dialog input {
22
+ border: none;
23
+ outline: none;
24
+ background: transparent;
25
+ width: 20em;
26
+ color: inherit;
27
+ font-family: monospace;
28
+ }
29
+
30
+ .CodeMirror-dialog button {
31
+ font-size: 70%;
32
+ }
assets/vendor/codemirror/addon/dialog/dialog.js ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // Open simple dialogs on top of an editor. Relies on dialog.css.
5
+
6
+ (function(mod) {
7
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
8
+ mod(require("../../lib/codemirror"));
9
+ else if (typeof define == "function" && define.amd) // AMD
10
+ define(["../../lib/codemirror"], mod);
11
+ else // Plain browser env
12
+ mod(CodeMirror);
13
+ })(function(CodeMirror) {
14
+ function dialogDiv(cm, template, bottom) {
15
+ var wrap = cm.getWrapperElement();
16
+ var dialog;
17
+ dialog = wrap.appendChild(document.createElement("div"));
18
+ if (bottom)
19
+ dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
20
+ else
21
+ dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
22
+
23
+ if (typeof template == "string") {
24
+ dialog.innerHTML = template;
25
+ } else { // Assuming it's a detached DOM element.
26
+ dialog.appendChild(template);
27
+ }
28
+ CodeMirror.addClass(wrap, 'dialog-opened');
29
+ return dialog;
30
+ }
31
+
32
+ function closeNotification(cm, newVal) {
33
+ if (cm.state.currentNotificationClose)
34
+ cm.state.currentNotificationClose();
35
+ cm.state.currentNotificationClose = newVal;
36
+ }
37
+
38
+ CodeMirror.defineExtension("openDialog", function(template, callback, options) {
39
+ if (!options) options = {};
40
+
41
+ closeNotification(this, null);
42
+
43
+ var dialog = dialogDiv(this, template, options.bottom);
44
+ var closed = false, me = this;
45
+ function close(newVal) {
46
+ if (typeof newVal == 'string') {
47
+ inp.value = newVal;
48
+ } else {
49
+ if (closed) return;
50
+ closed = true;
51
+ CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
52
+ dialog.parentNode.removeChild(dialog);
53
+ me.focus();
54
+
55
+ if (options.onClose) options.onClose(dialog);
56
+ }
57
+ }
58
+
59
+ var inp = dialog.getElementsByTagName("input")[0], button;
60
+ if (inp) {
61
+ inp.focus();
62
+
63
+ if (options.value) {
64
+ inp.value = options.value;
65
+ if (options.selectValueOnOpen !== false) {
66
+ inp.select();
67
+ }
68
+ }
69
+
70
+ if (options.onInput)
71
+ CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
72
+ if (options.onKeyUp)
73
+ CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
74
+
75
+ CodeMirror.on(inp, "keydown", function(e) {
76
+ if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
77
+ if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
78
+ inp.blur();
79
+ CodeMirror.e_stop(e);
80
+ close();
81
+ }
82
+ if (e.keyCode == 13) callback(inp.value, e);
83
+ });
84
+
85
+ if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
86
+ } else if (button = dialog.getElementsByTagName("button")[0]) {
87
+ CodeMirror.on(button, "click", function() {
88
+ close();
89
+ me.focus();
90
+ });
91
+
92
+ if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
93
+
94
+ button.focus();
95
+ }
96
+ return close;
97
+ });
98
+
99
+ CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
100
+ closeNotification(this, null);
101
+ var dialog = dialogDiv(this, template, options && options.bottom);
102
+ var buttons = dialog.getElementsByTagName("button");
103
+ var closed = false, me = this, blurring = 1;
104
+ function close() {
105
+ if (closed) return;
106
+ closed = true;
107
+ CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
108
+ dialog.parentNode.removeChild(dialog);
109
+ me.focus();
110
+ }
111
+ buttons[0].focus();
112
+ for (var i = 0; i < buttons.length; ++i) {
113
+ var b = buttons[i];
114
+ (function(callback) {
115
+ CodeMirror.on(b, "click", function(e) {
116
+ CodeMirror.e_preventDefault(e);
117
+ close();
118
+ if (callback) callback(me);
119
+ });
120
+ })(callbacks[i]);
121
+ CodeMirror.on(b, "blur", function() {
122
+ --blurring;
123
+ setTimeout(function() { if (blurring <= 0) close(); }, 200);
124
+ });
125
+ CodeMirror.on(b, "focus", function() { ++blurring; });
126
+ }
127
+ });
128
+
129
+ /*
130
+ * openNotification
131
+ * Opens a notification, that can be closed with an optional timer
132
+ * (default 5000ms timer) and always closes on click.
133
+ *
134
+ * If a notification is opened while another is opened, it will close the
135
+ * currently opened one and open the new one immediately.
136
+ */
137
+ CodeMirror.defineExtension("openNotification", function(template, options) {
138
+ closeNotification(this, close);
139
+ var dialog = dialogDiv(this, template, options && options.bottom);
140
+ var closed = false, doneTimer;
141
+ var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
142
+
143
+ function close() {
144
+ if (closed) return;
145
+ closed = true;
146
+ clearTimeout(doneTimer);
147
+ CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
148
+ dialog.parentNode.removeChild(dialog);
149
+ }
150
+
151
+ CodeMirror.on(dialog, 'click', function(e) {
152
+ CodeMirror.e_preventDefault(e);
153
+ close();
154
+ });
155
+
156
+ if (duration)
157
+ doneTimer = setTimeout(close, duration);
158
+
159
+ return close;
160
+ });
161
+ });
assets/vendor/codemirror/addon/edit/closebrackets.js ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ var defaults = {
13
+ pairs: "()[]{}''\"\"",
14
+ triples: "",
15
+ explode: "[]{}"
16
+ };
17
+
18
+ var Pos = CodeMirror.Pos;
19
+
20
+ CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
21
+ if (old && old != CodeMirror.Init) {
22
+ cm.removeKeyMap(keyMap);
23
+ cm.state.closeBrackets = null;
24
+ }
25
+ if (val) {
26
+ ensureBound(getOption(val, "pairs"))
27
+ cm.state.closeBrackets = val;
28
+ cm.addKeyMap(keyMap);
29
+ }
30
+ });
31
+
32
+ function getOption(conf, name) {
33
+ if (name == "pairs" && typeof conf == "string") return conf;
34
+ if (typeof conf == "object" && conf[name] != null) return conf[name];
35
+ return defaults[name];
36
+ }
37
+
38
+ var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
39
+ function ensureBound(chars) {
40
+ for (var i = 0; i < chars.length; i++) {
41
+ var ch = chars.charAt(i), key = "'" + ch + "'"
42
+ if (!keyMap[key]) keyMap[key] = handler(ch)
43
+ }
44
+ }
45
+ ensureBound(defaults.pairs + "`")
46
+
47
+ function handler(ch) {
48
+ return function(cm) { return handleChar(cm, ch); };
49
+ }
50
+
51
+ function getConfig(cm) {
52
+ var deflt = cm.state.closeBrackets;
53
+ if (!deflt || deflt.override) return deflt;
54
+ var mode = cm.getModeAt(cm.getCursor());
55
+ return mode.closeBrackets || deflt;
56
+ }
57
+
58
+ function handleBackspace(cm) {
59
+ var conf = getConfig(cm);
60
+ if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
61
+
62
+ var pairs = getOption(conf, "pairs");
63
+ var ranges = cm.listSelections();
64
+ for (var i = 0; i < ranges.length; i++) {
65
+ if (!ranges[i].empty()) return CodeMirror.Pass;
66
+ var around = charsAround(cm, ranges[i].head);
67
+ if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
68
+ }
69
+ for (var i = ranges.length - 1; i >= 0; i--) {
70
+ var cur = ranges[i].head;
71
+ cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
72
+ }
73
+ }
74
+
75
+ function handleEnter(cm) {
76
+ var conf = getConfig(cm);
77
+ var explode = conf && getOption(conf, "explode");
78
+ if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
79
+
80
+ var ranges = cm.listSelections();
81
+ for (var i = 0; i < ranges.length; i++) {
82
+ if (!ranges[i].empty()) return CodeMirror.Pass;
83
+ var around = charsAround(cm, ranges[i].head);
84
+ if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
85
+ }
86
+ cm.operation(function() {
87
+ var linesep = cm.lineSeparator() || "\n";
88
+ cm.replaceSelection(linesep + linesep, null);
89
+ cm.execCommand("goCharLeft");
90
+ ranges = cm.listSelections();
91
+ for (var i = 0; i < ranges.length; i++) {
92
+ var line = ranges[i].head.line;
93
+ cm.indentLine(line, null, true);
94
+ cm.indentLine(line + 1, null, true);
95
+ }
96
+ });
97
+ }
98
+
99
+ function contractSelection(sel) {
100
+ var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
101
+ return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
102
+ head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
103
+ }
104
+
105
+ function handleChar(cm, ch) {
106
+ var conf = getConfig(cm);
107
+ if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
108
+
109
+ var pairs = getOption(conf, "pairs");
110
+ var pos = pairs.indexOf(ch);
111
+ if (pos == -1) return CodeMirror.Pass;
112
+ var triples = getOption(conf, "triples");
113
+
114
+ var identical = pairs.charAt(pos + 1) == ch;
115
+ var ranges = cm.listSelections();
116
+ var opening = pos % 2 == 0;
117
+
118
+ var type;
119
+ for (var i = 0; i < ranges.length; i++) {
120
+ var range = ranges[i], cur = range.head, curType;
121
+ var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
122
+ if (opening && !range.empty()) {
123
+ curType = "surround";
124
+ } else if ((identical || !opening) && next == ch) {
125
+ if (identical && stringStartsAfter(cm, cur))
126
+ curType = "both";
127
+ else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
128
+ curType = "skipThree";
129
+ else
130
+ curType = "skip";
131
+ } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
132
+ cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
133
+ if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
134
+ curType = "addFour";
135
+ } else if (identical) {
136
+ var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
137
+ if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
138
+ else return CodeMirror.Pass;
139
+ } else if (opening && (cm.getLine(cur.line).length == cur.ch ||
140
+ isClosingBracket(next, pairs) ||
141
+ /\s/.test(next))) {
142
+ curType = "both";
143
+ } else {
144
+ return CodeMirror.Pass;
145
+ }
146
+ if (!type) type = curType;
147
+ else if (type != curType) return CodeMirror.Pass;
148
+ }
149
+
150
+ var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
151
+ var right = pos % 2 ? ch : pairs.charAt(pos + 1);
152
+ cm.operation(function() {
153
+ if (type == "skip") {
154
+ cm.execCommand("goCharRight");
155
+ } else if (type == "skipThree") {
156
+ for (var i = 0; i < 3; i++)
157
+ cm.execCommand("goCharRight");
158
+ } else if (type == "surround") {
159
+ var sels = cm.getSelections();
160
+ for (var i = 0; i < sels.length; i++)
161
+ sels[i] = left + sels[i] + right;
162
+ cm.replaceSelections(sels, "around");
163
+ sels = cm.listSelections().slice();
164
+ for (var i = 0; i < sels.length; i++)
165
+ sels[i] = contractSelection(sels[i]);
166
+ cm.setSelections(sels);
167
+ } else if (type == "both") {
168
+ cm.replaceSelection(left + right, null);
169
+ cm.triggerElectric(left + right);
170
+ cm.execCommand("goCharLeft");
171
+ } else if (type == "addFour") {
172
+ cm.replaceSelection(left + left + left + left, "before");
173
+ cm.execCommand("goCharRight");
174
+ }
175
+ });
176
+ }
177
+
178
+ function isClosingBracket(ch, pairs) {
179
+ var pos = pairs.lastIndexOf(ch);
180
+ return pos > -1 && pos % 2 == 1;
181
+ }
182
+
183
+ function charsAround(cm, pos) {
184
+ var str = cm.getRange(Pos(pos.line, pos.ch - 1),
185
+ Pos(pos.line, pos.ch + 1));
186
+ return str.length == 2 ? str : null;
187
+ }
188
+
189
+ function stringStartsAfter(cm, pos) {
190
+ var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
191
+ return /\bstring/.test(token.type) && token.start == pos.ch &&
192
+ (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
193
+ }
194
+ });
assets/vendor/codemirror/addon/edit/closetag.js ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ /**
5
+ * Tag-closer extension for CodeMirror.
6
+ *
7
+ * This extension adds an "autoCloseTags" option that can be set to
8
+ * either true to get the default behavior, or an object to further
9
+ * configure its behavior.
10
+ *
11
+ * These are supported options:
12
+ *
13
+ * `whenClosing` (default true)
14
+ * Whether to autoclose when the '/' of a closing tag is typed.
15
+ * `whenOpening` (default true)
16
+ * Whether to autoclose the tag when the final '>' of an opening
17
+ * tag is typed.
18
+ * `dontCloseTags` (default is empty tags for HTML, none for XML)
19
+ * An array of tag names that should not be autoclosed.
20
+ * `indentTags` (default is block tags for HTML, none for XML)
21
+ * An array of tag names that should, when opened, cause a
22
+ * blank line to be added inside the tag, and the blank line and
23
+ * closing line to be indented.
24
+ *
25
+ * See demos/closetag.html for a usage example.
26
+ */
27
+
28
+ (function(mod) {
29
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
30
+ mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
31
+ else if (typeof define == "function" && define.amd) // AMD
32
+ define(["../../lib/codemirror", "../fold/xml-fold"], mod);
33
+ else // Plain browser env
34
+ mod(CodeMirror);
35
+ })(function(CodeMirror) {
36
+ CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
37
+ if (old != CodeMirror.Init && old)
38
+ cm.removeKeyMap("autoCloseTags");
39
+ if (!val) return;
40
+ var map = {name: "autoCloseTags"};
41
+ if (typeof val != "object" || val.whenClosing)
42
+ map["'/'"] = function(cm) { return autoCloseSlash(cm); };
43
+ if (typeof val != "object" || val.whenOpening)
44
+ map["'>'"] = function(cm) { return autoCloseGT(cm); };
45
+ cm.addKeyMap(map);
46
+ });
47
+
48
+ var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
49
+ "source", "track", "wbr"];
50
+ var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
51
+ "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
52
+
53
+ function autoCloseGT(cm) {
54
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
55
+ var ranges = cm.listSelections(), replacements = [];
56
+ var opt = cm.getOption("autoCloseTags");
57
+ for (var i = 0; i < ranges.length; i++) {
58
+ if (!ranges[i].empty()) return CodeMirror.Pass;
59
+ var pos = ranges[i].head, tok = cm.getTokenAt(pos);
60
+ var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
61
+ if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
62
+
63
+ var html = inner.mode.configuration == "html";
64
+ var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
65
+ var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
66
+
67
+ var tagName = state.tagName;
68
+ if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
69
+ var lowerTagName = tagName.toLowerCase();
70
+ // Don't process the '>' at the end of an end-tag or self-closing tag
71
+ if (!tagName ||
72
+ tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
73
+ tok.type == "tag" && state.type == "closeTag" ||
74
+ tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
75
+ dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
76
+ closingTagExists(cm, tagName, pos, state, true))
77
+ return CodeMirror.Pass;
78
+
79
+ var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
80
+ replacements[i] = {indent: indent,
81
+ text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
82
+ newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
83
+ }
84
+
85
+ var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose);
86
+ for (var i = ranges.length - 1; i >= 0; i--) {
87
+ var info = replacements[i];
88
+ cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
89
+ var sel = cm.listSelections().slice(0);
90
+ sel[i] = {head: info.newPos, anchor: info.newPos};
91
+ cm.setSelections(sel);
92
+ if (!dontIndentOnAutoClose && info.indent) {
93
+ cm.indentLine(info.newPos.line, null, true);
94
+ cm.indentLine(info.newPos.line + 1, null, true);
95
+ }
96
+ }
97
+ }
98
+
99
+ function autoCloseCurrent(cm, typingSlash) {
100
+ var ranges = cm.listSelections(), replacements = [];
101
+ var head = typingSlash ? "/" : "</";
102
+ var opt = cm.getOption("autoCloseTags");
103
+ var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnSlash);
104
+ for (var i = 0; i < ranges.length; i++) {
105
+ if (!ranges[i].empty()) return CodeMirror.Pass;
106
+ var pos = ranges[i].head, tok = cm.getTokenAt(pos);
107
+ var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
108
+ if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
109
+ tok.start != pos.ch - 1))
110
+ return CodeMirror.Pass;
111
+ // Kludge to get around the fact that we are not in XML mode
112
+ // when completing in JS/CSS snippet in htmlmixed mode. Does not
113
+ // work for other XML embedded languages (there is no general
114
+ // way to go from a mixed mode to its current XML state).
115
+ var replacement;
116
+ if (inner.mode.name != "xml") {
117
+ if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
118
+ replacement = head + "script";
119
+ else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
120
+ replacement = head + "style";
121
+ else
122
+ return CodeMirror.Pass;
123
+ } else {
124
+ if (!state.context || !state.context.tagName ||
125
+ closingTagExists(cm, state.context.tagName, pos, state))
126
+ return CodeMirror.Pass;
127
+ replacement = head + state.context.tagName;
128
+ }
129
+ if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
130
+ replacements[i] = replacement;
131
+ }
132
+ cm.replaceSelections(replacements);
133
+ ranges = cm.listSelections();
134
+ if (!dontIndentOnAutoClose) {
135
+ for (var i = 0; i < ranges.length; i++)
136
+ if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
137
+ cm.indentLine(ranges[i].head.line);
138
+ }
139
+ }
140
+
141
+ function autoCloseSlash(cm) {
142
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
143
+ return autoCloseCurrent(cm, true);
144
+ }
145
+
146
+ CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
147
+
148
+ function indexOf(collection, elt) {
149
+ if (collection.indexOf) return collection.indexOf(elt);
150
+ for (var i = 0, e = collection.length; i < e; ++i)
151
+ if (collection[i] == elt) return i;
152
+ return -1;
153
+ }
154
+
155
+ // If xml-fold is loaded, we use its functionality to try and verify
156
+ // whether a given tag is actually unclosed.
157
+ function closingTagExists(cm, tagName, pos, state, newTag) {
158
+ if (!CodeMirror.scanForClosingTag) return false;
159
+ var end = Math.min(cm.lastLine() + 1, pos.line + 500);
160
+ var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end);
161
+ if (!nextClose || nextClose.tag != tagName) return false;
162
+ var cx = state.context;
163
+ // If the immediate wrapping context contains onCx instances of
164
+ // the same tag, a closing tag only exists if there are at least
165
+ // that many closing tags of that type following.
166
+ for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx;
167
+ pos = nextClose.to;
168
+ for (var i = 1; i < onCx; i++) {
169
+ var next = CodeMirror.scanForClosingTag(cm, pos, null, end);
170
+ if (!next || next.tag != tagName) return false;
171
+ pos = next.to;
172
+ }
173
+ return true;
174
+ }
175
+ });
assets/vendor/codemirror/addon/edit/continuelist.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
15
+ emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
16
+ unorderedListRE = /[*+-]\s/;
17
+
18
+ CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
19
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
20
+ var ranges = cm.listSelections(), replacements = [];
21
+ for (var i = 0; i < ranges.length; i++) {
22
+ var pos = ranges[i].head;
23
+ var eolState = cm.getStateAfter(pos.line);
24
+ var inList = eolState.list !== false;
25
+ var inQuote = eolState.quote !== 0;
26
+
27
+ var line = cm.getLine(pos.line), match = listRE.exec(line);
28
+ var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch));
29
+ if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
30
+ cm.execCommand("newlineAndIndent");
31
+ return;
32
+ }
33
+ if (emptyListRE.test(line)) {
34
+ if (!/>\s*$/.test(line)) cm.replaceRange("", {
35
+ line: pos.line, ch: 0
36
+ }, {
37
+ line: pos.line, ch: pos.ch + 1
38
+ });
39
+ replacements[i] = "\n";
40
+ } else {
41
+ var indent = match[1], after = match[5];
42
+ var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
43
+ var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " ");
44
+ replacements[i] = "\n" + indent + bullet + after;
45
+
46
+ if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
47
+ }
48
+ }
49
+
50
+ cm.replaceSelections(replacements);
51
+ };
52
+
53
+ // Auto-updating Markdown list numbers when a new item is added to the
54
+ // middle of a list
55
+ function incrementRemainingMarkdownListNumbers(cm, pos) {
56
+ var startLine = pos.line, lookAhead = 0, skipCount = 0;
57
+ var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1];
58
+
59
+ do {
60
+ lookAhead += 1;
61
+ var nextLineNumber = startLine + lookAhead;
62
+ var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine);
63
+
64
+ if (nextItem) {
65
+ var nextIndent = nextItem[1];
66
+ var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount);
67
+ var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber;
68
+
69
+ if (startIndent === nextIndent && !isNaN(nextNumber)) {
70
+ if (newNumber === nextNumber) itemNumber = nextNumber + 1;
71
+ if (newNumber > nextNumber) itemNumber = newNumber + 1;
72
+ cm.replaceRange(
73
+ nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
74
+ {
75
+ line: nextLineNumber, ch: 0
76
+ }, {
77
+ line: nextLineNumber, ch: nextLine.length
78
+ });
79
+ } else {
80
+ if (startIndent.length > nextIndent.length) return;
81
+ // This doesn't run if the next line immediatley indents, as it is
82
+ // not clear of the users intention (new indented item or same level)
83
+ if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return;
84
+ skipCount += 1;
85
+ }
86
+ }
87
+ } while (nextItem);
88
+ }
89
+ });
assets/vendor/codemirror/addon/edit/matchbrackets.js ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
13
+ (document.documentMode == null || document.documentMode < 8);
14
+
15
+ var Pos = CodeMirror.Pos;
16
+
17
+ var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
18
+
19
+ function findMatchingBracket(cm, where, config) {
20
+ var line = cm.getLineHandle(where.line), pos = where.ch - 1;
21
+ var afterCursor = config && config.afterCursor
22
+ if (afterCursor == null)
23
+ afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
24
+
25
+ // A cursor is defined as between two characters, but in in vim command mode
26
+ // (i.e. not insert mode), the cursor is visually represented as a
27
+ // highlighted box on top of the 2nd character. Otherwise, we allow matches
28
+ // from before or after the cursor.
29
+ var match = (!afterCursor && pos >= 0 && matching[line.text.charAt(pos)]) ||
30
+ matching[line.text.charAt(++pos)];
31
+ if (!match) return null;
32
+ var dir = match.charAt(1) == ">" ? 1 : -1;
33
+ if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
34
+ var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
35
+
36
+ var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
37
+ if (found == null) return null;
38
+ return {from: Pos(where.line, pos), to: found && found.pos,
39
+ match: found && found.ch == match.charAt(0), forward: dir > 0};
40
+ }
41
+
42
+ // bracketRegex is used to specify which type of bracket to scan
43
+ // should be a regexp, e.g. /[[\]]/
44
+ //
45
+ // Note: If "where" is on an open bracket, then this bracket is ignored.
46
+ //
47
+ // Returns false when no bracket was found, null when it reached
48
+ // maxScanLines and gave up
49
+ function scanForBracket(cm, where, dir, style, config) {
50
+ var maxScanLen = (config && config.maxScanLineLength) || 10000;
51
+ var maxScanLines = (config && config.maxScanLines) || 1000;
52
+
53
+ var stack = [];
54
+ var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
55
+ var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
56
+ : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
57
+ for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
58
+ var line = cm.getLine(lineNo);
59
+ if (!line) continue;
60
+ var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
61
+ if (line.length > maxScanLen) continue;
62
+ if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
63
+ for (; pos != end; pos += dir) {
64
+ var ch = line.charAt(pos);
65
+ if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
66
+ var match = matching[ch];
67
+ if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
68
+ else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
69
+ else stack.pop();
70
+ }
71
+ }
72
+ }
73
+ return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
74
+ }
75
+
76
+ function matchBrackets(cm, autoclear, config) {
77
+ // Disable brace matching in long lines, since it'll cause hugely slow updates
78
+ var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
79
+ var marks = [], ranges = cm.listSelections();
80
+ for (var i = 0; i < ranges.length; i++) {
81
+ var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
82
+ if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
83
+ var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
84
+ marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
85
+ if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
86
+ marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
87
+ }
88
+ }
89
+
90
+ if (marks.length) {
91
+ // Kludge to work around the IE bug from issue #1193, where text
92
+ // input stops going to the textare whever this fires.
93
+ if (ie_lt8 && cm.state.focused) cm.focus();
94
+
95
+ var clear = function() {
96
+ cm.operation(function() {
97
+ for (var i = 0; i < marks.length; i++) marks[i].clear();
98
+ });
99
+ };
100
+ if (autoclear) setTimeout(clear, 800);
101
+ else return clear;
102
+ }
103
+ }
104
+
105
+ function doMatchBrackets(cm) {
106
+ cm.operation(function() {
107
+ if (cm.state.matchBrackets.currentlyHighlighted) {
108
+ cm.state.matchBrackets.currentlyHighlighted();
109
+ cm.state.matchBrackets.currentlyHighlighted = null;
110
+ }
111
+ cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
112
+ });
113
+ }
114
+
115
+ CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
116
+ if (old && old != CodeMirror.Init) {
117
+ cm.off("cursorActivity", doMatchBrackets);
118
+ if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
119
+ cm.state.matchBrackets.currentlyHighlighted();
120
+ cm.state.matchBrackets.currentlyHighlighted = null;
121
+ }
122
+ }
123
+ if (val) {
124
+ cm.state.matchBrackets = typeof val == "object" ? val : {};
125
+ cm.on("cursorActivity", doMatchBrackets);
126
+ }
127
+ });
128
+
129
+ CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
130
+ CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
131
+ // Backwards-compatibility kludge
132
+ if (oldConfig || typeof config == "boolean") {
133
+ if (!oldConfig) {
134
+ config = config ? {strict: true} : null
135
+ } else {
136
+ oldConfig.strict = config
137
+ config = oldConfig
138
+ }
139
+ }
140
+ return findMatchingBracket(this, pos, config)
141
+ });
142
+ CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
143
+ return scanForBracket(this, pos, dir, style, config);
144
+ });
145
+ });
assets/vendor/codemirror/addon/edit/matchtags.js ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../fold/xml-fold"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineOption("matchTags", false, function(cm, val, old) {
15
+ if (old && old != CodeMirror.Init) {
16
+ cm.off("cursorActivity", doMatchTags);
17
+ cm.off("viewportChange", maybeUpdateMatch);
18
+ clear(cm);
19
+ }
20
+ if (val) {
21
+ cm.state.matchBothTags = typeof val == "object" && val.bothTags;
22
+ cm.on("cursorActivity", doMatchTags);
23
+ cm.on("viewportChange", maybeUpdateMatch);
24
+ doMatchTags(cm);
25
+ }
26
+ });
27
+
28
+ function clear(cm) {
29
+ if (cm.state.tagHit) cm.state.tagHit.clear();
30
+ if (cm.state.tagOther) cm.state.tagOther.clear();
31
+ cm.state.tagHit = cm.state.tagOther = null;
32
+ }
33
+
34
+ function doMatchTags(cm) {
35
+ cm.state.failedTagMatch = false;
36
+ cm.operation(function() {
37
+ clear(cm);
38
+ if (cm.somethingSelected()) return;
39
+ var cur = cm.getCursor(), range = cm.getViewport();
40
+ range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to);
41
+ var match = CodeMirror.findMatchingTag(cm, cur, range);
42
+ if (!match) return;
43
+ if (cm.state.matchBothTags) {
44
+ var hit = match.at == "open" ? match.open : match.close;
45
+ if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"});
46
+ }
47
+ var other = match.at == "close" ? match.open : match.close;
48
+ if (other)
49
+ cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"});
50
+ else
51
+ cm.state.failedTagMatch = true;
52
+ });
53
+ }
54
+
55
+ function maybeUpdateMatch(cm) {
56
+ if (cm.state.failedTagMatch) doMatchTags(cm);
57
+ }
58
+
59
+ CodeMirror.commands.toMatchingTag = function(cm) {
60
+ var found = CodeMirror.findMatchingTag(cm, cm.getCursor());
61
+ if (found) {
62
+ var other = found.at == "close" ? found.open : found.close;
63
+ if (other) cm.extendSelection(other.to, other.from);
64
+ }
65
+ };
66
+ });
assets/vendor/codemirror/addon/edit/trailingspace.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
13
+ if (prev == CodeMirror.Init) prev = false;
14
+ if (prev && !val)
15
+ cm.removeOverlay("trailingspace");
16
+ else if (!prev && val)
17
+ cm.addOverlay({
18
+ token: function(stream) {
19
+ for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
20
+ if (i > stream.pos) { stream.pos = i; return null; }
21
+ stream.pos = l;
22
+ return "trailingspace";
23
+ },
24
+ name: "trailingspace"
25
+ });
26
+ });
27
+ });
assets/vendor/codemirror/addon/emmet/emmet.js ADDED
@@ -0,0 +1,43080 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;"undefined"!=typeof window?o=window:"undefined"!=typeof global?o=global:"undefined"!=typeof self&&(o=self),o.emmetCodeMirror=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ "use strict";
3
+
4
+ var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
5
+
6
+ var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
7
+
8
+ var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
9
+
10
+ Object.defineProperty(exports, "__esModule", {
11
+ value: true
12
+ });
13
+ /**
14
+ * Emmet Editor interface implementation for CodeMirror.
15
+ * Interface is optimized for multiple cursor usage: authors
16
+ * should run acttion multiple times and update `selectionIndex`
17
+ * property on each iteration.
18
+ */
19
+
20
+ var emmet = _interopRequire(require("./emmet"));
21
+
22
+ var modeMap = {
23
+ "text/html": "html",
24
+ "application/xml": "xml",
25
+ "text/xsl": "xsl",
26
+ "text/css": "css",
27
+ "text/x-less": "less",
28
+ "text/x-scss": "scss",
29
+ "text/x-sass": "sass"
30
+ };
31
+
32
+ exports.modeMap = modeMap;
33
+
34
+ var EmmetEditor = (function () {
35
+ function EmmetEditor(ctx) {
36
+ var selIndex = arguments[1] === undefined ? 0 : arguments[1];
37
+
38
+ _classCallCheck(this, EmmetEditor);
39
+
40
+ this.context = ctx;
41
+ this.selectionIndex = selIndex || 0;
42
+ }
43
+
44
+ _createClass(EmmetEditor, {
45
+ selectionList: {
46
+
47
+ /**
48
+ * Returns list of selections for current CodeMirror instance.
49
+ * @return {Array}
50
+ */
51
+
52
+ value: function selectionList() {
53
+ var cm = this.context;
54
+ return cm.listSelections().map(function (sel) {
55
+ var anchor = posToIndex(cm, sel.anchor);
56
+ var head = posToIndex(cm, sel.head);
57
+
58
+ return {
59
+ start: Math.min(anchor, head),
60
+ end: Math.max(anchor, head)
61
+ };
62
+ });
63
+ }
64
+ },
65
+ getCaretPos: {
66
+ value: function getCaretPos() {
67
+ return this.getSelectionRange().start;
68
+ }
69
+ },
70
+ setCaretPos: {
71
+ value: function setCaretPos(pos) {
72
+ this.createSelection(pos);
73
+ }
74
+ },
75
+ getSelectionRange: {
76
+
77
+ /**
78
+ * Returns current selection range (for current selection index)
79
+ * @return {Object}
80
+ */
81
+
82
+ value: function getSelectionRange() {
83
+ return this.selectionList()[this.selectionIndex];
84
+ }
85
+ },
86
+ createSelection: {
87
+ value: function createSelection(start, end) {
88
+ if (typeof end == "undefined") {
89
+ end = start;
90
+ }
91
+
92
+ var sels = this.selectionList();
93
+ var cm = this.context;
94
+ sels[this.selectionIndex] = { start: start, end: end };
95
+ this.context.setSelections(sels.map(function (sel) {
96
+ return {
97
+ head: indexToPos(cm, sel.start),
98
+ anchor: indexToPos(cm, sel.end)
99
+ };
100
+ }));
101
+ }
102
+ },
103
+ getSelection: {
104
+
105
+ /**
106
+ * Returns current selection
107
+ * @return {String}
108
+ */
109
+
110
+ value: function getSelection() {
111
+ var sel = this.getSelectionRange();
112
+ sel.start = indexToPos(this.context, sel.start);
113
+ sel.end = indexToPos(this.context, sel.end);
114
+ return this.context.getRange(sel.start, sel.end);
115
+ }
116
+ },
117
+ getCurrentLineRange: {
118
+ value: function getCurrentLineRange() {
119
+ var caret = indexToPos(this.context, this.getCaretPos());
120
+ return {
121
+ start: posToIndex(this.context, caret.line, 0),
122
+ end: posToIndex(this.context, caret.line, this.context.getLine(caret.line).length)
123
+ };
124
+ }
125
+ },
126
+ getCurrentLine: {
127
+ value: function getCurrentLine() {
128
+ var caret = indexToPos(this.context, this.getCaretPos());
129
+ return this.context.getLine(caret.line) || "";
130
+ }
131
+ },
132
+ replaceContent: {
133
+ value: function replaceContent(value, start, end, noIndent) {
134
+ if (typeof end == "undefined") {
135
+ end = typeof start == "undefined" ? this.getContent().length : start;
136
+ }
137
+ if (typeof start == "undefined") {
138
+ start = 0;
139
+ }
140
+
141
+ // normalize indentation according to editor preferences
142
+ value = this.normalize(value);
143
+
144
+ // indent new value
145
+ if (!noIndent) {
146
+ value = emmet.utils.common.padString(value, emmet.utils.common.getLinePaddingFromPosition(this.getContent(), start));
147
+ }
148
+
149
+ // find new caret position
150
+ var tabstopData = emmet.tabStops.extract(value, { escape: function (ch) {
151
+ return ch;
152
+ } });
153
+ value = tabstopData.text;
154
+
155
+ var firstTabStop = tabstopData.tabstops[0] || { start: value.length, end: value.length };
156
+ firstTabStop.start += start;
157
+ firstTabStop.end += start;
158
+
159
+ this.context.replaceRange(value, indexToPos(this.context, start), indexToPos(this.context, end));
160
+ this.createSelection(firstTabStop.start, firstTabStop.end);
161
+ }
162
+ },
163
+ normalize: {
164
+
165
+ /**
166
+ * Normalizes string indentation in given string
167
+ * according to editor preferences
168
+ * @param {String} str
169
+ * @return {String}
170
+ */
171
+
172
+ value: function normalize(str) {
173
+ var indent = "\t";
174
+ var ctx = this.context;
175
+ if (!ctx.getOption("indentWithTabs")) {
176
+ indent = emmet.utils.common.repeatString(" ", ctx.getOption("indentUnit"));
177
+ }
178
+
179
+ return emmet.utils.editor.normalize(str, {
180
+ indentation: indent
181
+ });
182
+ }
183
+ },
184
+ getContent: {
185
+ value: function getContent() {
186
+ return this.context.getValue();
187
+ }
188
+ },
189
+ getSyntax: {
190
+ value: function getSyntax() {
191
+ var editor = this.context;
192
+ var pos = editor.posFromIndex(this.getCaretPos());
193
+ var mode = editor.getModeAt(editor.getCursor());
194
+ var syntax = mode.name;
195
+ if (syntax === "xml" && mode.configuration) {
196
+ syntax = mode.configuration;
197
+ }
198
+
199
+ return syntax || emmet.utils.action.detectSyntax(this, syntax);
200
+ }
201
+ },
202
+ getProfileName: {
203
+
204
+ /**
205
+ * Returns current output profile name (@see emmet#setupProfile)
206
+ * @return {String}
207
+ */
208
+
209
+ value: function getProfileName() {
210
+ if (this.context.getOption("profile")) {
211
+ return this.context.getOption("profile");
212
+ }
213
+
214
+ return emmet.utils.action.detectProfile(this);
215
+ }
216
+ },
217
+ prompt: {
218
+
219
+ /**
220
+ * Ask user to enter something
221
+ * @param {String} title Dialog title
222
+ * @return {String} Entered data
223
+ */
224
+
225
+ value: (function (_prompt) {
226
+ var _promptWrapper = function prompt(_x) {
227
+ return _prompt.apply(this, arguments);
228
+ };
229
+
230
+ _promptWrapper.toString = function () {
231
+ return _prompt.toString();
232
+ };
233
+
234
+ return _promptWrapper;
235
+ })(function (title) {
236
+ return prompt(title);
237
+ })
238
+ },
239
+ getFilePath: {
240
+
241
+ /**
242
+ * Returns current editor's file path
243
+ * @return {String}
244
+ */
245
+
246
+ value: function getFilePath() {
247
+ return location.href;
248
+ }
249
+ },
250
+ isValidSyntax: {
251
+
252
+ /**
253
+ * Check if current editor syntax is valid, e.g. is supported by Emmet
254
+ * @return {Boolean}
255
+ */
256
+
257
+ value: function isValidSyntax() {
258
+ return emmet.resources.hasSyntax(this.getSyntax());
259
+ }
260
+ }
261
+ });
262
+
263
+ return EmmetEditor;
264
+ })();
265
+
266
+ exports["default"] = EmmetEditor;
267
+
268
+ /**
269
+ * Converts CM’s inner representation of character
270
+ * position (line, ch) to character index in text
271
+ * @param {CodeMirror} cm CodeMirror instance
272
+ * @param {Object} pos Position object
273
+ * @return {Number}
274
+ */
275
+ function posToIndex(cm, pos) {
276
+ if (arguments.length > 2 && typeof pos !== "object") {
277
+ pos = { line: arguments[1], ch: arguments[2] };
278
+ }
279
+ return cm.indexFromPos(pos);
280
+ }
281
+
282
+ /**
283
+ * Converts charater index in text to CM’s internal object representation
284
+ * @param {CodeMirror} cm CodeMirror instance
285
+ * @param {Number} ix Character index in CM document
286
+ * @return {Object}
287
+ */
288
+ function indexToPos(cm, ix) {
289
+ return cm.posFromIndex(ix);
290
+ }
291
+ },{"./emmet":2}],2:[function(require,module,exports){
292
+ "use strict";
293
+
294
+ var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
295
+
296
+ var emmet = _interopRequire(require("emmet"));
297
+
298
+ require("emmet/bundles/snippets");
299
+
300
+ require("emmet/bundles/caniuse");
301
+
302
+ module.exports = emmet;
303
+ },{"emmet":39,"emmet/bundles/caniuse":3,"emmet/bundles/snippets":4}],3:[function(require,module,exports){
304
+ /**
305
+ * Bundler, used in builder script to statically
306
+ * include optimized caniuse.json into bundle
307
+ */
308
+ var ciu = require('../lib/assets/caniuse');
309
+ var db = require('../lib/caniuse.json');
310
+ ciu.load(db, true);
311
+ },{"../lib/assets/caniuse":23,"../lib/caniuse.json":35}],4:[function(require,module,exports){
312
+ /**
313
+ * Bundler, used in builder script to statically
314
+ * include snippets.json into bundle
315
+ */
316
+ var res = require('../lib/assets/resources');
317
+ var snippets = require('../lib/snippets.json');
318
+ res.setVocabulary(snippets, 'system');
319
+
320
+ },{"../lib/assets/resources":31,"../lib/snippets.json":68}],5:[function(require,module,exports){
321
+ /**
322
+ * HTML pair matching (balancing) actions
323
+ * @constructor
324
+ */
325
+ if (typeof module === 'object' && typeof define !== 'function') {
326
+ var define = function (factory) {
327
+ module.exports = factory(require, exports, module);
328
+ };
329
+ }
330
+
331
+ define(function(require, exports, module) {
332
+ var htmlMatcher = require('../assets/htmlMatcher');
333
+ var utils = require('../utils/common');
334
+ var editorUtils = require('../utils/editor');
335
+ var actionUtils = require('../utils/action');
336
+ var range = require('../assets/range');
337
+ var cssEditTree = require('../editTree/css');
338
+ var cssSections = require('../utils/cssSections');
339
+ var lastMatch = null;
340
+
341
+ function last(arr) {
342
+ return arr[arr.length - 1];
343
+ }
344
+
345
+ function balanceHTML(editor, direction) {
346
+ var info = editorUtils.outputInfo(editor);
347
+ var content = info.content;
348
+ var sel = range(editor.getSelectionRange());
349
+
350
+ // validate previous match
351
+ if (lastMatch && !lastMatch.range.equal(sel)) {
352
+ lastMatch = null;
353
+ }
354
+
355
+ if (lastMatch && sel.length()) {
356
+ if (direction == 'in') {
357
+ // user has previously selected tag and wants to move inward
358
+ if (lastMatch.type == 'tag' && !lastMatch.close) {
359
+ // unary tag was selected, can't move inward
360
+ return false;
361
+ } else {
362
+ if (lastMatch.range.equal(lastMatch.outerRange)) {
363
+ lastMatch.range = lastMatch.innerRange;
364
+ } else {
365
+ var narrowed = utils.narrowToNonSpace(content, lastMatch.innerRange);
366
+ lastMatch = htmlMatcher.find(content, narrowed.start + 1);
367
+ if (lastMatch && lastMatch.range.equal(sel) && lastMatch.outerRange.equal(sel)) {
368
+ lastMatch.range = lastMatch.innerRange;
369
+ }
370
+ }
371
+ }
372
+ } else {
373
+ if (
374
+ !lastMatch.innerRange.equal(lastMatch.outerRange)
375
+ && lastMatch.range.equal(lastMatch.innerRange)
376
+ && sel.equal(lastMatch.range)) {
377
+ lastMatch.range = lastMatch.outerRange;
378
+ } else {
379
+ lastMatch = htmlMatcher.find(content, sel.start);
380
+ if (lastMatch && lastMatch.range.equal(sel) && lastMatch.innerRange.equal(sel)) {
381
+ lastMatch.range = lastMatch.outerRange;
382
+ }
383
+ }
384
+ }
385
+ } else {
386
+ lastMatch = htmlMatcher.find(content, sel.start);
387
+ }
388
+
389
+ if (lastMatch) {
390
+ if (lastMatch.innerRange.equal(sel)) {
391
+ lastMatch.range = lastMatch.outerRange;
392
+ }
393
+
394
+ if (!lastMatch.range.equal(sel)) {
395
+ editor.createSelection(lastMatch.range.start, lastMatch.range.end);
396
+ return true;
397
+ }
398
+ }
399
+
400
+ lastMatch = null;
401
+ return false;
402
+ }
403
+
404
+ function rangesForCSSRule(rule, pos) {
405
+ // find all possible ranges
406
+ var ranges = [rule.range(true)];
407
+
408
+ // braces content
409
+ ranges.push(rule.valueRange(true));
410
+
411
+ // find nested sections
412
+ var nestedSections = cssSections.nestedSectionsInRule(rule);
413
+
414
+ // real content, e.g. from first property name to
415
+ // last property value
416
+ var items = rule.list();
417
+ if (items.length || nestedSections.length) {
418
+ var start = Number.POSITIVE_INFINITY, end = -1;
419
+ if (items.length) {
420
+ start = items[0].namePosition(true);
421
+ end = last(items).range(true).end;
422
+ }
423
+
424
+ if (nestedSections.length) {
425
+ if (nestedSections[0].start < start) {
426
+ start = nestedSections[0].start;
427
+ }
428
+
429
+ if (last(nestedSections).end > end) {
430
+ end = last(nestedSections).end;
431
+ }
432
+ }
433
+
434
+ ranges.push(range.create2(start, end));
435
+ }
436
+
437
+ ranges = ranges.concat(nestedSections);
438
+
439
+ var prop = cssEditTree.propertyFromPosition(rule, pos) || items[0];
440
+ if (prop) {
441
+ ranges.push(prop.range(true));
442
+ var valueRange = prop.valueRange(true);
443
+ if (!prop.end()) {
444
+ valueRange._unterminated = true;
445
+ }
446
+ ranges.push(valueRange);
447
+ }
448
+
449
+ return ranges;
450
+ }
451
+
452
+ /**
453
+ * Returns all possible selection ranges for given caret position
454
+ * @param {String} content CSS content
455
+ * @param {Number} pos Caret position(where to start searching)
456
+ * @return {Array}
457
+ */
458
+ function getCSSRanges(content, pos) {
459
+ var rule;
460
+ if (typeof content === 'string') {
461
+ var ruleRange = cssSections.matchEnclosingRule(content, pos);
462
+ if (ruleRange) {
463
+ rule = cssEditTree.parse(ruleRange.substring(content), {
464
+ offset: ruleRange.start
465
+ });
466
+ }
467
+ } else {
468
+ // passed parsed CSS rule
469
+ rule = content;
470
+ }
471
+
472
+ if (!rule) {
473
+ return null;
474
+ }
475
+
476
+ // find all possible ranges
477
+ var ranges = rangesForCSSRule(rule, pos);
478
+
479
+ // remove empty ranges
480
+ ranges = ranges.filter(function(item) {
481
+ return !!item.length;
482
+ });
483
+
484
+ return utils.unique(ranges, function(item) {
485
+ return item.valueOf();
486
+ });
487
+ }
488
+
489
+ function balanceCSS(editor, direction) {
490
+ var info = editorUtils.outputInfo(editor);
491
+ var content = info.content;
492
+ var sel = range(editor.getSelectionRange());
493
+
494
+ var ranges = getCSSRanges(info.content, sel.start);
495
+ if (!ranges && sel.length()) {
496
+ // possible reason: user has already selected
497
+ // CSS rule from last match
498
+ try {
499
+ var rule = cssEditTree.parse(sel.substring(info.content), {
500
+ offset: sel.start
501
+ });
502
+ ranges = getCSSRanges(rule, sel.start);
503
+ } catch(e) {}
504
+ }
505
+
506
+ if (!ranges) {
507
+ return false;
508
+ }
509
+
510
+ ranges = range.sort(ranges, true);
511
+
512
+ // edge case: find match that equals current selection,
513
+ // in case if user moves inward after selecting full CSS rule
514
+ var bestMatch = utils.find(ranges, function(r) {
515
+ return r.equal(sel);
516
+ });
517
+
518
+ if (!bestMatch) {
519
+ bestMatch = utils.find(ranges, function(r) {
520
+ // Check for edge case: caret right after CSS value
521
+ // but it doesn‘t contains terminating semicolon.
522
+ // In this case we have to check full value range
523
+ return r._unterminated ? r.include(sel.start) : r.inside(sel.start);
524
+ });
525
+ }
526
+
527
+ if (!bestMatch) {
528
+ return false;
529
+ }
530
+
531
+ // if best match equals to current selection, move index
532
+ // one position up or down, depending on direction
533
+ var bestMatchIx = ranges.indexOf(bestMatch);
534
+ if (bestMatch.equal(sel)) {
535
+ bestMatchIx += direction == 'out' ? 1 : -1;
536
+ }
537
+
538
+ if (bestMatchIx < 0 || bestMatchIx >= ranges.length) {
539
+ if (bestMatchIx >= ranges.length && direction == 'out') {
540
+ pos = bestMatch.start - 1;
541
+
542
+ var outerRanges = getCSSRanges(content, pos);
543
+ if (outerRanges) {
544
+ bestMatch = last(outerRanges.filter(function(r) {
545
+ return r.inside(pos);
546
+ }));
547
+ }
548
+ } else if (bestMatchIx < 0 && direction == 'in') {
549
+ bestMatch = null;
550
+ } else {
551
+ bestMatch = null;
552
+ }
553
+ } else {
554
+ bestMatch = ranges[bestMatchIx];
555
+ }
556
+
557
+ if (bestMatch) {
558
+ editor.createSelection(bestMatch.start, bestMatch.end);
559
+ return true;
560
+ }
561
+
562
+ return false;
563
+ }
564
+
565
+ return {
566
+ /**
567
+ * Find and select HTML tag pair
568
+ * @param {IEmmetEditor} editor Editor instance
569
+ * @param {String} direction Direction of pair matching: 'in' or 'out'.
570
+ * Default is 'out'
571
+ */
572
+ balance: function(editor, direction) {
573
+ direction = String((direction || 'out').toLowerCase());
574
+ var info = editorUtils.outputInfo(editor);
575
+ if (actionUtils.isSupportedCSS(info.syntax)) {
576
+ return balanceCSS(editor, direction);
577
+ }
578
+
579
+ return balanceHTML(editor, direction);
580
+ },
581
+
582
+ balanceInwardAction: function(editor) {
583
+ return this.balance(editor, 'in');
584
+ },
585
+
586
+ balanceOutwardAction: function(editor) {
587
+ return this.balance(editor, 'out');
588
+ },
589
+
590
+ /**
591
+ * Moves caret to matching opening or closing tag
592
+ * @param {IEmmetEditor} editor
593
+ */
594
+ goToMatchingPairAction: function(editor) {
595
+ var content = String(editor.getContent());
596
+ var caretPos = editor.getCaretPos();
597
+
598
+ if (content.charAt(caretPos) == '<')
599
+ // looks like caret is outside of tag pair
600
+ caretPos++;
601
+
602
+ var tag = htmlMatcher.tag(content, caretPos);
603
+ if (tag && tag.close) { // exclude unary tags
604
+ if (tag.open.range.inside(caretPos)) {
605
+ editor.setCaretPos(tag.close.range.start);
606
+ } else {
607
+ editor.setCaretPos(tag.open.range.start);
608
+ }
609
+
610
+ return true;
611
+ }
612
+
613
+ return false;
614
+ }
615
+ };
616
+ });
617
+ },{"../assets/htmlMatcher":26,"../assets/range":30,"../editTree/css":37,"../utils/action":70,"../utils/common":73,"../utils/cssSections":74,"../utils/editor":75}],6:[function(require,module,exports){
618
+ /**
619
+ * Encodes/decodes image under cursor to/from base64
620
+ * @param {IEmmetEditor} editor
621
+ */
622
+ if (typeof module === 'object' && typeof define !== 'function') {
623
+ var define = function (factory) {
624
+ module.exports = factory(require, exports, module);
625
+ };
626
+ }
627
+
628
+ define(function(require, exports, module) {
629
+ var file = require('../plugin/file');
630
+ var base64 = require('../utils/base64');
631
+ var actionUtils = require('../utils/action');
632
+ var editorUtils = require('../utils/editor');
633
+
634
+ /**
635
+ * Test if <code>text</code> starts with <code>token</code> at <code>pos</code>
636
+ * position. If <code>pos</code> is omitted, search from beginning of text
637
+ * @param {String} token Token to test
638
+ * @param {String} text Where to search
639
+ * @param {Number} pos Position where to start search
640
+ * @return {Boolean}
641
+ * @since 0.65
642
+ */
643
+ function startsWith(token, text, pos) {
644
+ pos = pos || 0;
645
+ return text.charAt(pos) == token.charAt(0) && text.substr(pos, token.length) == token;
646
+ }
647
+
648
+ /**
649
+ * Encodes image to base64
650
+ *
651
+ * @param {IEmmetEditor} editor
652
+ * @param {String} imgPath Path to image
653
+ * @param {Number} pos Caret position where image is located in the editor
654
+ * @return {Boolean}
655
+ */
656
+ function encodeToBase64(editor, imgPath, pos) {
657
+ var editorFile = editor.getFilePath();
658
+ var defaultMimeType = 'application/octet-stream';
659
+
660
+ if (editorFile === null) {
661
+ throw "You should save your file before using this action";
662
+ }
663
+
664
+ // locate real image path
665
+ var realImgPath = file.locateFile(editorFile, imgPath);
666
+ if (realImgPath === null) {
667
+ throw "Can't find " + imgPath + ' file';
668
+ }
669
+
670
+ file.read(realImgPath, function(err, content) {
671
+ if (err) {
672
+ throw 'Unable to read ' + realImgPath + ': ' + err;
673
+ }
674
+
675
+ var b64 = base64.encode(String(content));
676
+ if (!b64) {
677
+ throw "Can't encode file content to base64";
678
+ }
679
+
680
+ b64 = 'data:' + (actionUtils.mimeTypes[String(file.getExt(realImgPath))] || defaultMimeType) +
681
+ ';base64,' + b64;
682
+
683
+ editor.replaceContent('$0' + b64, pos, pos + imgPath.length);
684
+ });
685
+
686
+ return true;
687
+ }
688
+
689
+ /**
690
+ * Decodes base64 string back to file.
691
+ * @param {IEmmetEditor} editor
692
+ * @param {String} data Base64-encoded file content
693
+ * @param {Number} pos Caret position where image is located in the editor
694
+ */
695
+ function decodeFromBase64(editor, data, pos) {
696
+ // ask user to enter path to file
697
+ var filePath = String(editor.prompt('Enter path to file (absolute or relative)'));
698
+ if (!filePath)
699
+ return false;
700
+
701
+ var absPath = file.createPath(editor.getFilePath(), filePath);
702
+ if (!absPath) {
703
+ throw "Can't save file";
704
+ }
705
+
706
+ file.save(absPath, base64.decode( data.replace(/^data\:.+?;.+?,/, '') ));
707
+ editor.replaceContent('$0' + filePath, pos, pos + data.length);
708
+ return true;
709
+ }
710
+
711
+ return {
712
+ /**
713
+ * Action to encode or decode file to data:url
714
+ * @param {IEmmetEditor} editor Editor instance
715
+ * @param {String} syntax Current document syntax
716
+ * @param {String} profile Output profile name
717
+ * @return {Boolean}
718
+ */
719
+ encodeDecodeDataUrlAction: function(editor) {
720
+ var data = String(editor.getSelection());
721
+ var caretPos = editor.getCaretPos();
722
+ var info = editorUtils.outputInfo(editor);
723
+
724
+ if (!data) {
725
+ // no selection, try to find image bounds from current caret position
726
+ var text = info.content, m;
727
+ while (caretPos-- >= 0) {
728
+ if (startsWith('src=', text, caretPos)) { // found <img src="">
729
+ if ((m = text.substr(caretPos).match(/^(src=(["'])?)([^'"<>\s]+)\1?/))) {
730
+ data = m[3];
731
+ caretPos += m[1].length;
732
+ }
733
+ break;
734
+ } else if (startsWith('url(', text, caretPos)) { // found CSS url() pattern
735
+ if ((m = text.substr(caretPos).match(/^(url\((['"])?)([^'"\)\s]+)\1?/))) {
736
+ data = m[3];
737
+ caretPos += m[1].length;
738
+ }
739
+ break;
740
+ }
741
+ }
742
+ }
743
+
744
+ if (data) {
745
+ if (startsWith('data:', data)) {
746
+ return decodeFromBase64(editor, data, caretPos);
747
+ } else {
748
+ return encodeToBase64(editor, data, caretPos);
749
+ }
750
+ }
751
+
752
+ return false;
753
+ }
754
+ };
755
+ });
756
+
757
+ },{"../plugin/file":63,"../utils/action":70,"../utils/base64":71,"../utils/editor":75}],7:[function(require,module,exports){
758
+ /**
759
+ * Move between next/prev edit points. 'Edit points' are places between tags
760
+ * and quotes of empty attributes in html
761
+ */
762
+ if (typeof module === 'object' && typeof define !== 'function') {
763
+ var define = function (factory) {
764
+ module.exports = factory(require, exports, module);
765
+ };
766
+ }
767
+
768
+ define(function(require, exports, module) {
769
+ /**
770
+ * Search for new caret insertion point
771
+ * @param {IEmmetEditor} editor Editor instance
772
+ * @param {Number} inc Search increment: -1 — search left, 1 — search right
773
+ * @param {Number} offset Initial offset relative to current caret position
774
+ * @return {Number} Returns -1 if insertion point wasn't found
775
+ */
776
+ function findNewEditPoint(editor, inc, offset) {
777
+ inc = inc || 1;
778
+ offset = offset || 0;
779
+
780
+ var curPoint = editor.getCaretPos() + offset;
781
+ var content = String(editor.getContent());
782
+ var maxLen = content.length;
783
+ var nextPoint = -1;
784
+ var reEmptyLine = /^\s+$/;
785
+
786
+ function getLine(ix) {
787
+ var start = ix;
788
+ while (start >= 0) {
789
+ var c = content.charAt(start);
790
+ if (c == '\n' || c == '\r')
791
+ break;
792
+ start--;
793
+ }
794
+
795
+ return content.substring(start, ix);
796
+ }
797
+
798
+ while (curPoint <= maxLen && curPoint >= 0) {
799
+ curPoint += inc;
800
+ var curChar = content.charAt(curPoint);
801
+ var nextChar = content.charAt(curPoint + 1);
802
+ var prevChar = content.charAt(curPoint - 1);
803
+
804
+ switch (curChar) {
805
+ case '"':
806
+ case '\'':
807
+ if (nextChar == curChar && prevChar == '=') {
808
+ // empty attribute
809
+ nextPoint = curPoint + 1;
810
+ }
811
+ break;
812
+ case '>':
813
+ if (nextChar == '<') {
814
+ // between tags
815
+ nextPoint = curPoint + 1;
816
+ }
817
+ break;
818
+ case '\n':
819
+ case '\r':
820
+ // empty line
821
+ if (reEmptyLine.test(getLine(curPoint - 1))) {
822
+ nextPoint = curPoint;
823
+ }
824
+ break;
825
+ }
826
+
827
+ if (nextPoint != -1)
828
+ break;
829
+ }
830
+
831
+ return nextPoint;
832
+ }
833
+
834
+ return {
835
+ /**
836
+ * Move to previous edit point
837
+ * @param {IEmmetEditor} editor Editor instance
838
+ * @param {String} syntax Current document syntax
839
+ * @param {String} profile Output profile name
840
+ * @return {Boolean}
841
+ */
842
+ previousEditPointAction: function(editor, syntax, profile) {
843
+ var curPos = editor.getCaretPos();
844
+ var newPoint = findNewEditPoint(editor, -1);
845
+
846
+ if (newPoint == curPos)
847
+ // we're still in the same point, try searching from the other place
848
+ newPoint = findNewEditPoint(editor, -1, -2);
849
+
850
+ if (newPoint != -1) {
851
+ editor.setCaretPos(newPoint);
852
+ return true;
853
+ }
854
+
855
+ return false;
856
+ },
857
+
858
+ /**
859
+ * Move to next edit point
860
+ * @param {IEmmetEditor} editor Editor instance
861
+ * @param {String} syntax Current document syntax
862
+ * @param {String} profile Output profile name
863
+ * @return {Boolean}
864
+ */
865
+ nextEditPointAction: function(editor, syntax, profile) {
866
+ var newPoint = findNewEditPoint(editor, 1);
867
+ if (newPoint != -1) {
868
+ editor.setCaretPos(newPoint);
869
+ return true;
870
+ }
871
+
872
+ return false;
873
+ }
874
+ };
875
+ });
876
+ },{}],8:[function(require,module,exports){
877
+ /**
878
+ * Evaluates simple math expression under caret
879
+ */
880
+ if (typeof module === 'object' && typeof define !== 'function') {
881
+ var define = function (factory) {
882
+ module.exports = factory(require, exports, module);
883
+ };
884
+ }
885
+
886
+ define(function(require, exports, module) {
887
+ var actionUtils = require('../utils/action');
888
+ var utils = require('../utils/common');
889
+ var math = require('../utils/math');
890
+ var range = require('../assets/range');
891
+
892
+ return {
893
+ /**
894
+ * Evaluates math expression under the caret
895
+ * @param {IEmmetEditor} editor
896
+ * @return {Boolean}
897
+ */
898
+ evaluateMathAction: function(editor) {
899
+ var content = editor.getContent();
900
+ var chars = '.+-*/\\';
901
+
902
+ /** @type Range */
903
+ var sel = range(editor.getSelectionRange());
904
+ if (!sel.length()) {
905
+ sel = actionUtils.findExpressionBounds(editor, function(ch) {
906
+ return utils.isNumeric(ch) || chars.indexOf(ch) != -1;
907
+ });
908
+ }
909
+
910
+ if (sel && sel.length()) {
911
+ var expr = sel.substring(content);
912
+
913
+ // replace integral division: 11\2 => Math.round(11/2)
914
+ expr = expr.replace(/([\d\.\-]+)\\([\d\.\-]+)/g, 'round($1/$2)');
915
+
916
+ try {
917
+ var result = utils.prettifyNumber(math.evaluate(expr));
918
+ editor.replaceContent(result, sel.start, sel.end);
919
+ editor.setCaretPos(sel.start + result.length);
920
+ return true;
921
+ } catch (e) {}
922
+ }
923
+
924
+ return false;
925
+ }
926
+ };
927
+ });
928
+
929
+ },{"../assets/range":30,"../utils/action":70,"../utils/common":73,"../utils/math":76}],9:[function(require,module,exports){
930
+ /**
931
+ * 'Expand abbreviation' editor action: extracts abbreviation from current caret
932
+ * position and replaces it with formatted output.
933
+ * <br><br>
934
+ * This behavior can be overridden with custom handlers which can perform
935
+ * different actions when 'Expand Abbreviation' action is called.
936
+ * For example, a CSS gradient handler that produces vendor-prefixed gradient
937
+ * definitions registers its own expand abbreviation handler.
938
+ */
939
+ if (typeof module === 'object' && typeof define !== 'function') {
940
+ var define = function (factory) {
941
+ module.exports = factory(require, exports, module);
942
+ };
943
+ }
944
+
945
+ define(function(require, exports, module) {
946
+ var handlerList = require('../assets/handlerList');
947
+ var range = require('../assets/range');
948
+ var prefs = require('../assets/preferences');
949
+ var utils = require('../utils/common');
950
+ var editorUtils = require('../utils/editor');
951
+ var actionUtils = require('../utils/action');
952
+ var cssGradient = require('../resolver/cssGradient');
953
+ var parser = require('../parser/abbreviation');
954
+
955
+ /**
956
+ * Search for abbreviation in editor from current caret position
957
+ * @param {IEmmetEditor} editor Editor instance
958
+ * @return {String}
959
+ */
960
+ function findAbbreviation(editor) {
961
+ var r = range(editor.getSelectionRange());
962
+ var content = String(editor.getContent());
963
+ if (r.length()) {
964
+ // abbreviation is selected by user
965
+ return r.substring(content);
966
+ }
967
+
968
+ // search for new abbreviation from current caret position
969
+ var curLine = editor.getCurrentLineRange();
970
+ return actionUtils.extractAbbreviation(content.substring(curLine.start, r.start));
971
+ }
972
+
973
+ /**
974
+ * @type HandlerList List of registered handlers
975
+ */
976
+ var handlers = handlerList.create();
977
+
978
+ // XXX setup default expand handlers
979
+
980
+ /**
981
+ * Extracts abbreviation from current caret
982
+ * position and replaces it with formatted output
983
+ * @param {IEmmetEditor} editor Editor instance
984
+ * @param {String} syntax Syntax type (html, css, etc.)
985
+ * @param {String} profile Output profile name (html, xml, xhtml)
986
+ * @return {Boolean} Returns <code>true</code> if abbreviation was expanded
987
+ * successfully
988
+ */
989
+ handlers.add(function(editor, syntax, profile) {
990
+ var caretPos = editor.getSelectionRange().end;
991
+ var abbr = findAbbreviation(editor);
992
+
993
+ if (abbr) {
994
+ var content = parser.expand(abbr, {
995
+ syntax: syntax,
996
+ profile: profile,
997
+ contextNode: actionUtils.captureContext(editor)
998
+ });
999
+
1000
+ if (content) {
1001
+ var replaceFrom = caretPos - abbr.length;
1002
+ var replaceTo = caretPos;
1003
+
1004
+ // a special case for CSS: if editor already contains
1005
+ // semicolon right after current caret position — replace it too
1006
+ var cssSyntaxes = prefs.getArray('css.syntaxes');
1007
+ if (cssSyntaxes && ~cssSyntaxes.indexOf(syntax)) {
1008
+ var curContent = editor.getContent();
1009
+ if (curContent.charAt(caretPos) == ';' && content.charAt(content.length - 1) == ';') {
1010
+ replaceTo++;
1011
+ }
1012
+ }
1013
+
1014
+ editor.replaceContent(content, replaceFrom, replaceTo);
1015
+ return true;
1016
+ }
1017
+ }
1018
+
1019
+ return false;
1020
+ }, {order: -1});
1021
+ handlers.add(cssGradient.expandAbbreviationHandler.bind(cssGradient));
1022
+
1023
+ return {
1024
+ /**
1025
+ * The actual “Expand Abbreviation“ action routine
1026
+ * @param {IEmmetEditor} editor Editor instance
1027
+ * @param {String} syntax Current document syntax
1028
+ * @param {String} profile Output profile name
1029
+ * @return {Boolean}
1030
+ */
1031
+ expandAbbreviationAction: function(editor, syntax, profile) {
1032
+ var args = utils.toArray(arguments);
1033
+
1034
+ // normalize incoming arguments
1035
+ var info = editorUtils.outputInfo(editor, syntax, profile);
1036
+ args[1] = info.syntax;
1037
+ args[2] = info.profile;
1038
+
1039
+ return handlers.exec(false, args);
1040
+ },
1041
+
1042
+ /**
1043
+ * A special case of “Expand Abbreviation“ action, invoked by Tab key.
1044
+ * In this case if abbreviation wasn’t expanded successfully or there’s a selecetion,
1045
+ * the current line/selection will be indented.
1046
+ * @param {IEmmetEditor} editor Editor instance
1047
+ * @param {String} syntax Current document syntax
1048
+ * @param {String} profile Output profile name
1049
+ * @return {Boolean}
1050
+ */
1051
+ expandAbbreviationWithTabAction: function(editor, syntax, profile) {
1052
+ var sel = editor.getSelection();
1053
+ var indent = '\t';
1054
+
1055
+ // if something is selected in editor,
1056
+ // we should indent the selected content
1057
+ if (sel) {
1058
+ var selRange = range(editor.getSelectionRange());
1059
+ var content = utils.padString(sel, indent);
1060
+
1061
+ editor.replaceContent(indent + '${0}', editor.getCaretPos());
1062
+ var replaceRange = range(editor.getCaretPos(), selRange.length());
1063
+ editor.replaceContent(content, replaceRange.start, replaceRange.end, true);
1064
+ editor.createSelection(replaceRange.start, replaceRange.start + content.length);
1065
+ return true;
1066
+ }
1067
+
1068
+ // nothing selected, try to expand
1069
+ if (!this.expandAbbreviationAction(editor, syntax, profile)) {
1070
+ editor.replaceContent(indent, editor.getCaretPos());
1071
+ }
1072
+
1073
+ return true;
1074
+ },
1075
+
1076
+
1077
+ _defaultHandler: function(editor, syntax, profile) {
1078
+ var caretPos = editor.getSelectionRange().end;
1079
+ var abbr = this.findAbbreviation(editor);
1080
+
1081
+ if (abbr) {
1082
+ var ctx = actionUtils.captureContext(editor);
1083
+ var content = parser.expand(abbr, syntax, profile, ctx);
1084
+ if (content) {
1085
+ editor.replaceContent(content, caretPos - abbr.length, caretPos);
1086
+ return true;
1087
+ }
1088
+ }
1089
+
1090
+ return false;
1091
+ },
1092
+
1093
+ /**
1094
+ * Adds custom expand abbreviation handler. The passed function should
1095
+ * return <code>true</code> if it was performed successfully,
1096
+ * <code>false</code> otherwise.
1097
+ *
1098
+ * Added handlers will be called when 'Expand Abbreviation' is called
1099
+ * in order they were added
1100
+ * @memberOf expandAbbreviation
1101
+ * @param {Function} fn
1102
+ * @param {Object} options
1103
+ */
1104
+ addHandler: function(fn, options) {
1105
+ handlers.add(fn, options);
1106
+ },
1107
+
1108
+ /**
1109
+ * Removes registered handler
1110
+ * @returns
1111
+ */
1112
+ removeHandler: function(fn) {
1113
+ handlers.remove(fn);
1114
+ },
1115
+
1116
+ findAbbreviation: findAbbreviation
1117
+ };
1118
+ });
1119
+ },{"../assets/handlerList":25,"../assets/preferences":28,"../assets/range":30,"../parser/abbreviation":55,"../resolver/cssGradient":65,"../utils/action":70,"../utils/common":73,"../utils/editor":75}],10:[function(require,module,exports){
1120
+ /**
1121
+ * Increment/decrement number under cursor
1122
+ */
1123
+ if (typeof module === 'object' && typeof define !== 'function') {
1124
+ var define = function (factory) {
1125
+ module.exports = factory(require, exports, module);
1126
+ };
1127
+ }
1128
+
1129
+ define(function(require, exports, module) {
1130
+ var utils = require('../utils/common');
1131
+ var actionUtils = require('../utils/action');
1132
+
1133
+ /**
1134
+ * Returns length of integer part of number
1135
+ * @param {String} num
1136
+ */
1137
+ function intLength(num) {
1138
+ num = num.replace(/^\-/, '');
1139
+ if (~num.indexOf('.')) {
1140
+ return num.split('.')[0].length;
1141
+ }
1142
+
1143
+ return num.length;
1144
+ }
1145
+
1146
+ return {
1147
+ increment01Action: function(editor) {
1148
+ return this.incrementNumber(editor, .1);
1149
+ },
1150
+
1151
+ increment1Action: function(editor) {
1152
+ return this.incrementNumber(editor, 1);
1153
+ },
1154
+
1155
+ increment10Action: function(editor) {
1156
+ return this.incrementNumber(editor, 10);
1157
+ },
1158
+
1159
+ decrement01Action: function(editor) {
1160
+ return this.incrementNumber(editor, -.1);
1161
+ },
1162
+
1163
+ decrement1Action: function(editor) {
1164
+ return this.incrementNumber(editor, -1);
1165
+ },
1166
+
1167
+ decrement10Action: function(editor) {
1168
+ return this.incrementNumber(editor, -10);
1169
+ },
1170
+
1171
+ /**
1172
+ * Default method to increment/decrement number under
1173
+ * caret with given step
1174
+ * @param {IEmmetEditor} editor
1175
+ * @param {Number} step
1176
+ * @return {Boolean}
1177
+ */
1178
+ incrementNumber: function(editor, step) {
1179
+ var hasSign = false;
1180
+ var hasDecimal = false;
1181
+
1182
+ var r = actionUtils.findExpressionBounds(editor, function(ch, pos, content) {
1183
+ if (utils.isNumeric(ch))
1184
+ return true;
1185
+ if (ch == '.') {
1186
+ // make sure that next character is numeric too
1187
+ if (!utils.isNumeric(content.charAt(pos + 1)))
1188
+ return false;
1189
+
1190
+ return hasDecimal ? false : hasDecimal = true;
1191
+ }
1192
+ if (ch == '-')
1193
+ return hasSign ? false : hasSign = true;
1194
+
1195
+ return false;
1196
+ });
1197
+
1198
+ if (r && r.length()) {
1199
+ var strNum = r.substring(String(editor.getContent()));
1200
+ var num = parseFloat(strNum);
1201
+ if (!isNaN(num)) {
1202
+ num = utils.prettifyNumber(num + step);
1203
+
1204
+ // do we have zero-padded number?
1205
+ if (/^(\-?)0+[1-9]/.test(strNum)) {
1206
+ var minus = '';
1207
+ if (RegExp.$1) {
1208
+ minus = '-';
1209
+ num = num.substring(1);
1210
+ }
1211
+
1212
+ var parts = num.split('.');
1213
+ parts[0] = utils.zeroPadString(parts[0], intLength(strNum));
1214
+ num = minus + parts.join('.');
1215
+ }
1216
+
1217
+ editor.replaceContent(num, r.start, r.end);
1218
+ editor.createSelection(r.start, r.start + num.length);
1219
+ return true;
1220
+ }
1221
+ }
1222
+
1223
+ return false;
1224
+ }
1225
+ };
1226
+ });
1227
+ },{"../utils/action":70,"../utils/common":73}],11:[function(require,module,exports){
1228
+ /**
1229
+ * Actions to insert line breaks. Some simple editors (like browser's
1230
+ * &lt;textarea&gt;, for example) do not provide such simple things
1231
+ */
1232
+ if (typeof module === 'object' && typeof define !== 'function') {
1233
+ var define = function (factory) {
1234
+ module.exports = factory(require, exports, module);
1235
+ };
1236
+ }
1237
+
1238
+ define(function(require, exports, module) {
1239
+ var prefs = require('../assets/preferences');
1240
+ var utils = require('../utils/common');
1241
+ var resources = require('../assets/resources');
1242
+ var htmlMatcher = require('../assets/htmlMatcher');
1243
+ var editorUtils = require('../utils/editor');
1244
+
1245
+ var xmlSyntaxes = ['html', 'xml', 'xsl'];
1246
+
1247
+ // setup default preferences
1248
+ prefs.define('css.closeBraceIndentation', '\n',
1249
+ 'Indentation before closing brace of CSS rule. Some users prefere '
1250
+ + 'indented closing brace of CSS rule for better readability. '
1251
+ + 'This preference’s value will be automatically inserted before '
1252
+ + 'closing brace when user adds newline in newly created CSS rule '
1253
+ + '(e.g. when “Insert formatted linebreak” action will be performed '
1254
+ + 'in CSS file). If you’re such user, you may want to write put a value '
1255
+ + 'like <code>\\n\\t</code> in this preference.');
1256
+
1257
+ return {
1258
+ /**
1259
+ * Inserts newline character with proper indentation. This action is used in
1260
+ * editors that doesn't have indentation control (like textarea element) to
1261
+ * provide proper indentation for inserted newlines
1262
+ * @param {IEmmetEditor} editor Editor instance
1263
+ */
1264
+ insertLineBreakAction: function(editor) {
1265
+ if (!this.insertLineBreakOnlyAction(editor)) {
1266
+ var curPadding = editorUtils.getCurrentLinePadding(editor);
1267
+ var content = String(editor.getContent());
1268
+ var caretPos = editor.getCaretPos();
1269
+ var len = content.length;
1270
+ var nl = '\n';
1271
+
1272
+ // check out next line padding
1273
+ var lineRange = editor.getCurrentLineRange();
1274
+ var nextPadding = '';
1275
+
1276
+ for (var i = lineRange.end + 1, ch; i < len; i++) {
1277
+ ch = content.charAt(i);
1278
+ if (ch == ' ' || ch == '\t')
1279
+ nextPadding += ch;
1280
+ else
1281
+ break;
1282
+ }
1283
+
1284
+ if (nextPadding.length > curPadding.length) {
1285
+ editor.replaceContent(nl + nextPadding, caretPos, caretPos, true);
1286
+ } else {
1287
+ editor.replaceContent(nl, caretPos);
1288
+ }
1289
+ }
1290
+
1291
+ return true;
1292
+ },
1293
+
1294
+ /**
1295
+ * Inserts newline character with proper indentation in specific positions only.
1296
+ * @param {IEmmetEditor} editor
1297
+ * @return {Boolean} Returns <code>true</code> if line break was inserted
1298
+ */
1299
+ insertLineBreakOnlyAction: function(editor) {
1300
+ var info = editorUtils.outputInfo(editor);
1301
+ var caretPos = editor.getCaretPos();
1302
+ var nl = '\n';
1303
+ var pad = '\t';
1304
+
1305
+ if (~xmlSyntaxes.indexOf(info.syntax)) {
1306
+ // let's see if we're breaking newly created tag
1307
+ var tag = htmlMatcher.tag(info.content, caretPos);
1308
+ if (tag && !tag.innerRange.length()) {
1309
+ editor.replaceContent(nl + pad + utils.getCaretPlaceholder() + nl, caretPos);
1310
+ return true;
1311
+ }
1312
+ } else if (info.syntax == 'css') {
1313
+ /** @type String */
1314
+ var content = info.content;
1315
+ if (caretPos && content.charAt(caretPos - 1) == '{') {
1316
+ var append = prefs.get('css.closeBraceIndentation');
1317
+
1318
+ var hasCloseBrace = content.charAt(caretPos) == '}';
1319
+ if (!hasCloseBrace) {
1320
+ // do we really need special formatting here?
1321
+ // check if this is really a newly created rule,
1322
+ // look ahead for a closing brace
1323
+ for (var i = caretPos, il = content.length, ch; i < il; i++) {
1324
+ ch = content.charAt(i);
1325
+ if (ch == '{') {
1326
+ // ok, this is a new rule without closing brace
1327
+ break;
1328
+ }
1329
+
1330
+ if (ch == '}') {
1331
+ // not a new rule, just add indentation
1332
+ append = '';
1333
+ hasCloseBrace = true;
1334
+ break;
1335
+ }
1336
+ }
1337
+ }
1338
+
1339
+ if (!hasCloseBrace) {
1340
+ append += '}';
1341
+ }
1342
+
1343
+ // defining rule set
1344
+ var insValue = nl + pad + utils.getCaretPlaceholder() + append;
1345
+ editor.replaceContent(insValue, caretPos);
1346
+ return true;
1347
+ }
1348
+ }
1349
+
1350
+ return false;
1351
+ }
1352
+ };
1353
+ });
1354
+ },{"../assets/htmlMatcher":26,"../assets/preferences":28,"../assets/resources":31,"../utils/common":73,"../utils/editor":75}],12:[function(require,module,exports){
1355
+ /**
1356
+ * Module describes and performs Emmet actions. The actions themselves are
1357
+ * defined in <i>actions</i> folder
1358
+ */
1359
+ if (typeof module === 'object' && typeof define !== 'function') {
1360
+ var define = function (factory) {
1361
+ module.exports = factory(require, exports, module);
1362
+ };
1363
+ }
1364
+
1365
+ define(function(require, exports, module) {
1366
+ var utils = require('../utils/common');
1367
+
1368
+ // all registered actions
1369
+ var actions = {};
1370
+
1371
+ // load all default actions
1372
+ var actionModules = {
1373
+ base64: require('./base64'),
1374
+ editPoints: require('./editPoints'),
1375
+ evaluateMath: require('./evaluateMath'),
1376
+ expandAbbreviation: require('./expandAbbreviation'),
1377
+ incrementDecrement: require('./incrementDecrement'),
1378
+ lineBreaks: require('./lineBreaks'),
1379
+ balance: require('./balance'),
1380
+ mergeLines: require('./mergeLines'),
1381
+ reflectCSSValue: require('./reflectCSSValue'),
1382
+ removeTag: require('./removeTag'),
1383
+ selectItem: require('./selectItem'),
1384
+ selectLine: require('./selectLine'),
1385
+ splitJoinTag: require('./splitJoinTag'),
1386
+ toggleComment: require('./toggleComment'),
1387
+ updateImageSize: require('./updateImageSize'),
1388
+ wrapWithAbbreviation: require('./wrapWithAbbreviation'),
1389
+ updateTag: require('./updateTag')
1390
+ };
1391
+
1392
+ function addAction(name, fn, options) {
1393
+ name = name.toLowerCase();
1394
+ options = options || {};
1395
+
1396
+ if (typeof options === 'string') {
1397
+ options = {label: options};
1398
+ }
1399
+
1400
+ if (!options.label) {
1401
+ options.label = humanizeActionName(name);
1402
+ }
1403
+
1404
+ actions[name] = {
1405
+ name: name,
1406
+ fn: fn,
1407
+ options: options
1408
+ };
1409
+ }
1410
+
1411
+ /**
1412
+ * “Humanizes” action name, makes it more readable for people
1413
+ * @param {String} name Action name (like 'expand_abbreviation')
1414
+ * @return Humanized name (like 'Expand Abbreviation')
1415
+ */
1416
+ function humanizeActionName(name) {
1417
+ return utils.trim(name.charAt(0).toUpperCase()
1418
+ + name.substring(1).replace(/_[a-z]/g, function(str) {
1419
+ return ' ' + str.charAt(1).toUpperCase();
1420
+ }));
1421
+ }
1422
+
1423
+ var bind = function(name, method) {
1424
+ var m = actionModules[name];
1425
+ return m[method].bind(m);
1426
+ };
1427
+
1428
+ // XXX register default actions
1429
+ addAction('encode_decode_data_url', bind('base64', 'encodeDecodeDataUrlAction'), 'Encode\\Decode data:URL image');
1430
+ addAction('prev_edit_point', bind('editPoints', 'previousEditPointAction'), 'Previous Edit Point');
1431
+ addAction('next_edit_point', bind('editPoints', 'nextEditPointAction'), 'Next Edit Point');
1432
+ addAction('evaluate_math_expression', bind('evaluateMath', 'evaluateMathAction'), 'Numbers/Evaluate Math Expression');
1433
+ addAction('expand_abbreviation_with_tab', bind('expandAbbreviation', 'expandAbbreviationWithTabAction'), {hidden: true});
1434
+ addAction('expand_abbreviation', bind('expandAbbreviation', 'expandAbbreviationAction'), 'Expand Abbreviation');
1435
+ addAction('insert_formatted_line_break_only', bind('lineBreaks', 'insertLineBreakOnlyAction'), {hidden: true});
1436
+ addAction('insert_formatted_line_break', bind('lineBreaks', 'insertLineBreakAction'), {hidden: true});
1437
+ addAction('balance_inward', bind('balance', 'balanceInwardAction'), 'Balance (inward)');
1438
+ addAction('balance_outward', bind('balance', 'balanceOutwardAction'), 'Balance (outward)');
1439
+ addAction('matching_pair', bind('balance', 'goToMatchingPairAction'), 'HTML/Go To Matching Tag Pair');
1440
+ addAction('merge_lines', bind('mergeLines', 'mergeLinesAction'), 'Merge Lines');
1441
+ addAction('reflect_css_value', bind('reflectCSSValue', 'reflectCSSValueAction'), 'CSS/Reflect Value');
1442
+ addAction('remove_tag', bind('removeTag', 'removeTagAction'), 'HTML/Remove Tag');
1443
+ addAction('select_next_item', bind('selectItem', 'selectNextItemAction'), 'Select Next Item');
1444
+ addAction('select_previous_item', bind('selectItem', 'selectPreviousItemAction'), 'Select Previous Item');
1445
+ addAction('split_join_tag', bind('splitJoinTag', 'splitJoinTagAction'), 'HTML/Split\\Join Tag Declaration');
1446
+ addAction('toggle_comment', bind('toggleComment', 'toggleCommentAction'), 'Toggle Comment');
1447
+ addAction('update_image_size', bind('updateImageSize', 'updateImageSizeAction'), 'Update Image Size');
1448
+ addAction('wrap_with_abbreviation', bind('wrapWithAbbreviation', 'wrapWithAbbreviationAction'), 'Wrap With Abbreviation');
1449
+ addAction('update_tag', bind('updateTag', 'updateTagAction'), 'HTML/Update Tag');
1450
+
1451
+ [1, -1, 10, -10, 0.1, -0.1].forEach(function(num) {
1452
+ var prefix = num > 0 ? 'increment' : 'decrement';
1453
+ var suffix = String(Math.abs(num)).replace('.', '').substring(0, 2);
1454
+ var actionId = prefix + '_number_by_' + suffix;
1455
+ var actionMethod = prefix + suffix + 'Action';
1456
+ var actionLabel = 'Numbers/' + prefix.charAt(0).toUpperCase() + prefix.substring(1) + ' number by ' + Math.abs(num);
1457
+ addAction(actionId, bind('incrementDecrement', actionMethod), actionLabel);
1458
+ });
1459
+
1460
+ return {
1461
+ /**
1462
+ * Registers new action
1463
+ * @param {String} name Action name
1464
+ * @param {Function} fn Action function
1465
+ * @param {Object} options Custom action options:<br>
1466
+ * <b>label</b> : (<code>String</code>) – Human-readable action name.
1467
+ * May contain '/' symbols as submenu separators<br>
1468
+ * <b>hidden</b> : (<code>Boolean</code>) – Indicates whether action
1469
+ * should be displayed in menu (<code>getMenu()</code> method)
1470
+ */
1471
+ add: addAction,
1472
+
1473
+ /**
1474
+ * Returns action object
1475
+ * @param {String} name Action name
1476
+ * @returns {Object}
1477
+ */
1478
+ get: function(name) {
1479
+ return actions[name.toLowerCase()];
1480
+ },
1481
+
1482
+ /**
1483
+ * Runs Emmet action. For list of available actions and their
1484
+ * arguments see <i>actions</i> folder.
1485
+ * @param {String} name Action name
1486
+ * @param {Array} args Additional arguments. It may be array of arguments
1487
+ * or inline arguments. The first argument should be <code>IEmmetEditor</code> instance
1488
+ * @returns {Boolean} Status of performed operation, <code>true</code>
1489
+ * means action was performed successfully.
1490
+ * @example
1491
+ * require('action/main').run('expand_abbreviation', editor);
1492
+ * require('action/main').run('wrap_with_abbreviation', [editor, 'div']);
1493
+ */
1494
+ run: function(name, args) {
1495
+ if (!Array.isArray(args)) {
1496
+ args = utils.toArray(arguments, 1);
1497
+ }
1498
+
1499
+ var action = this.get(name);
1500
+ if (!action) {
1501
+ throw new Error('Action "' + name + '" is not defined');
1502
+ }
1503
+
1504
+ return action.fn.apply(action, args);
1505
+ },
1506
+
1507
+ /**
1508
+ * Returns all registered actions as object
1509
+ * @returns {Object}
1510
+ */
1511
+ getAll: function() {
1512
+ return actions;
1513
+ },
1514
+
1515
+ /**
1516
+ * Returns all registered actions as array
1517
+ * @returns {Array}
1518
+ */
1519
+ getList: function() {
1520
+ var all = this.getAll();
1521
+ return Object.keys(all).map(function(key) {
1522
+ return all[key];
1523
+ });
1524
+ },
1525
+
1526
+ /**
1527
+ * Returns actions list as structured menu. If action has <i>label</i>,
1528
+ * it will be splitted by '/' symbol into submenus (for example:
1529
+ * CSS/Reflect Value) and grouped with other items
1530
+ * @param {Array} skipActions List of action identifiers that should be
1531
+ * skipped from menu
1532
+ * @returns {Array}
1533
+ */
1534
+ getMenu: function(skipActions) {
1535
+ var result = [];
1536
+ skipActions = skipActions || [];
1537
+ this.getList().forEach(function(action) {
1538
+ if (action.options.hidden || ~skipActions.indexOf(action.name))
1539
+ return;
1540
+
1541
+ var actionName = humanizeActionName(action.name);
1542
+ var ctx = result;
1543
+ if (action.options.label) {
1544
+ var parts = action.options.label.split('/');
1545
+ actionName = parts.pop();
1546
+
1547
+ // create submenus, if needed
1548
+ var menuName, submenu;
1549
+ while ((menuName = parts.shift())) {
1550
+ submenu = utils.find(ctx, function(item) {
1551
+ return item.type == 'submenu' && item.name == menuName;
1552
+ });
1553
+
1554
+ if (!submenu) {
1555
+ submenu = {
1556
+ name: menuName,
1557
+ type: 'submenu',
1558
+ items: []
1559
+ };
1560
+ ctx.push(submenu);
1561
+ }
1562
+
1563
+ ctx = submenu.items;
1564
+ }
1565
+ }
1566
+
1567
+ ctx.push({
1568
+ type: 'action',
1569
+ name: action.name,
1570
+ label: actionName
1571
+ });
1572
+ });
1573
+
1574
+ return result;
1575
+ },
1576
+
1577
+ /**
1578
+ * Returns action name associated with menu item title
1579
+ * @param {String} title
1580
+ * @returns {String}
1581
+ */
1582
+ getActionNameForMenuTitle: function(title, menu) {
1583
+ return utils.find(menu || this.getMenu(), function(val) {
1584
+ if (val.type == 'action') {
1585
+ if (val.label == title || val.name == title) {
1586
+ return val.name;
1587
+ }
1588
+ } else {
1589
+ return this.getActionNameForMenuTitle(title, val.items);
1590
+ }
1591
+ }, this);
1592
+ }
1593
+ };
1594
+ });
1595
+ },{"../utils/common":73,"./balance":5,"./base64":6,"./editPoints":7,"./evaluateMath":8,"./expandAbbreviation":9,"./incrementDecrement":10,"./lineBreaks":11,"./mergeLines":13,"./reflectCSSValue":14,"./removeTag":15,"./selectItem":16,"./selectLine":17,"./splitJoinTag":18,"./toggleComment":19,"./updateImageSize":20,"./updateTag":21,"./wrapWithAbbreviation":22}],13:[function(require,module,exports){
1596
+ /**
1597
+ * Merges selected lines or lines between XHTML tag pairs
1598
+ * @param {Function} require
1599
+ * @param {Underscore} _
1600
+ */
1601
+ if (typeof module === 'object' && typeof define !== 'function') {
1602
+ var define = function (factory) {
1603
+ module.exports = factory(require, exports, module);
1604
+ };
1605
+ }
1606
+
1607
+ define(function(require, exports, module) {
1608
+ var htmlMatcher = require('../assets/htmlMatcher');
1609
+ var utils = require('../utils/common');
1610
+ var editorUtils = require('../utils/editor');
1611
+ var range = require('../assets/range');
1612
+
1613
+ return {
1614
+ mergeLinesAction: function(editor) {
1615
+ var info = editorUtils.outputInfo(editor);
1616
+
1617
+ var selection = range(editor.getSelectionRange());
1618
+ if (!selection.length()) {
1619
+ // find matching tag
1620
+ var pair = htmlMatcher.find(info.content, editor.getCaretPos());
1621
+ if (pair) {
1622
+ selection = pair.outerRange;
1623
+ }
1624
+ }
1625
+
1626
+ if (selection.length()) {
1627
+ // got range, merge lines
1628
+ var text = selection.substring(info.content);
1629
+ var lines = utils.splitByLines(text);
1630
+
1631
+ for (var i = 1; i < lines.length; i++) {
1632
+ lines[i] = lines[i].replace(/^\s+/, '');
1633
+ }
1634
+
1635
+ text = lines.join('').replace(/\s{2,}/, ' ');
1636
+ var textLen = text.length;
1637
+ text = utils.escapeText(text);
1638
+ editor.replaceContent(text, selection.start, selection.end);
1639
+ editor.createSelection(selection.start, selection.start + textLen);
1640
+
1641
+ return true;
1642
+ }
1643
+
1644
+ return false;
1645
+ }
1646
+ };
1647
+ });
1648
+ },{"../assets/htmlMatcher":26,"../assets/range":30,"../utils/common":73,"../utils/editor":75}],14:[function(require,module,exports){
1649
+ /**
1650
+ * Reflect CSS value: takes rule's value under caret and pastes it for the same
1651
+ * rules with vendor prefixes
1652
+ */
1653
+ if (typeof module === 'object' && typeof define !== 'function') {
1654
+ var define = function (factory) {
1655
+ module.exports = factory(require, exports, module);
1656
+ };
1657
+ }
1658
+
1659
+ define(function(require, exports, module) {
1660
+ var handlerList = require('../assets/handlerList');
1661
+ var prefs = require('../assets/preferences');
1662
+ var cssResolver = require('../resolver/css');
1663
+ var cssEditTree = require('../editTree/css');
1664
+ var utils = require('../utils/common');
1665
+ var actionUtils = require('../utils/action');
1666
+ var editorUtils = require('../utils/editor');
1667
+ var cssGradient = require('../resolver/cssGradient');
1668
+
1669
+ prefs.define('css.reflect.oldIEOpacity', false, 'Support IE6/7/8 opacity notation, e.g. <code>filter:alpha(opacity=...)</code>.\
1670
+ Note that CSS3 and SVG also provides <code>filter</code> property so this option is disabled by default.')
1671
+
1672
+ /**
1673
+ * @type HandlerList List of registered handlers
1674
+ */
1675
+ var handlers = handlerList.create();
1676
+
1677
+ function doCSSReflection(editor) {
1678
+ var outputInfo = editorUtils.outputInfo(editor);
1679
+ var caretPos = editor.getCaretPos();
1680
+
1681
+ var cssRule = cssEditTree.parseFromPosition(outputInfo.content, caretPos);
1682
+ if (!cssRule) return;
1683
+
1684
+ var property = cssRule.itemFromPosition(caretPos, true);
1685
+ // no property under cursor, nothing to reflect
1686
+ if (!property) return;
1687
+
1688
+ var oldRule = cssRule.source;
1689
+ var offset = cssRule.options.offset;
1690
+ var caretDelta = caretPos - offset - property.range().start;
1691
+
1692
+ handlers.exec(false, [property]);
1693
+
1694
+ if (oldRule !== cssRule.source) {
1695
+ return {
1696
+ data: cssRule.source,
1697
+ start: offset,
1698
+ end: offset + oldRule.length,
1699
+ caret: offset + property.range().start + caretDelta
1700
+ };
1701
+ }
1702
+ }
1703
+
1704
+ /**
1705
+ * Returns regexp that should match reflected CSS property names
1706
+ * @param {String} name Current CSS property name
1707
+ * @return {RegExp}
1708
+ */
1709
+ function getReflectedCSSName(name) {
1710
+ name = cssEditTree.baseName(name);
1711
+ var vendorPrefix = '^(?:\\-\\w+\\-)?', m;
1712
+
1713
+ if ((name == 'opacity' || name == 'filter') && prefs.get('css.reflect.oldIEOpacity')) {
1714
+ return new RegExp(vendorPrefix + '(?:opacity|filter)$');
1715
+ } else if ((m = name.match(/^border-radius-(top|bottom)(left|right)/))) {
1716
+ // Mozilla-style border radius
1717
+ return new RegExp(vendorPrefix + '(?:' + name + '|border-' + m[1] + '-' + m[2] + '-radius)$');
1718
+ } else if ((m = name.match(/^border-(top|bottom)-(left|right)-radius/))) {
1719
+ return new RegExp(vendorPrefix + '(?:' + name + '|border-radius-' + m[1] + m[2] + ')$');
1720
+ }
1721
+
1722
+ return new RegExp(vendorPrefix + name + '$');
1723
+ }
1724
+
1725
+ /**
1726
+ * Reflects inner CSS properites in given value
1727
+ * agains name‘s vendor prefix. In other words, it tries
1728
+ * to modify `transform 0.2s linear` value for `-webkit-transition`
1729
+ * property
1730
+ * @param {String} name Reciever CSS property name
1731
+ * @param {String} value New property value
1732
+ * @return {String}
1733
+ */
1734
+ function reflectValueParts(name, value) {
1735
+ // detects and updates vendor-specific properties in value,
1736
+ // e.g. -webkit-transition: -webkit-transform
1737
+
1738
+ var reVendor = /^\-(\w+)\-/;
1739
+ var propPrefix = reVendor.test(name) ? RegExp.$1.toLowerCase() : '';
1740
+ var parts = cssEditTree.findParts(value);
1741
+
1742
+ parts.reverse();
1743
+ parts.forEach(function(part) {
1744
+ var partValue = part.substring(value).replace(reVendor, '');
1745
+ var prefixes = cssResolver.vendorPrefixes(partValue);
1746
+ if (prefixes) {
1747
+ // if prefixes are not null then given value can
1748
+ // be resolved against Can I Use database and may or
1749
+ // may not contain prefixed variant
1750
+ if (propPrefix && ~prefixes.indexOf(propPrefix)) {
1751
+ partValue = '-' + propPrefix + '-' + partValue;
1752
+ }
1753
+
1754
+ value = utils.replaceSubstring(value, partValue, part);
1755
+ }
1756
+ });
1757
+
1758
+ return value;
1759
+ }
1760
+
1761
+ /**
1762
+ * Reflects value from <code>donor</code> into <code>receiver</code>
1763
+ * @param {CSSProperty} donor Donor CSS property from which value should
1764
+ * be reflected
1765
+ * @param {CSSProperty} receiver Property that should receive reflected
1766
+ * value from donor
1767
+ */
1768
+ function reflectValue(donor, receiver) {
1769
+ var value = getReflectedValue(donor.name(), donor.value(),
1770
+ receiver.name(), receiver.value());
1771
+
1772
+ value = reflectValueParts(receiver.name(), value);
1773
+ receiver.value(value);
1774
+ }
1775
+
1776
+ /**
1777
+ * Returns value that should be reflected for <code>refName</code> CSS property
1778
+ * from <code>curName</code> property. This function is used for special cases,
1779
+ * when the same result must be achieved with different properties for different
1780
+ * browsers. For example: opаcity:0.5; → filter:alpha(opacity=50);<br><br>
1781
+ *
1782
+ * This function does value conversion between different CSS properties
1783
+ *
1784
+ * @param {String} curName Current CSS property name
1785
+ * @param {String} curValue Current CSS property value
1786
+ * @param {String} refName Receiver CSS property's name
1787
+ * @param {String} refValue Receiver CSS property's value
1788
+ * @return {String} New value for receiver property
1789
+ */
1790
+ function getReflectedValue(curName, curValue, refName, refValue) {
1791
+ curName = cssEditTree.baseName(curName);
1792
+ refName = cssEditTree.baseName(refName);
1793
+
1794
+ if (curName == 'opacity' && refName == 'filter') {
1795
+ return refValue.replace(/opacity=[^)]*/i, 'opacity=' + Math.floor(parseFloat(curValue) * 100));
1796
+ } else if (curName == 'filter' && refName == 'opacity') {
1797
+ var m = curValue.match(/opacity=([^)]*)/i);
1798
+ return m ? utils.prettifyNumber(parseInt(m[1], 10) / 100) : refValue;
1799
+ }
1800
+
1801
+ return curValue;
1802
+ }
1803
+
1804
+ module = module || {};
1805
+ module.exports = {
1806
+ reflectCSSValueAction: function(editor) {
1807
+ if (editor.getSyntax() != 'css') {
1808
+ return false;
1809
+ }
1810
+
1811
+ return actionUtils.compoundUpdate(editor, doCSSReflection(editor));
1812
+ },
1813
+
1814
+ _defaultHandler: function(property) {
1815
+ var reName = getReflectedCSSName(property.name());
1816
+ property.parent.list().forEach(function(p) {
1817
+ if (reName.test(p.name())) {
1818
+ reflectValue(property, p);
1819
+ }
1820
+ });
1821
+ },
1822
+
1823
+ /**
1824
+ * Adds custom reflect handler. The passed function will receive matched
1825
+ * CSS property (as <code>CSSEditElement</code> object) and should
1826
+ * return <code>true</code> if it was performed successfully (handled
1827
+ * reflection), <code>false</code> otherwise.
1828
+ * @param {Function} fn
1829
+ * @param {Object} options
1830
+ */
1831
+ addHandler: function(fn, options) {
1832
+ handlers.add(fn, options);
1833
+ },
1834
+
1835
+ /**
1836
+ * Removes registered handler
1837
+ * @returns
1838
+ */
1839
+ removeHandler: function(fn) {
1840
+ handlers.remove(fn);
1841
+ }
1842
+ };
1843
+
1844
+ // XXX add default handlers
1845
+ handlers.add(module.exports._defaultHandler.bind(module.exports), {order: -1});
1846
+ handlers.add(cssGradient.reflectValueHandler.bind(cssGradient));
1847
+
1848
+ return module.exports;
1849
+ });
1850
+ },{"../assets/handlerList":25,"../assets/preferences":28,"../editTree/css":37,"../resolver/css":64,"../resolver/cssGradient":65,"../utils/action":70,"../utils/common":73,"../utils/editor":75}],15:[function(require,module,exports){
1851
+ /**
1852
+ * Gracefully removes tag under cursor
1853
+ */
1854
+ if (typeof module === 'object' && typeof define !== 'function') {
1855
+ var define = function (factory) {
1856
+ module.exports = factory(require, exports, module);
1857
+ };
1858
+ }
1859
+
1860
+ define(function(require, exports, module) {
1861
+ var utils = require('../utils/common');
1862
+ var editorUtils = require('../utils/editor');
1863
+ var htmlMatcher = require('../assets/htmlMatcher');
1864
+
1865
+ return {
1866
+ removeTagAction: function(editor) {
1867
+ var info = editorUtils.outputInfo(editor);
1868
+
1869
+ // search for tag
1870
+ var tag = htmlMatcher.tag(info.content, editor.getCaretPos());
1871
+ if (tag) {
1872
+ if (!tag.close) {
1873
+ // simply remove unary tag
1874
+ editor.replaceContent(utils.getCaretPlaceholder(), tag.range.start, tag.range.end);
1875
+ } else {
1876
+ // remove tag and its newlines
1877
+ /** @type Range */
1878
+ var tagContentRange = utils.narrowToNonSpace(info.content, tag.innerRange);
1879
+ /** @type Range */
1880
+ var startLineBounds = utils.findNewlineBounds(info.content, tagContentRange.start);
1881
+ var startLinePad = utils.getLinePadding(startLineBounds.substring(info.content));
1882
+ var tagContent = tagContentRange.substring(info.content);
1883
+
1884
+ tagContent = utils.unindentString(tagContent, startLinePad);
1885
+ editor.replaceContent(utils.getCaretPlaceholder() + utils.escapeText(tagContent), tag.outerRange.start, tag.outerRange.end);
1886
+ }
1887
+
1888
+ return true;
1889
+ }
1890
+
1891
+ return false;
1892
+ }
1893
+ };
1894
+ });
1895
+
1896
+ },{"../assets/htmlMatcher":26,"../utils/common":73,"../utils/editor":75}],16:[function(require,module,exports){
1897
+ /**
1898
+ * Actions that use stream parsers and tokenizers for traversing:
1899
+ * -- Search for next/previous items in HTML
1900
+ * -- Search for next/previous items in CSS
1901
+ */
1902
+ if (typeof module === 'object' && typeof define !== 'function') {
1903
+ var define = function (factory) {
1904
+ module.exports = factory(require, exports, module);
1905
+ };
1906
+ }
1907
+
1908
+ define(function(require, exports, module) {
1909
+ var range = require('../assets/range');
1910
+ var utils = require('../utils/common');
1911
+ var editorUtils = require('../utils/editor');
1912
+ var actionUtils = require('../utils/action');
1913
+ var stringStream = require('../assets/stringStream');
1914
+ var xmlParser = require('../parser/xml');
1915
+ var cssEditTree = require('../editTree/css');
1916
+ var cssSections = require('../utils/cssSections');
1917
+
1918
+ var startTag = /^<([\w\:\-]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
1919
+
1920
+ /**
1921
+ * Generic function for searching for items to select
1922
+ * @param {IEmmetEditor} editor
1923
+ * @param {Boolean} isBackward Search backward (search forward otherwise)
1924
+ * @param {Function} extractFn Function that extracts item content
1925
+ * @param {Function} rangeFn Function that search for next token range
1926
+ */
1927
+ function findItem(editor, isBackward, extractFn, rangeFn) {
1928
+ var content = editorUtils.outputInfo(editor).content;
1929
+
1930
+ var contentLength = content.length;
1931
+ var itemRange, rng;
1932
+ /** @type Range */
1933
+ var prevRange = range(-1, 0);
1934
+ /** @type Range */
1935
+ var sel = range(editor.getSelectionRange());
1936
+
1937
+ var searchPos = sel.start, loop = 100000; // endless loop protection
1938
+ while (searchPos >= 0 && searchPos < contentLength && --loop > 0) {
1939
+ if ( (itemRange = extractFn(content, searchPos, isBackward)) ) {
1940
+ if (prevRange.equal(itemRange)) {
1941
+ break;
1942
+ }
1943
+
1944
+ prevRange = itemRange.clone();
1945
+ rng = rangeFn(itemRange.substring(content), itemRange.start, sel.clone());
1946
+
1947
+ if (rng) {
1948
+ editor.createSelection(rng.start, rng.end);
1949
+ return true;
1950
+ } else {
1951
+ searchPos = isBackward ? itemRange.start : itemRange.end - 1;
1952
+ }
1953
+ }
1954
+
1955
+ searchPos += isBackward ? -1 : 1;
1956
+ }
1957
+
1958
+ return false;
1959
+ }
1960
+
1961
+ // XXX HTML section
1962
+
1963
+ /**
1964
+ * Find next HTML item
1965
+ * @param {IEmmetEditor} editor
1966
+ */
1967
+ function findNextHTMLItem(editor) {
1968
+ var isFirst = true;
1969
+ return findItem(editor, false, function(content, searchPos){
1970
+ if (isFirst) {
1971
+ isFirst = false;
1972
+ return findOpeningTagFromPosition(content, searchPos);
1973
+ } else {
1974
+ return getOpeningTagFromPosition(content, searchPos);
1975
+ }
1976
+ }, function(tag, offset, selRange) {
1977
+ return getRangeForHTMLItem(tag, offset, selRange, false);
1978
+ });
1979
+ }
1980
+
1981
+ /**
1982
+ * Find previous HTML item
1983
+ * @param {IEmmetEditor} editor
1984
+ */
1985
+ function findPrevHTMLItem(editor) {
1986
+ return findItem(editor, true, getOpeningTagFromPosition, function (tag, offset, selRange) {
1987
+ return getRangeForHTMLItem(tag, offset, selRange, true);
1988
+ });
1989
+ }
1990
+
1991
+ /**
1992
+ * Creates possible selection ranges for HTML tag
1993
+ * @param {String} source Original HTML source for tokens
1994
+ * @param {Array} tokens List of HTML tokens
1995
+ * @returns {Array}
1996
+ */
1997
+ function makePossibleRangesHTML(source, tokens, offset) {
1998
+ offset = offset || 0;
1999
+ var result = [];
2000
+ var attrStart = -1, attrName = '', attrValue = '', attrValueRange, tagName;
2001
+ tokens.forEach(function(tok) {
2002
+ switch (tok.type) {
2003
+ case 'tag':
2004
+ tagName = source.substring(tok.start, tok.end);
2005
+ if (/^<[\w\:\-]/.test(tagName)) {
2006
+ // add tag name
2007
+ result.push(range({
2008
+ start: tok.start + 1,
2009
+ end: tok.end
2010
+ }));
2011
+ }
2012
+ break;
2013
+ case 'attribute':
2014
+ attrStart = tok.start;
2015
+ attrName = source.substring(tok.start, tok.end);
2016
+ break;
2017
+
2018
+ case 'string':
2019
+ // attribute value
2020
+ // push full attribute first
2021
+ result.push(range(attrStart, tok.end - attrStart));
2022
+
2023
+ attrValueRange = range(tok);
2024
+ attrValue = attrValueRange.substring(source);
2025
+
2026
+ // is this a quoted attribute?
2027
+ if (isQuote(attrValue.charAt(0)))
2028
+ attrValueRange.start++;
2029
+
2030
+ if (isQuote(attrValue.charAt(attrValue.length - 1)))
2031
+ attrValueRange.end--;
2032
+
2033
+ result.push(attrValueRange);
2034
+
2035
+ if (attrName == 'class') {
2036
+ result = result.concat(classNameRanges(attrValueRange.substring(source), attrValueRange.start));
2037
+ }
2038
+
2039
+ break;
2040
+ }
2041
+ });
2042
+
2043
+ // offset ranges
2044
+ result = result.filter(function(item) {
2045
+ if (item.length()) {
2046
+ item.shift(offset);
2047
+ return true;
2048
+ }
2049
+ });
2050
+
2051
+ // remove duplicates
2052
+ return utils.unique(result, function(item) {
2053
+ return item.toString();
2054
+ });
2055
+ }
2056
+
2057
+ /**
2058
+ * Returns ranges of class names in "class" attribute value
2059
+ * @param {String} className
2060
+ * @returns {Array}
2061
+ */
2062
+ function classNameRanges(className, offset) {
2063
+ offset = offset || 0;
2064
+ var result = [];
2065
+ /** @type StringStream */
2066
+ var stream = stringStream.create(className);
2067
+
2068
+ // skip whitespace
2069
+ stream.eatSpace();
2070
+ stream.start = stream.pos;
2071
+
2072
+ var ch;
2073
+ while ((ch = stream.next())) {
2074
+ if (/[\s\u00a0]/.test(ch)) {
2075
+ result.push(range(stream.start + offset, stream.pos - stream.start - 1));
2076
+ stream.eatSpace();
2077
+ stream.start = stream.pos;
2078
+ }
2079
+ }
2080
+
2081
+ result.push(range(stream.start + offset, stream.pos - stream.start));
2082
+ return result;
2083
+ }
2084
+
2085
+ /**
2086
+ * Returns best HTML tag range match for current selection
2087
+ * @param {String} tag Tag declaration
2088
+ * @param {Number} offset Tag's position index inside content
2089
+ * @param {Range} selRange Selection range
2090
+ * @return {Range} Returns range if next item was found, <code>null</code> otherwise
2091
+ */
2092
+ function getRangeForHTMLItem(tag, offset, selRange, isBackward) {
2093
+ var ranges = makePossibleRangesHTML(tag, xmlParser.parse(tag), offset);
2094
+
2095
+ if (isBackward)
2096
+ ranges.reverse();
2097
+
2098
+ // try to find selected range
2099
+ var curRange = utils.find(ranges, function(r) {
2100
+ return r.equal(selRange);
2101
+ });
2102
+
2103
+ if (curRange) {
2104
+ var ix = ranges.indexOf(curRange);
2105
+ if (ix < ranges.length - 1)
2106
+ return ranges[ix + 1];
2107
+
2108
+ return null;
2109
+ }
2110
+
2111
+ // no selected range, find nearest one
2112
+ if (isBackward)
2113
+ // search backward
2114
+ return utils.find(ranges, function(r) {
2115
+ return r.start < selRange.start;
2116
+ });
2117
+
2118
+ // search forward
2119
+ // to deal with overlapping ranges (like full attribute definition
2120
+ // and attribute value) let's find range under caret first
2121
+ if (!curRange) {
2122
+ var matchedRanges = ranges.filter(function(r) {
2123
+ return r.inside(selRange.end);
2124
+ });
2125
+
2126
+ if (matchedRanges.length > 1)
2127
+ return matchedRanges[1];
2128
+ }
2129
+
2130
+
2131
+ return utils.find(ranges, function(r) {
2132
+ return r.end > selRange.end;
2133
+ });
2134
+ }
2135
+
2136
+ /**
2137
+ * Search for opening tag in content, starting at specified position
2138
+ * @param {String} html Where to search tag
2139
+ * @param {Number} pos Character index where to start searching
2140
+ * @return {Range} Returns range if valid opening tag was found,
2141
+ * <code>null</code> otherwise
2142
+ */
2143
+ function findOpeningTagFromPosition(html, pos) {
2144
+ var tag;
2145
+ while (pos >= 0) {
2146
+ if ((tag = getOpeningTagFromPosition(html, pos)))
2147
+ return tag;
2148
+ pos--;
2149
+ }
2150
+
2151
+ return null;
2152
+ }
2153
+
2154
+ /**
2155
+ * @param {String} html Where to search tag
2156
+ * @param {Number} pos Character index where to start searching
2157
+ * @return {Range} Returns range if valid opening tag was found,
2158
+ * <code>null</code> otherwise
2159
+ */
2160
+ function getOpeningTagFromPosition(html, pos) {
2161
+ var m;
2162
+ if (html.charAt(pos) == '<' && (m = html.substring(pos, html.length).match(startTag))) {
2163
+ return range(pos, m[0]);
2164
+ }
2165
+ }
2166
+
2167
+ function isQuote(ch) {
2168
+ return ch == '"' || ch == "'";
2169
+ }
2170
+
2171
+ /**
2172
+ * Returns all ranges inside given rule, available for selection
2173
+ * @param {CSSEditContainer} rule
2174
+ * @return {Array}
2175
+ */
2176
+ function findInnerRanges(rule) {
2177
+ // rule selector
2178
+ var ranges = [rule.nameRange(true)];
2179
+
2180
+ // find nested sections, keep selectors only
2181
+ var nestedSections = cssSections.nestedSectionsInRule(rule);
2182
+ nestedSections.forEach(function(section) {
2183
+ ranges.push(range.create2(section.start, section._selectorEnd));
2184
+ });
2185
+
2186
+ // add full property ranges and values
2187
+ rule.list().forEach(function(property) {
2188
+ ranges = ranges.concat(makePossibleRangesCSS(property));
2189
+ });
2190
+
2191
+ ranges = range.sort(ranges);
2192
+
2193
+ // optimize result: remove empty ranges and duplicates
2194
+ ranges = ranges.filter(function(item) {
2195
+ return !!item.length();
2196
+ });
2197
+ return utils.unique(ranges, function(item) {
2198
+ return item.toString();
2199
+ });
2200
+ }
2201
+
2202
+ /**
2203
+ * Makes all possible selection ranges for specified CSS property
2204
+ * @param {CSSProperty} property
2205
+ * @returns {Array}
2206
+ */
2207
+ function makePossibleRangesCSS(property) {
2208
+ // find all possible ranges, sorted by position and size
2209
+ var valueRange = property.valueRange(true);
2210
+ var result = [property.range(true), valueRange];
2211
+
2212
+ // locate parts of complex values.
2213
+ // some examples:
2214
+ // – 1px solid red: 3 parts
2215
+ // – arial, sans-serif: enumeration, 2 parts
2216
+ // – url(image.png): function value part
2217
+ var value = property.value();
2218
+ property.valueParts().forEach(function(r) {
2219
+ // add absolute range
2220
+ var clone = r.clone();
2221
+ result.push(clone.shift(valueRange.start));
2222
+
2223
+ /** @type StringStream */
2224
+ var stream = stringStream.create(r.substring(value));
2225
+ if (stream.match(/^[\w\-]+\(/, true)) {
2226
+ // we have a function, find values in it.
2227
+ // but first add function contents
2228
+ stream.start = stream.pos;
2229
+ stream.backUp(1);
2230
+ stream.skipToPair('(', ')');
2231
+ stream.backUp(1);
2232
+ var fnBody = stream.current();
2233
+ result.push(range(clone.start + stream.start, fnBody));
2234
+
2235
+ // find parts
2236
+ cssEditTree.findParts(fnBody).forEach(function(part) {
2237
+ result.push(range(clone.start + stream.start + part.start, part.substring(fnBody)));
2238
+ });
2239
+ }
2240
+ });
2241
+
2242
+ return result;
2243
+ }
2244
+
2245
+ /**
2246
+ * Tries to find matched CSS property and nearest range for selection
2247
+ * @param {CSSRule} rule
2248
+ * @param {Range} selRange
2249
+ * @param {Boolean} isBackward
2250
+ * @returns {Range}
2251
+ */
2252
+ function matchedRangeForCSSProperty(rule, selRange, isBackward) {
2253
+ var ranges = findInnerRanges(rule);
2254
+ if (isBackward) {
2255
+ ranges.reverse();
2256
+ }
2257
+
2258
+ // return next to selected range, if possible
2259
+ var r = utils.find(ranges, function(item) {
2260
+ return item.equal(selRange);
2261
+ });
2262
+
2263
+ if (r) {
2264
+ return ranges[ranges.indexOf(r) + 1];
2265
+ }
2266
+
2267
+ // find matched and (possibly) overlapping ranges
2268
+ var nested = ranges.filter(function(item) {
2269
+ return item.inside(selRange.end);
2270
+ });
2271
+
2272
+ if (nested.length) {
2273
+ return nested.sort(function(a, b) {
2274
+ return a.length() - b.length();
2275
+ })[0];
2276
+ }
2277
+
2278
+ // return range next to caret
2279
+ var test =
2280
+ r = utils.find(ranges, isBackward
2281
+ ? function(item) {return item.end < selRange.start;}
2282
+ : function(item) {return item.end > selRange.start;}
2283
+ );
2284
+
2285
+ if (!r) {
2286
+ // can’t find anything, just pick first one
2287
+ r = ranges[0];
2288
+ }
2289
+
2290
+ return r;
2291
+ }
2292
+
2293
+ function findNextCSSItem(editor) {
2294
+ return findItem(editor, false, cssSections.locateRule.bind(cssSections), getRangeForNextItemInCSS);
2295
+ }
2296
+
2297
+ function findPrevCSSItem(editor) {
2298
+ return findItem(editor, true, cssSections.locateRule.bind(cssSections), getRangeForPrevItemInCSS);
2299
+ }
2300
+
2301
+ /**
2302
+ * Returns range for item to be selected in CSS after current caret
2303
+ * (selection) position
2304
+ * @param {String} rule CSS rule declaration
2305
+ * @param {Number} offset Rule's position index inside content
2306
+ * @param {Range} selRange Selection range
2307
+ * @return {Range} Returns range if next item was found, <code>null</code> otherwise
2308
+ */
2309
+ function getRangeForNextItemInCSS(rule, offset, selRange) {
2310
+ var tree = cssEditTree.parse(rule, {
2311
+ offset: offset
2312
+ });
2313
+
2314
+ return matchedRangeForCSSProperty(tree, selRange, false);
2315
+ }
2316
+
2317
+ /**
2318
+ * Returns range for item to be selected in CSS before current caret
2319
+ * (selection) position
2320
+ * @param {String} rule CSS rule declaration
2321
+ * @param {Number} offset Rule's position index inside content
2322
+ * @param {Range} selRange Selection range
2323
+ * @return {Range} Returns range if previous item was found, <code>null</code> otherwise
2324
+ */
2325
+ function getRangeForPrevItemInCSS(rule, offset, selRange) {
2326
+ var tree = cssEditTree.parse(rule, {
2327
+ offset: offset
2328
+ });
2329
+
2330
+ return matchedRangeForCSSProperty(tree, selRange, true);
2331
+ }
2332
+
2333
+ return {
2334
+ selectNextItemAction: function(editor) {
2335
+ if (actionUtils.isSupportedCSS(editor.getSyntax())) {
2336
+ return findNextCSSItem(editor);
2337
+ } else {
2338
+ return findNextHTMLItem(editor);
2339
+ }
2340
+ },
2341
+
2342
+ selectPreviousItemAction: function(editor) {
2343
+ if (actionUtils.isSupportedCSS(editor.getSyntax())) {
2344
+ return findPrevCSSItem(editor);
2345
+ } else {
2346
+ return findPrevHTMLItem(editor);
2347
+ }
2348
+ }
2349
+ };
2350
+ });
2351
+ },{"../assets/range":30,"../assets/stringStream":32,"../editTree/css":37,"../parser/xml":62,"../utils/action":70,"../utils/common":73,"../utils/cssSections":74,"../utils/editor":75}],17:[function(require,module,exports){
2352
+ /**
2353
+ * Select current line (for simple editors like browser's &lt;textarea&gt;)
2354
+ */
2355
+ if (typeof module === 'object' && typeof define !== 'function') {
2356
+ var define = function (factory) {
2357
+ module.exports = factory(require, exports, module);
2358
+ };
2359
+ }
2360
+
2361
+ define(function(require, exports, module) {
2362
+ return {
2363
+ selectLineAction: function(editor) {
2364
+ var range = editor.getCurrentLineRange();
2365
+ editor.createSelection(range.start, range.end);
2366
+ return true;
2367
+ }
2368
+ };
2369
+ });
2370
+ },{}],18:[function(require,module,exports){
2371
+ /**
2372
+ * Splits or joins tag, e.g. transforms it into a short notation and vice versa:<br>
2373
+ * &lt;div&gt;&lt;/div&gt; → &lt;div /&gt; : join<br>
2374
+ * &lt;div /&gt; → &lt;div&gt;&lt;/div&gt; : split
2375
+ */
2376
+ if (typeof module === 'object' && typeof define !== 'function') {
2377
+ var define = function (factory) {
2378
+ module.exports = factory(require, exports, module);
2379
+ };
2380
+ }
2381
+
2382
+ define(function(require, exports, module) {
2383
+ var utils = require('../utils/common');
2384
+ var resources = require('../assets/resources');
2385
+ var matcher = require('../assets/htmlMatcher');
2386
+ var editorUtils = require('../utils/editor');
2387
+ var profile = require('../assets/profile');
2388
+
2389
+ /**
2390
+ * @param {IEmmetEditor} editor
2391
+ * @param {Object} profile
2392
+ * @param {Object} tag
2393
+ */
2394
+ function joinTag(editor, profile, tag) {
2395
+ // empty closing slash is a nonsense for this action
2396
+ var slash = profile.selfClosing() || ' /';
2397
+ var content = tag.open.range.substring(tag.source).replace(/\s*>$/, slash + '>');
2398
+
2399
+ var caretPos = editor.getCaretPos();
2400
+
2401
+ // update caret position
2402
+ if (content.length + tag.outerRange.start < caretPos) {
2403
+ caretPos = content.length + tag.outerRange.start;
2404
+ }
2405
+
2406
+ content = utils.escapeText(content);
2407
+ editor.replaceContent(content, tag.outerRange.start, tag.outerRange.end);
2408
+ editor.setCaretPos(caretPos);
2409
+ return true;
2410
+ }
2411
+
2412
+ function splitTag(editor, profile, tag) {
2413
+ var caretPos = editor.getCaretPos();
2414
+
2415
+ // define tag content depending on profile
2416
+ var tagContent = (profile.tag_nl === true) ? '\n\t\n' : '';
2417
+ var content = tag.outerContent().replace(/\s*\/>$/, '>');
2418
+ caretPos = tag.outerRange.start + content.length;
2419
+ content += tagContent + '</' + tag.open.name + '>';
2420
+
2421
+ content = utils.escapeText(content);
2422
+ editor.replaceContent(content, tag.outerRange.start, tag.outerRange.end);
2423
+ editor.setCaretPos(caretPos);
2424
+ return true;
2425
+ }
2426
+
2427
+ return {
2428
+ splitJoinTagAction: function(editor, profileName) {
2429
+ var info = editorUtils.outputInfo(editor, null, profileName);
2430
+ var curProfile = profile.get(info.profile);
2431
+
2432
+ // find tag at current position
2433
+ var tag = matcher.tag(info.content, editor.getCaretPos());
2434
+ if (tag) {
2435
+ return tag.close
2436
+ ? joinTag(editor, curProfile, tag)
2437
+ : splitTag(editor, curProfile, tag);
2438
+ }
2439
+
2440
+ return false;
2441
+ }
2442
+ };
2443
+ });
2444
+ },{"../assets/htmlMatcher":26,"../assets/profile":29,"../assets/resources":31,"../utils/common":73,"../utils/editor":75}],19:[function(require,module,exports){
2445
+ /**
2446
+ * Toggles HTML and CSS comments depending on current caret context. Unlike
2447
+ * the same action in most editors, this action toggles comment on currently
2448
+ * matched item—HTML tag or CSS selector—when nothing is selected.
2449
+ */
2450
+ if (typeof module === 'object' && typeof define !== 'function') {
2451
+ var define = function (factory) {
2452
+ module.exports = factory(require, exports, module);
2453
+ };
2454
+ }
2455
+
2456
+ define(function(require, exports, module) {
2457
+ var prefs = require('../assets/preferences');
2458
+ var range = require('../assets/range');
2459
+ var utils = require('../utils/common');
2460
+ var actionUtils = require('../utils/action');
2461
+ var editorUtils = require('../utils/editor');
2462
+ var htmlMatcher = require('../assets/htmlMatcher');
2463
+ var cssEditTree = require('../editTree/css');
2464
+
2465
+ /**
2466
+ * Toggle HTML comment on current selection or tag
2467
+ * @param {IEmmetEditor} editor
2468
+ * @return {Boolean} Returns <code>true</code> if comment was toggled
2469
+ */
2470
+ function toggleHTMLComment(editor) {
2471
+ /** @type Range */
2472
+ var r = range(editor.getSelectionRange());
2473
+ var info = editorUtils.outputInfo(editor);
2474
+
2475
+ if (!r.length()) {
2476
+ // no selection, find matching tag
2477
+ var tag = htmlMatcher.tag(info.content, editor.getCaretPos());
2478
+ if (tag) { // found pair
2479
+ r = tag.outerRange;
2480
+ }
2481
+ }
2482
+
2483
+ return genericCommentToggle(editor, '<!--', '-->', r);
2484
+ }
2485
+
2486
+ /**
2487
+ * Simple CSS commenting
2488
+ * @param {IEmmetEditor} editor
2489
+ * @return {Boolean} Returns <code>true</code> if comment was toggled
2490
+ */
2491
+ function toggleCSSComment(editor) {
2492
+ /** @type Range */
2493
+ var rng = range(editor.getSelectionRange());
2494
+ var info = editorUtils.outputInfo(editor);
2495
+
2496
+ if (!rng.length()) {
2497
+ // no selection, try to get current rule
2498
+ /** @type CSSRule */
2499
+ var rule = cssEditTree.parseFromPosition(info.content, editor.getCaretPos());
2500
+ if (rule) {
2501
+ var property = cssItemFromPosition(rule, editor.getCaretPos());
2502
+ rng = property
2503
+ ? property.range(true)
2504
+ : range(rule.nameRange(true).start, rule.source);
2505
+ }
2506
+ }
2507
+
2508
+ if (!rng.length()) {
2509
+ // still no selection, get current line
2510
+ rng = range(editor.getCurrentLineRange());
2511
+ utils.narrowToNonSpace(info.content, rng);
2512
+ }
2513
+
2514
+ return genericCommentToggle(editor, '/*', '*/', rng);
2515
+ }
2516
+
2517
+ /**
2518
+ * Returns CSS property from <code>rule</code> that matches passed position
2519
+ * @param {EditContainer} rule
2520
+ * @param {Number} absPos
2521
+ * @returns {EditElement}
2522
+ */
2523
+ function cssItemFromPosition(rule, absPos) {
2524
+ // do not use default EditContainer.itemFromPosition() here, because
2525
+ // we need to make a few assumptions to make CSS commenting more reliable
2526
+ var relPos = absPos - (rule.options.offset || 0);
2527
+ var reSafeChar = /^[\s\n\r]/;
2528
+ return utils.find(rule.list(), function(item) {
2529
+ if (item.range().end === relPos) {
2530
+ // at the end of property, but outside of it
2531
+ // if there’s a space character at current position,
2532
+ // use current property
2533
+ return reSafeChar.test(rule.source.charAt(relPos));
2534
+ }
2535
+
2536
+ return item.range().inside(relPos);
2537
+ });
2538
+ }
2539
+
2540
+ /**
2541
+ * Search for nearest comment in <code>str</code>, starting from index <code>from</code>
2542
+ * @param {String} text Where to search
2543
+ * @param {Number} from Search start index
2544
+ * @param {String} start_token Comment start string
2545
+ * @param {String} end_token Comment end string
2546
+ * @return {Range} Returns null if comment wasn't found
2547
+ */
2548
+ function searchComment(text, from, startToken, endToken) {
2549
+ var commentStart = -1;
2550
+ var commentEnd = -1;
2551
+
2552
+ var hasMatch = function(str, start) {
2553
+ return text.substr(start, str.length) == str;
2554
+ };
2555
+
2556
+ // search for comment start
2557
+ while (from--) {
2558
+ if (hasMatch(startToken, from)) {
2559
+ commentStart = from;
2560
+ break;
2561
+ }
2562
+ }
2563
+
2564
+ if (commentStart != -1) {
2565
+ // search for comment end
2566
+ from = commentStart;
2567
+ var contentLen = text.length;
2568
+ while (contentLen >= from++) {
2569
+ if (hasMatch(endToken, from)) {
2570
+ commentEnd = from + endToken.length;
2571
+ break;
2572
+ }
2573
+ }
2574
+ }
2575
+
2576
+ return (commentStart != -1 && commentEnd != -1)
2577
+ ? range(commentStart, commentEnd - commentStart)
2578
+ : null;
2579
+ }
2580
+
2581
+ /**
2582
+ * Generic comment toggling routine
2583
+ * @param {IEmmetEditor} editor
2584
+ * @param {String} commentStart Comment start token
2585
+ * @param {String} commentEnd Comment end token
2586
+ * @param {Range} range Selection range
2587
+ * @return {Boolean}
2588
+ */
2589
+ function genericCommentToggle(editor, commentStart, commentEnd, range) {
2590
+ var content = editorUtils.outputInfo(editor).content;
2591
+ var caretPos = editor.getCaretPos();
2592
+ var newContent = null;
2593
+
2594
+ /**
2595
+ * Remove comment markers from string
2596
+ * @param {Sting} str
2597
+ * @return {String}
2598
+ */
2599
+ function removeComment(str) {
2600
+ return str
2601
+ .replace(new RegExp('^' + utils.escapeForRegexp(commentStart) + '\\s*'), function(str){
2602
+ caretPos -= str.length;
2603
+ return '';
2604
+ }).replace(new RegExp('\\s*' + utils.escapeForRegexp(commentEnd) + '$'), '');
2605
+ }
2606
+
2607
+ // first, we need to make sure that this substring is not inside
2608
+ // comment
2609
+ var commentRange = searchComment(content, caretPos, commentStart, commentEnd);
2610
+ if (commentRange && commentRange.overlap(range)) {
2611
+ // we're inside comment, remove it
2612
+ range = commentRange;
2613
+ newContent = removeComment(range.substring(content));
2614
+ } else {
2615
+ // should add comment
2616
+ // make sure that there's no comment inside selection
2617
+ newContent = commentStart + ' ' +
2618
+ range.substring(content)
2619
+ .replace(new RegExp(utils.escapeForRegexp(commentStart) + '\\s*|\\s*' + utils.escapeForRegexp(commentEnd), 'g'), '') +
2620
+ ' ' + commentEnd;
2621
+
2622
+ // adjust caret position
2623
+ caretPos += commentStart.length + 1;
2624
+ }
2625
+
2626
+ // replace editor content
2627
+ if (newContent !== null) {
2628
+ newContent = utils.escapeText(newContent);
2629
+ editor.setCaretPos(range.start);
2630
+ editor.replaceContent(editorUtils.unindent(editor, newContent), range.start, range.end);
2631
+ editor.setCaretPos(caretPos);
2632
+ return true;
2633
+ }
2634
+
2635
+ return false;
2636
+ }
2637
+
2638
+ return {
2639
+ /**
2640
+ * Toggle comment on current editor's selection or HTML tag/CSS rule
2641
+ * @param {IEmmetEditor} editor
2642
+ */
2643
+ toggleCommentAction: function(editor) {
2644
+ var info = editorUtils.outputInfo(editor);
2645
+ if (actionUtils.isSupportedCSS(info.syntax)) {
2646
+ // in case our editor is good enough and can recognize syntax from
2647
+ // current token, we have to make sure that cursor is not inside
2648
+ // 'style' attribute of html element
2649
+ var caretPos = editor.getCaretPos();
2650
+ var tag = htmlMatcher.tag(info.content, caretPos);
2651
+ if (tag && tag.open.range.inside(caretPos)) {
2652
+ info.syntax = 'html';
2653
+ }
2654
+ }
2655
+
2656
+ var cssSyntaxes = prefs.getArray('css.syntaxes');
2657
+ if (~cssSyntaxes.indexOf(info.syntax)) {
2658
+ return toggleCSSComment(editor);
2659
+ }
2660
+
2661
+ return toggleHTMLComment(editor);
2662
+ }
2663
+ };
2664
+ });
2665
+ },{"../assets/htmlMatcher":26,"../assets/preferences":28,"../assets/range":30,"../editTree/css":37,"../utils/action":70,"../utils/common":73,"../utils/editor":75}],20:[function(require,module,exports){
2666
+ /**
2667
+ * Automatically updates image size attributes in HTML's &lt;img&gt; element or
2668
+ * CSS rule
2669
+ */
2670
+ if (typeof module === 'object' && typeof define !== 'function') {
2671
+ var define = function (factory) {
2672
+ module.exports = factory(require, exports, module);
2673
+ };
2674
+ }
2675
+
2676
+ define(function(require, exports, module) {
2677
+ var utils = require('../utils/common');
2678
+ var editorUtils = require('../utils/editor');
2679
+ var actionUtils = require('../utils/action');
2680
+ var xmlEditTree = require('../editTree/xml');
2681
+ var cssEditTree = require('../editTree/css');
2682
+ var base64 = require('../utils/base64');
2683
+ var file = require('../plugin/file');
2684
+
2685
+ /**
2686
+ * Updates image size of &lt;img src=""&gt; tag
2687
+ * @param {IEmmetEditor} editor
2688
+ */
2689
+ function updateImageSizeHTML(editor) {
2690
+ var offset = editor.getCaretPos();
2691
+
2692
+ // find tag from current caret position
2693
+ var info = editorUtils.outputInfo(editor);
2694
+ var xmlElem = xmlEditTree.parseFromPosition(info.content, offset, true);
2695
+ if (xmlElem && (xmlElem.name() || '').toLowerCase() == 'img') {
2696
+ getImageSizeForSource(editor, xmlElem.value('src'), function(size) {
2697
+ if (size) {
2698
+ var compoundData = xmlElem.range(true);
2699
+ xmlElem.value('width', size.width);
2700
+ xmlElem.value('height', size.height, xmlElem.indexOf('width') + 1);
2701
+
2702
+ actionUtils.compoundUpdate(editor, utils.extend(compoundData, {
2703
+ data: xmlElem.toString(),
2704
+ caret: offset
2705
+ }));
2706
+ }
2707
+ });
2708
+ }
2709
+ }
2710
+
2711
+ /**
2712
+ * Updates image size of CSS property
2713
+ * @param {IEmmetEditor} editor
2714
+ */
2715
+ function updateImageSizeCSS(editor) {
2716
+ var offset = editor.getCaretPos();
2717
+
2718
+ // find tag from current caret position
2719
+ var info = editorUtils.outputInfo(editor);
2720
+ var cssRule = cssEditTree.parseFromPosition(info.content, offset, true);
2721
+ if (cssRule) {
2722
+ // check if there is property with image under caret
2723
+ var prop = cssRule.itemFromPosition(offset, true), m;
2724
+ if (prop && (m = /url\((["']?)(.+?)\1\)/i.exec(prop.value() || ''))) {
2725
+ getImageSizeForSource(editor, m[2], function(size) {
2726
+ if (size) {
2727
+ var compoundData = cssRule.range(true);
2728
+ cssRule.value('width', size.width + 'px');
2729
+ cssRule.value('height', size.height + 'px', cssRule.indexOf('width') + 1);
2730
+
2731
+ actionUtils.compoundUpdate(editor, utils.extend(compoundData, {
2732
+ data: cssRule.toString(),
2733
+ caret: offset
2734
+ }));
2735
+ }
2736
+ });
2737
+ }
2738
+ }
2739
+ }
2740
+
2741
+ /**
2742
+ * Returns image dimensions for source
2743
+ * @param {IEmmetEditor} editor
2744
+ * @param {String} src Image source (path or data:url)
2745
+ */
2746
+ function getImageSizeForSource(editor, src, callback) {
2747
+ var fileContent;
2748
+ if (src) {
2749
+ // check if it is data:url
2750
+ if (/^data:/.test(src)) {
2751
+ fileContent = base64.decode( src.replace(/^data\:.+?;.+?,/, '') );
2752
+ return callback(actionUtils.getImageSize(fileContent));
2753
+ }
2754
+
2755
+ var absPath = file.locateFile(editor.getFilePath(), src);
2756
+ if (absPath === null) {
2757
+ throw "Can't find " + src + ' file';
2758
+ }
2759
+
2760
+ file.read(absPath, function(err, content) {
2761
+ if (err) {
2762
+ throw 'Unable to read ' + absPath + ': ' + err;
2763
+ }
2764
+
2765
+ content = String(content);
2766
+ callback(actionUtils.getImageSize(content));
2767
+ });
2768
+ }
2769
+ }
2770
+
2771
+ return {
2772
+ updateImageSizeAction: function(editor) {
2773
+ // this action will definitely won’t work in SASS dialect,
2774
+ // but may work in SCSS or LESS
2775
+ if (actionUtils.isSupportedCSS(editor.getSyntax())) {
2776
+ updateImageSizeCSS(editor);
2777
+ } else {
2778
+ updateImageSizeHTML(editor);
2779
+ }
2780
+
2781
+ return true;
2782
+ }
2783
+ };
2784
+ });
2785
+ },{"../editTree/css":37,"../editTree/xml":38,"../plugin/file":63,"../utils/action":70,"../utils/base64":71,"../utils/common":73,"../utils/editor":75}],21:[function(require,module,exports){
2786
+ /**
2787
+ * Update Tag action: allows users to update existing HTML tags and add/remove
2788
+ * attributes or even tag name
2789
+ */
2790
+ if (typeof module === 'object' && typeof define !== 'function') {
2791
+ var define = function (factory) {
2792
+ module.exports = factory(require, exports, module);
2793
+ };
2794
+ }
2795
+
2796
+ define(function(require, exports, module) {
2797
+ var xmlEditTree = require('../editTree/xml');
2798
+ var editorUtils = require('../utils/editor');
2799
+ var actionUtils = require('../utils/action');
2800
+ var utils = require('../utils/common');
2801
+ var parser = require('../parser/abbreviation');
2802
+
2803
+ function updateAttributes(tag, abbrNode, ix) {
2804
+ var classNames = (abbrNode.attribute('class') || '').split(/\s+/g);
2805
+ if (ix) {
2806
+ classNames.push('+' + abbrNode.name());
2807
+ }
2808
+
2809
+ var r = function(str) {
2810
+ return utils.replaceCounter(str, abbrNode.counter);
2811
+ };
2812
+
2813
+ // update class
2814
+ classNames.forEach(function(className) {
2815
+ if (!className) {
2816
+ return;
2817
+ }
2818
+
2819
+ className = r(className);
2820
+ var ch = className.charAt(0);
2821
+ if (ch == '+') {
2822
+ tag.addClass(className.substr(1));
2823
+ } else if (ch == '-') {
2824
+ tag.removeClass(className.substr(1));
2825
+ } else {
2826
+ tag.value('class', className);
2827
+ }
2828
+ });
2829
+
2830
+ // update attributes
2831
+ abbrNode.attributeList().forEach(function(attr) {
2832
+ if (attr.name.toLowerCase() == 'class') {
2833
+ return;
2834
+ }
2835
+
2836
+ var ch = attr.name.charAt(0);
2837
+ if (ch == '+') {
2838
+ var attrName = attr.name.substr(1);
2839
+ var tagAttr = tag.get(attrName);
2840
+ if (tagAttr) {
2841
+ tagAttr.value(tagAttr.value() + r(attr.value));
2842
+ } else {
2843
+ tag.value(attrName, r(attr.value));
2844
+ }
2845
+ } else if (ch == '-') {
2846
+ tag.remove(attr.name.substr(1));
2847
+ } else {
2848
+ tag.value(attr.name, r(attr.value));
2849
+ }
2850
+ });
2851
+ }
2852
+
2853
+ return {
2854
+ /**
2855
+ * Matches HTML tag under caret and updates its definition
2856
+ * according to given abbreviation
2857
+ * @param {IEmmetEditor} Editor instance
2858
+ * @param {String} abbr Abbreviation to update with
2859
+ */
2860
+ updateTagAction: function(editor, abbr) {
2861
+ abbr = abbr || editor.prompt("Enter abbreviation");
2862
+
2863
+ if (!abbr) {
2864
+ return false;
2865
+ }
2866
+
2867
+ var content = editor.getContent();
2868
+ var ctx = actionUtils.captureContext(editor);
2869
+ var tag = this.getUpdatedTag(abbr, ctx, content);
2870
+
2871
+ if (!tag) {
2872
+ // nothing to update
2873
+ return false;
2874
+ }
2875
+
2876
+ // check if tag name was updated
2877
+ if (tag.name() != ctx.name && ctx.match.close) {
2878
+ editor.replaceContent('</' + tag.name() + '>', ctx.match.close.range.start, ctx.match.close.range.end, true);
2879
+ }
2880
+
2881
+ editor.replaceContent(tag.source, ctx.match.open.range.start, ctx.match.open.range.end, true);
2882
+ return true;
2883
+ },
2884
+
2885
+ /**
2886
+ * Returns XMLEditContainer node with updated tag structure
2887
+ * of existing tag context.
2888
+ * This data can be used to modify existing tag
2889
+ * @param {String} abbr Abbreviation
2890
+ * @param {Object} ctx Tag to be updated (captured with `htmlMatcher`)
2891
+ * @param {String} content Original editor content
2892
+ * @return {XMLEditContainer}
2893
+ */
2894
+ getUpdatedTag: function(abbr, ctx, content, options) {
2895
+ if (!ctx) {
2896
+ // nothing to update
2897
+ return null;
2898
+ }
2899
+
2900
+ var tree = parser.parse(abbr, options || {});
2901
+
2902
+ // for this action some characters in abbreviation has special
2903
+ // meaning. For example, `.-c2` means “remove `c2` class from
2904
+ // element” and `.+c3` means “append class `c3` to exising one.
2905
+ //
2906
+ // But `.+c3` abbreviation will actually produce two elements:
2907
+ // <div class=""> and <c3>. Thus, we have to walk on each element
2908
+ // of parsed tree and use their definitions to update current element
2909
+ var tag = xmlEditTree.parse(ctx.match.open.range.substring(content), {
2910
+ offset: ctx.match.outerRange.start
2911
+ });
2912
+
2913
+ tree.children.forEach(function(node, i) {
2914
+ updateAttributes(tag, node, i);
2915
+ });
2916
+
2917
+ // if tag name was resolved by implicit tag name resolver,
2918
+ // then user omitted it in abbreviation and wants to keep
2919
+ // original tag name
2920
+ var el = tree.children[0];
2921
+ if (!el.data('nameResolved')) {
2922
+ tag.name(el.name());
2923
+ }
2924
+
2925
+ return tag;
2926
+ }
2927
+ };
2928
+ });
2929
+ },{"../editTree/xml":38,"../parser/abbreviation":55,"../utils/action":70,"../utils/common":73,"../utils/editor":75}],22:[function(require,module,exports){
2930
+ /**
2931
+ * Action that wraps content with abbreviation. For convenience, action is
2932
+ * defined as reusable module
2933
+ */
2934
+ if (typeof module === 'object' && typeof define !== 'function') {
2935
+ var define = function (factory) {
2936
+ module.exports = factory(require, exports, module);
2937
+ };
2938
+ }
2939
+
2940
+ define(function(require, exports, module) {
2941
+ var range = require('../assets/range');
2942
+ var htmlMatcher = require('../assets/htmlMatcher');
2943
+ var utils = require('../utils/common');
2944
+ var editorUtils = require('../utils/editor');
2945
+ var actionUtils = require('../utils/action');
2946
+ var parser = require('../parser/abbreviation');
2947
+
2948
+ return {
2949
+ /**
2950
+ * Wraps content with abbreviation
2951
+ * @param {IEmmetEditor} Editor instance
2952
+ * @param {String} abbr Abbreviation to wrap with
2953
+ * @param {String} syntax Syntax type (html, css, etc.)
2954
+ * @param {String} profile Output profile name (html, xml, xhtml)
2955
+ */
2956
+ wrapWithAbbreviationAction: function(editor, abbr, syntax, profile) {
2957
+ var info = editorUtils.outputInfo(editor, syntax, profile);
2958
+ abbr = abbr || editor.prompt("Enter abbreviation");
2959
+
2960
+ if (!abbr) {
2961
+ return null;
2962
+ }
2963
+
2964
+ abbr = String(abbr);
2965
+
2966
+ var r = range(editor.getSelectionRange());
2967
+
2968
+ if (!r.length()) {
2969
+ // no selection, find tag pair
2970
+ var match = htmlMatcher.tag(info.content, r.start);
2971
+ if (!match) { // nothing to wrap
2972
+ return false;
2973
+ }
2974
+
2975
+ r = utils.narrowToNonSpace(info.content, match.range);
2976
+ }
2977
+
2978
+ var newContent = utils.escapeText(r.substring(info.content));
2979
+ var result = parser.expand(abbr, {
2980
+ pastedContent: editorUtils.unindent(editor, newContent),
2981
+ syntax: info.syntax,
2982
+ profile: info.profile,
2983
+ contextNode: actionUtils.captureContext(editor)
2984
+ });
2985
+
2986
+ if (result) {
2987
+ editor.replaceContent(result, r.start, r.end);
2988
+ return true;
2989
+ }
2990
+
2991
+ return false;
2992
+ }
2993
+ };
2994
+ });
2995
+ },{"../assets/htmlMatcher":26,"../assets/range":30,"../parser/abbreviation":55,"../utils/action":70,"../utils/common":73,"../utils/editor":75}],23:[function(require,module,exports){
2996
+ /**
2997
+ * Parsed resources (snippets, abbreviations, variables, etc.) for Emmet.
2998
+ * Contains convenient method to get access for snippets with respect of
2999
+ * inheritance. Also provides ability to store data in different vocabularies
3000
+ * ('system' and 'user') for fast and safe resource update
3001
+ * @author Sergey Chikuyonok (serge.che@gmail.com)
3002
+ * @link http://chikuyonok.ru
3003
+ */
3004
+ if (typeof module === 'object' && typeof define !== 'function') {
3005
+ var define = function (factory) {
3006
+ module.exports = factory(require, exports, module);
3007
+ };
3008
+ }
3009
+
3010
+ define(function(require, exports, module) {
3011
+ var prefs = require('./preferences');
3012
+ var utils = require('../utils/common');
3013
+
3014
+ prefs.define('caniuse.enabled', true, 'Enable support of Can I Use database. When enabled,\
3015
+ CSS abbreviation resolver will look at Can I Use database first before detecting\
3016
+ CSS properties that should be resolved');
3017
+
3018
+ prefs.define('caniuse.vendors', 'all', 'A comma-separated list vendor identifiers\
3019
+ (as described in Can I Use database) that should be supported\
3020
+ when resolving vendor-prefixed properties. Set value to <code>all</code>\
3021
+ to support all available properties');
3022
+
3023
+ prefs.define('caniuse.era', 'e-2', 'Browser era, as defined in Can I Use database.\
3024
+ Examples: <code>e0</code> (current version), <code>e1</code> (near future)\
3025
+ <code>e-2</code> (2 versions back) and so on.');
3026
+
3027
+ var cssSections = {
3028
+ 'border-image': ['border-image'],
3029
+ 'css-boxshadow': ['box-shadow'],
3030
+ 'css3-boxsizing': ['box-sizing'],
3031
+ 'multicolumn': ['column-width', 'column-count', 'columns', 'column-gap', 'column-rule-color', 'column-rule-style', 'column-rule-width', 'column-rule', 'column-span', 'column-fill'],
3032
+ 'border-radius': ['border-radius', 'border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius'],
3033
+ 'transforms2d': ['transform'],
3034
+ 'css-hyphens': ['hyphens'],
3035
+ 'css-transitions': ['transition', 'transition-property', 'transition-duration', 'transition-timing-function', 'transition-delay'],
3036
+ 'font-feature': ['font-feature-settings'],
3037
+ 'css-animation': ['animation', 'animation-name', 'animation-duration', 'animation-timing-function', 'animation-iteration-count', 'animation-direction', 'animation-play-state', 'animation-delay', 'animation-fill-mode', '@keyframes'],
3038
+ 'css-gradients': ['linear-gradient'],
3039
+ 'css-masks': ['mask-image', 'mask-source-type', 'mask-repeat', 'mask-position', 'mask-clip', 'mask-origin', 'mask-size', 'mask', 'mask-type', 'mask-box-image-source', 'mask-box-image-slice', 'mask-box-image-width', 'mask-box-image-outset', 'mask-box-image-repeat', 'mask-box-image', 'clip-path', 'clip-rule'],
3040
+ 'css-featurequeries': ['@supports'],
3041
+ 'flexbox': ['flex', 'inline-flex', 'flex-direction', 'flex-wrap', 'flex-flow', 'order', 'flex'],
3042
+ 'calc': ['calc'],
3043
+ 'object-fit': ['object-fit', 'object-position'],
3044
+ 'css-grid': ['grid', 'inline-grid', 'grid-template-rows', 'grid-template-columns', 'grid-template-areas', 'grid-template', 'grid-auto-rows', 'grid-auto-columns', ' grid-auto-flow', 'grid-auto-position', 'grid', ' grid-row-start', 'grid-column-start', 'grid-row-end', 'grid-column-end', 'grid-column', 'grid-row', 'grid-area', 'justify-self', 'justify-items', 'align-self', 'align-items'],
3045
+ 'css-repeating-gradients': ['repeating-linear-gradient'],
3046
+ 'css-filters': ['filter'],
3047
+ 'user-select-none': ['user-select'],
3048
+ 'intrinsic-width': ['min-content', 'max-content', 'fit-content', 'fill-available'],
3049
+ 'css3-tabsize': ['tab-size']
3050
+ };
3051
+
3052
+ /** @type {Object} The Can I Use database for CSS */
3053
+ var cssDB = null;
3054
+ /** @type {Object} A list of available vendors (browsers) and their prefixes */
3055
+ var vendorsDB = null;
3056
+ var erasDB = null;
3057
+
3058
+ function intersection(arr1, arr2) {
3059
+ var result = [];
3060
+ var smaller = arr1, larger = arr2;
3061
+ if (smaller.length > larger.length) {
3062
+ smaller = arr2;
3063
+ larger = arr1;
3064
+ }
3065
+ larger.forEach(function(item) {
3066
+ if (~smaller.indexOf(item)) {
3067
+ result.push(item);
3068
+ }
3069
+ });
3070
+ return result;
3071
+ }
3072
+
3073
+ /**
3074
+ * Parses raw Can I Use database for better lookups
3075
+ * @param {String} data Raw database
3076
+ * @param {Boolean} optimized Pass `true` if given `data` is already optimized
3077
+ * @return {Object}
3078
+ */
3079
+ function parseDB(data, optimized) {
3080
+ if (typeof data == 'string') {
3081
+ data = JSON.parse(data);
3082
+ }
3083
+
3084
+ if (!optimized) {
3085
+ data = optimize(data);
3086
+ }
3087
+
3088
+ vendorsDB = data.vendors;
3089
+ cssDB = data.css;
3090
+ erasDB = data.era;
3091
+ }
3092
+
3093
+ /**
3094
+ * Extract required data only from CIU database
3095
+ * @param {Object} data Raw Can I Use database
3096
+ * @return {Object} Optimized database
3097
+ */
3098
+ function optimize(data) {
3099
+ if (typeof data == 'string') {
3100
+ data = JSON.parse(data);
3101
+ }
3102
+
3103
+ return {
3104
+ vendors: parseVendors(data),
3105
+ css: parseCSS(data),
3106
+ era: parseEra(data)
3107
+ };
3108
+ }
3109
+
3110
+ /**
3111
+ * Parses vendor data
3112
+ * @param {Object} data
3113
+ * @return {Object}
3114
+ */
3115
+ function parseVendors(data) {
3116
+ var out = {};
3117
+ Object.keys(data.agents).forEach(function(name) {
3118
+ var agent = data.agents[name];
3119
+ out[name] = {
3120
+ prefix: agent.prefix,
3121
+ versions: agent.versions
3122
+ };
3123
+ });
3124
+ return out;
3125
+ }
3126
+
3127
+ /**
3128
+ * Parses CSS data from Can I Use raw database
3129
+ * @param {Object} data
3130
+ * @return {Object}
3131
+ */
3132
+ function parseCSS(data) {
3133
+ var out = {};
3134
+ var cssCategories = data.cats.CSS;
3135
+ Object.keys(data.data).forEach(function(name) {
3136
+ var section = data.data[name];
3137
+ if (name in cssSections) {
3138
+ cssSections[name].forEach(function(kw) {
3139
+ out[kw] = section.stats;
3140
+ });
3141
+ }
3142
+ });
3143
+
3144
+ return out;
3145
+ }
3146
+
3147
+ /**
3148
+ * Parses era data from Can I Use raw database
3149
+ * @param {Object} data
3150
+ * @return {Array}
3151
+ */
3152
+ function parseEra(data) {
3153
+ // some runtimes (like Mozilla Rhino) does not preserves
3154
+ // key order so we have to sort values manually
3155
+ return Object.keys(data.eras).sort(function(a, b) {
3156
+ return parseInt(a.substr(1)) - parseInt(b.substr(1));
3157
+ });
3158
+ }
3159
+
3160
+ /**
3161
+ * Returs list of supported vendors, depending on user preferences
3162
+ * @return {Array}
3163
+ */
3164
+ function getVendorsList() {
3165
+ var allVendors = Object.keys(vendorsDB);
3166
+ var vendors = prefs.getArray('caniuse.vendors');
3167
+ if (!vendors || vendors[0] == 'all') {
3168
+ return allVendors;
3169
+ }
3170
+
3171
+ return intersection(allVendors, vendors);
3172
+ }
3173
+
3174
+ /**
3175
+ * Returns size of version slice as defined by era identifier
3176
+ * @return {Number}
3177
+ */
3178
+ function getVersionSlice() {
3179
+ var era = prefs.get('caniuse.era');
3180
+ var ix = erasDB.indexOf(era);
3181
+ if (!~ix) {
3182
+ ix = erasDB.indexOf('e-2');
3183
+ }
3184
+
3185
+ return ix;
3186
+ }
3187
+
3188
+ // try to load caniuse database
3189
+ // hide it from Require.JS parser
3190
+ var db = null;
3191
+ (function(r) {
3192
+ if (typeof define === 'undefined' || !define.amd) {
3193
+ try {
3194
+ var fs = r('fs');
3195
+ var path = r('path');
3196
+ db = fs.readFileSync(path.join(__dirname, '../caniuse.json'), {encoding: 'utf8'});
3197
+ } catch(e) {}
3198
+ }
3199
+ })(require);
3200
+
3201
+ if (db) {
3202
+ parseDB(db);
3203
+ }
3204
+
3205
+ return {
3206
+ load: parseDB,
3207
+ optimize: optimize,
3208
+
3209
+ /**
3210
+ * Resolves prefixes for given property
3211
+ * @param {String} property A property to resolve. It can start with `@` symbol
3212
+ * (CSS section, like `@keyframes`) or `:` (CSS value, like `flex`)
3213
+ * @return {Array} Array of resolved prefixes or <code>null</code>
3214
+ * if prefixes can't be resolved. Empty array means property has no vendor
3215
+ * prefixes
3216
+ */
3217
+ resolvePrefixes: function(property) {
3218
+ if (!prefs.get('caniuse.enabled') || !cssDB || !(property in cssDB)) {
3219
+ return null;
3220
+ }
3221
+
3222
+ var prefixes = [];
3223
+ var propStats = cssDB[property];
3224
+ var versions = getVersionSlice();
3225
+
3226
+ getVendorsList().forEach(function(vendor) {
3227
+ var vendorVesions = vendorsDB[vendor].versions.slice(versions);
3228
+ for (var i = 0, v; i < vendorVesions.length; i++) {
3229
+ v = vendorVesions[i];
3230
+ if (!v) {
3231
+ continue;
3232
+ }
3233
+
3234
+ if (~propStats[vendor][v].indexOf('x')) {
3235
+ prefixes.push(vendorsDB[vendor].prefix);
3236
+ break;
3237
+ }
3238
+ }
3239
+ });
3240
+
3241
+ return utils.unique(prefixes).sort(function(a, b) {
3242
+ return b.length - a.length;
3243
+ });
3244
+ }
3245
+ };
3246
+ });
3247
+ },{"../utils/common":73,"./preferences":28}],24:[function(require,module,exports){
3248
+ /**
3249
+ * Module that contains factories for element types used by Emmet
3250
+ */
3251
+ if (typeof module === 'object' && typeof define !== 'function') {
3252
+ var define = function (factory) {
3253
+ module.exports = factory(require, exports, module);
3254
+ };
3255
+ }
3256
+
3257
+ define(function(require, exports, module) {
3258
+ var factories = {};
3259
+ var reAttrs = /([@\!]?)([\w\-:]+)\s*=\s*(['"])(.*?)\3/g;
3260
+
3261
+ // register resource references
3262
+ function commonFactory(value) {
3263
+ return {data: value};
3264
+ }
3265
+
3266
+ module = module || {};
3267
+ module.exports = {
3268
+ /**
3269
+ * Create new element factory
3270
+ * @param {String} name Element identifier
3271
+ * @param {Function} factory Function that produces element of specified
3272
+ * type. The object generated by this factory is automatically
3273
+ * augmented with <code>type</code> property pointing to element
3274
+ * <code>name</code>
3275
+ * @memberOf elements
3276
+ */
3277
+ add: function(name, factory) {
3278
+ var that = this;
3279
+ factories[name] = function() {
3280
+ var elem = factory.apply(that, arguments);
3281
+ if (elem)
3282
+ elem.type = name;
3283
+
3284
+ return elem;
3285
+ };
3286
+ },
3287
+
3288
+ /**
3289
+ * Returns factory for specified name
3290
+ * @param {String} name
3291
+ * @returns {Function}
3292
+ */
3293
+ get: function(name) {
3294
+ return factories[name];
3295
+ },
3296
+
3297
+ /**
3298
+ * Creates new element with specified type
3299
+ * @param {String} name
3300
+ * @returns {Object}
3301
+ */
3302
+ create: function(name) {
3303
+ var args = [].slice.call(arguments, 1);
3304
+ var factory = this.get(name);
3305
+ return factory ? factory.apply(this, args) : null;
3306
+ },
3307
+
3308
+ /**
3309
+ * Check if passed element is of specified type
3310
+ * @param {Object} elem
3311
+ * @param {String} type
3312
+ * @returns {Boolean}
3313
+ */
3314
+ is: function(elem, type) {
3315
+ return this.type(elem) === type;
3316
+ },
3317
+
3318
+ /**
3319
+ * Returns type of element
3320
+ * @param {Object} elem
3321
+ * @return {String}
3322
+ */
3323
+ type: function(elem) {
3324
+ return elem && elem.type;
3325
+ }
3326
+ };
3327
+
3328
+ /**
3329
+ * Element factory
3330
+ * @param {String} elementName Name of output element
3331
+ * @param {String} attrs Attributes definition. You may also pass
3332
+ * <code>Array</code> where each contains object with <code>name</code>
3333
+ * and <code>value</code> properties, or <code>Object</code>
3334
+ * @param {Boolean} isEmpty Is expanded element should be empty
3335
+ */
3336
+ module.exports.add('element', function(elementName, attrs, isEmpty) {
3337
+ var ret = {
3338
+ name: elementName,
3339
+ is_empty: !!isEmpty
3340
+ };
3341
+
3342
+ if (attrs) {
3343
+ ret.attributes = [];
3344
+ if (Array.isArray(attrs)) {
3345
+ ret.attributes = attrs;
3346
+ } else if (typeof attrs === 'string') {
3347
+ var m;
3348
+ while ((m = reAttrs.exec(attrs))) {
3349
+ ret.attributes.push({
3350
+ name: m[2],
3351
+ value: m[4],
3352
+ isDefault: m[1] == '@',
3353
+ isImplied: m[1] == '!'
3354
+ });
3355
+ }
3356
+ } else {
3357
+ ret.attributes = Object.keys(attrs).map(function(name) {
3358
+ return {
3359
+ name: name,
3360
+ value: attrs[name]
3361
+ };
3362
+ });
3363
+ }
3364
+ }
3365
+
3366
+ return ret;
3367
+ });
3368
+
3369
+ module.exports.add('snippet', commonFactory);
3370
+ module.exports.add('reference', commonFactory);
3371
+ module.exports.add('empty', function() {
3372
+ return {};
3373
+ });
3374
+
3375
+ return module.exports;
3376
+ });
3377
+ },{}],25:[function(require,module,exports){
3378
+ /**
3379
+ * Utility module that provides ordered storage of function handlers.
3380
+ * Many Emmet modules' functionality can be extended/overridden by custom
3381
+ * function. This modules provides unified storage of handler functions, their
3382
+ * management and execution
3383
+ */
3384
+ if (typeof module === 'object' && typeof define !== 'function') {
3385
+ var define = function (factory) {
3386
+ module.exports = factory(require, exports, module);
3387
+ };
3388
+ }
3389
+
3390
+ define(function(require, exports, module) {
3391
+ var utils = require('../utils/common');
3392
+
3393
+ /**
3394
+ * @type HandlerList
3395
+ * @constructor
3396
+ */
3397
+ function HandlerList() {
3398
+ this._list = [];
3399
+ }
3400
+
3401
+ HandlerList.prototype = {
3402
+ /**
3403
+ * Adds function handler
3404
+ * @param {Function} fn Handler
3405
+ * @param {Object} options Handler options. Possible values are:<br><br>
3406
+ * <b>order</b> : (<code>Number</code>) – order in handler list. Handlers
3407
+ * with higher order value will be executed earlier.
3408
+ */
3409
+ add: function(fn, options) {
3410
+ // TODO hack for stable sort, remove after fixing `list()`
3411
+ var order = this._list.length;
3412
+ if (options && 'order' in options) {
3413
+ order = options.order * 10000;
3414
+ }
3415
+ this._list.push(utils.extend({}, options, {order: order, fn: fn}));
3416
+ },
3417
+
3418
+ /**
3419
+ * Removes handler from list
3420
+ * @param {Function} fn
3421
+ */
3422
+ remove: function(fn) {
3423
+ var item = utils.find(this._list, function(item) {
3424
+ return item.fn === fn;
3425
+ });
3426
+ if (item) {
3427
+ this._list.splice(this._list.indexOf(item), 1);
3428
+ }
3429
+ },
3430
+
3431
+ /**
3432
+ * Returns ordered list of handlers. By default, handlers
3433
+ * with the same <code>order</code> option returned in reverse order,
3434
+ * i.e. the latter function was added into the handlers list, the higher
3435
+ * it will be in the returned array
3436
+ * @returns {Array}
3437
+ */
3438
+ list: function() {
3439
+ // TODO make stable sort
3440
+ return this._list.sort(function(a, b) {
3441
+ return b.order - a.order;
3442
+ });
3443
+ },
3444
+
3445
+ /**
3446
+ * Returns ordered list of handler functions
3447
+ * @returns {Array}
3448
+ */
3449
+ listFn: function() {
3450
+ return this.list().map(function(item) {
3451
+ return item.fn;
3452
+ });
3453
+ },
3454
+
3455
+ /**
3456
+ * Executes handler functions in their designated order. If function
3457
+ * returns <code>skipVal</code>, meaning that function was unable to
3458
+ * handle passed <code>args</code>, the next function will be executed
3459
+ * and so on.
3460
+ * @param {Object} skipValue If function returns this value, execute
3461
+ * next handler.
3462
+ * @param {Array} args Arguments to pass to handler function
3463
+ * @returns {Boolean} Whether any of registered handlers performed
3464
+ * successfully
3465
+ */
3466
+ exec: function(skipValue, args) {
3467
+ args = args || [];
3468
+ var result = null;
3469
+ utils.find(this.list(), function(h) {
3470
+ result = h.fn.apply(h, args);
3471
+ if (result !== skipValue) {
3472
+ return true;
3473
+ }
3474
+ });
3475
+
3476
+ return result;
3477
+ }
3478
+ };
3479
+
3480
+ return {
3481
+ /**
3482
+ * Factory method that produces <code>HandlerList</code> instance
3483
+ * @returns {HandlerList}
3484
+ * @memberOf handlerList
3485
+ */
3486
+ create: function() {
3487
+ return new HandlerList();
3488
+ }
3489
+ };
3490
+ });
3491
+ },{"../utils/common":73}],26:[function(require,module,exports){
3492
+ /**
3493
+ * HTML matcher: takes string and searches for HTML tag pairs for given position
3494
+ *
3495
+ * Unlike “classic” matchers, it parses content from the specified
3496
+ * position, not from the start, so it may work even outside HTML documents
3497
+ * (for example, inside strings of programming languages like JavaScript, Python
3498
+ * etc.)
3499
+ */
3500
+ if (typeof module === 'object' && typeof define !== 'function') {
3501
+ var define = function (factory) {
3502
+ module.exports = factory(require, exports, module);
3503
+ };
3504
+ }
3505
+
3506
+ define(function(require, exports, module) {
3507
+ var range = require('./range');
3508
+
3509
+ // Regular Expressions for parsing tags and attributes
3510
+ var reOpenTag = /^<([\w\:\-]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
3511
+ var reCloseTag = /^<\/([\w\:\-]+)[^>]*>/;
3512
+
3513
+ function openTag(i, match) {
3514
+ return {
3515
+ name: match[1],
3516
+ selfClose: !!match[3],
3517
+ /** @type Range */
3518
+ range: range(i, match[0]),
3519
+ type: 'open'
3520
+ };
3521
+ }
3522
+
3523
+ function closeTag(i, match) {
3524
+ return {
3525
+ name: match[1],
3526
+ /** @type Range */
3527
+ range: range(i, match[0]),
3528
+ type: 'close'
3529
+ };
3530
+ }
3531
+
3532
+ function comment(i, match) {
3533
+ return {
3534
+ /** @type Range */
3535
+ range: range(i, typeof match == 'number' ? match - i : match[0]),
3536
+ type: 'comment'
3537
+ };
3538
+ }
3539
+
3540
+ /**
3541
+ * Creates new tag matcher session
3542
+ * @param {String} text
3543
+ */
3544
+ function createMatcher(text) {
3545
+ var memo = {}, m;
3546
+ return {
3547
+ /**
3548
+ * Test if given position matches opening tag
3549
+ * @param {Number} i
3550
+ * @returns {Object} Matched tag object
3551
+ */
3552
+ open: function(i) {
3553
+ var m = this.matches(i);
3554
+ return m && m.type == 'open' ? m : null;
3555
+ },
3556
+
3557
+ /**
3558
+ * Test if given position matches closing tag
3559
+ * @param {Number} i
3560
+ * @returns {Object} Matched tag object
3561
+ */
3562
+ close: function(i) {
3563
+ var m = this.matches(i);
3564
+ return m && m.type == 'close' ? m : null;
3565
+ },
3566
+
3567
+ /**
3568
+ * Matches either opening or closing tag for given position
3569
+ * @param i
3570
+ * @returns
3571
+ */
3572
+ matches: function(i) {
3573
+ var key = 'p' + i;
3574
+
3575
+ if (!(key in memo)) {
3576
+ memo[key] = false;
3577
+ if (text.charAt(i) == '<') {
3578
+ var substr = text.slice(i);
3579
+ if ((m = substr.match(reOpenTag))) {
3580
+ memo[key] = openTag(i, m);
3581
+ } else if ((m = substr.match(reCloseTag))) {
3582
+ memo[key] = closeTag(i, m);
3583
+ }
3584
+ }
3585
+ }
3586
+
3587
+ return memo[key];
3588
+ },
3589
+
3590
+ /**
3591
+ * Returns original text
3592
+ * @returns {String}
3593
+ */
3594
+ text: function() {
3595
+ return text;
3596
+ },
3597
+
3598
+ clean: function() {
3599
+ memo = text = m = null;
3600
+ }
3601
+ };
3602
+ }
3603
+
3604
+ function matches(text, pos, pattern) {
3605
+ return text.substring(pos, pos + pattern.length) == pattern;
3606
+ }
3607
+
3608
+ /**
3609
+ * Search for closing pair of opening tag
3610
+ * @param {Object} open Open tag instance
3611
+ * @param {Object} matcher Matcher instance
3612
+ */
3613
+ function findClosingPair(open, matcher) {
3614
+ var stack = [], tag = null;
3615
+ var text = matcher.text();
3616
+
3617
+ for (var pos = open.range.end, len = text.length; pos < len; pos++) {
3618
+ if (matches(text, pos, '<!--')) {
3619
+ // skip to end of comment
3620
+ for (var j = pos; j < len; j++) {
3621
+ if (matches(text, j, '-->')) {
3622
+ pos = j + 3;
3623
+ break;
3624
+ }
3625
+ }
3626
+ }
3627
+
3628
+ if ((tag = matcher.matches(pos))) {
3629
+ if (tag.type == 'open' && !tag.selfClose) {
3630
+ stack.push(tag.name);
3631
+ } else if (tag.type == 'close') {
3632
+ if (!stack.length) { // found valid pair?
3633
+ return tag.name == open.name ? tag : null;
3634
+ }
3635
+
3636
+ // check if current closing tag matches previously opened one
3637
+ if (stack[stack.length - 1] == tag.name) {
3638
+ stack.pop();
3639
+ } else {
3640
+ var found = false;
3641
+ while (stack.length && !found) {
3642
+ var last = stack.pop();
3643
+ if (last == tag.name) {
3644
+ found = true;
3645
+ }
3646
+ }
3647
+
3648
+ if (!stack.length && !found) {
3649
+ return tag.name == open.name ? tag : null;
3650
+ }
3651
+ }
3652
+ }
3653
+
3654
+ pos = tag.range.end - 1;
3655
+ }
3656
+ }
3657
+ }
3658
+
3659
+ return {
3660
+ /**
3661
+ * Main function: search for tag pair in <code>text</code> for given
3662
+ * position
3663
+ * @memberOf htmlMatcher
3664
+ * @param {String} text
3665
+ * @param {Number} pos
3666
+ * @returns {Object}
3667
+ */
3668
+ find: function(text, pos) {
3669
+ var matcher = createMatcher(text);
3670
+ var open = null, close = null;
3671
+ var j, jl;
3672
+
3673
+ for (var i = pos; i >= 0; i--) {
3674
+ if ((open = matcher.open(i))) {
3675
+ // found opening tag
3676
+ if (open.selfClose) {
3677
+ if (open.range.cmp(pos, 'lt', 'gt')) {
3678
+ // inside self-closing tag, found match
3679
+ break;
3680
+ }
3681
+
3682
+ // outside self-closing tag, continue
3683
+ continue;
3684
+ }
3685
+
3686
+ close = findClosingPair(open, matcher);
3687
+ if (close) {
3688
+ // found closing tag.
3689
+ var r = range.create2(open.range.start, close.range.end);
3690
+ if (r.contains(pos)) {
3691
+ break;
3692
+ }
3693
+ } else if (open.range.contains(pos)) {
3694
+ // we inside empty HTML tag like <br>
3695
+ break;
3696
+ }
3697
+
3698
+ open = null;
3699
+ } else if (matches(text, i, '-->')) {
3700
+ // skip back to comment start
3701
+ for (j = i - 1; j >= 0; j--) {
3702
+ if (matches(text, j, '-->')) {
3703
+ // found another comment end, do nothing
3704
+ break;
3705
+ } else if (matches(text, j, '<!--')) {
3706
+ i = j;
3707
+ break;
3708
+ }
3709
+ }
3710
+ } else if (matches(text, i, '<!--')) {
3711
+ // we're inside comment, match it
3712
+ for (j = i + 4, jl = text.length; j < jl; j++) {
3713
+ if (matches(text, j, '-->')) {
3714
+ j += 3;
3715
+ break;
3716
+ }
3717
+ }
3718
+
3719
+ open = comment(i, j);
3720
+ break;
3721
+ }
3722
+ }
3723
+
3724
+ matcher.clean();
3725
+
3726
+ if (open) {
3727
+ var outerRange = null;
3728
+ var innerRange = null;
3729
+
3730
+ if (close) {
3731
+ outerRange = range.create2(open.range.start, close.range.end);
3732
+ innerRange = range.create2(open.range.end, close.range.start);
3733
+ } else {
3734
+ outerRange = innerRange = range.create2(open.range.start, open.range.end);
3735
+ }
3736
+
3737
+ if (open.type == 'comment') {
3738
+ // adjust positions of inner range for comment
3739
+ var _c = outerRange.substring(text);
3740
+ innerRange.start += _c.length - _c.replace(/^<\!--\s*/, '').length;
3741
+ innerRange.end -= _c.length - _c.replace(/\s*-->$/, '').length;
3742
+ }
3743
+
3744
+ return {
3745
+ open: open,
3746
+ close: close,
3747
+ type: open.type == 'comment' ? 'comment' : 'tag',
3748
+ innerRange: innerRange,
3749
+ innerContent: function() {
3750
+ return this.innerRange.substring(text);
3751
+ },
3752
+ outerRange: outerRange,
3753
+ outerContent: function() {
3754
+ return this.outerRange.substring(text);
3755
+ },
3756
+ range: !innerRange.length() || !innerRange.cmp(pos, 'lte', 'gte') ? outerRange : innerRange,
3757
+ content: function() {
3758
+ return this.range.substring(text);
3759
+ },
3760
+ source: text
3761
+ };
3762
+ }
3763
+ },
3764
+
3765
+ /**
3766
+ * The same as <code>find()</code> method, but restricts matched result
3767
+ * to <code>tag</code> type
3768
+ * @param {String} text
3769
+ * @param {Number} pos
3770
+ * @returns {Object}
3771
+ */
3772
+ tag: function(text, pos) {
3773
+ var result = this.find(text, pos);
3774
+ if (result && result.type == 'tag') {
3775
+ return result;
3776
+ }
3777
+ }
3778
+ };
3779
+ });
3780
+ },{"./range":30}],27:[function(require,module,exports){
3781
+ /**
3782
+ * Simple logger for Emmet
3783
+ */
3784
+ if (typeof module === 'object' && typeof define !== 'function') {
3785
+ var define = function (factory) {
3786
+ module.exports = factory(require, exports, module);
3787
+ };
3788
+ }
3789
+
3790
+ define(function(require, exports, module) {
3791
+ return {
3792
+ log: function() {
3793
+ if (typeof console != 'undefined' && console.log) {
3794
+ console.log.apply(console, arguments);
3795
+ }
3796
+ }
3797
+ }
3798
+ })
3799
+ },{}],28:[function(require,module,exports){
3800
+ /**
3801
+ * Common module's preferences storage. This module
3802
+ * provides general storage for all module preferences, their description and
3803
+ * default values.<br><br>
3804
+ *
3805
+ * This module can also be used to list all available properties to create
3806
+ * UI for updating properties
3807
+ */
3808
+ if (typeof module === 'object' && typeof define !== 'function') {
3809
+ var define = function (factory) {
3810
+ module.exports = factory(require, exports, module);
3811
+ };
3812
+ }
3813
+
3814
+ define(function(require, exports, module) {
3815
+ var utils = require('../utils/common');
3816
+
3817
+ var preferences = {};
3818
+ var defaults = {};
3819
+ var _dbgDefaults = null;
3820
+ var _dbgPreferences = null;
3821
+
3822
+ function toBoolean(val) {
3823
+ if (typeof val === 'string') {
3824
+ val = val.toLowerCase();
3825
+ return val == 'yes' || val == 'true' || val == '1';
3826
+ }
3827
+
3828
+ return !!val;
3829
+ }
3830
+
3831
+ function isValueObj(obj) {
3832
+ return typeof obj === 'object'
3833
+ && !Array.isArray(obj)
3834
+ && 'value' in obj
3835
+ && Object.keys(obj).length < 3;
3836
+ }
3837
+
3838
+ return {
3839
+ /**
3840
+ * Creates new preference item with default value
3841
+ * @param {String} name Preference name. You can also pass object
3842
+ * with many options
3843
+ * @param {Object} value Preference default value
3844
+ * @param {String} description Item textual description
3845
+ * @memberOf preferences
3846
+ */
3847
+ define: function(name, value, description) {
3848
+ var prefs = name;
3849
+ if (typeof name === 'string') {
3850
+ prefs = {};
3851
+ prefs[name] = {
3852
+ value: value,
3853
+ description: description
3854
+ };
3855
+ }
3856
+
3857
+ Object.keys(prefs).forEach(function(k) {
3858
+ var v = prefs[k];
3859
+ defaults[k] = isValueObj(v) ? v : {value: v};
3860
+ });
3861
+ },
3862
+
3863
+ /**
3864
+ * Updates preference item value. Preference value should be defined
3865
+ * first with <code>define</code> method.
3866
+ * @param {String} name Preference name. You can also pass object
3867
+ * with many options
3868
+ * @param {Object} value Preference default value
3869
+ * @memberOf preferences
3870
+ */
3871
+ set: function(name, value) {
3872
+ var prefs = name;
3873
+ if (typeof name === 'string') {
3874
+ prefs = {};
3875
+ prefs[name] = value;
3876
+ }
3877
+
3878
+ Object.keys(prefs).forEach(function(k) {
3879
+ var v = prefs[k];
3880
+ if (!(k in defaults)) {
3881
+ throw new Error('Property "' + k + '" is not defined. You should define it first with `define` method of current module');
3882
+ }
3883
+
3884
+ // do not set value if it equals to default value
3885
+ if (v !== defaults[k].value) {
3886
+ // make sure we have value of correct type
3887
+ switch (typeof defaults[k].value) {
3888
+ case 'boolean':
3889
+ v = toBoolean(v);
3890
+ break;
3891
+ case 'number':
3892
+ v = parseInt(v + '', 10) || 0;
3893
+ break;
3894
+ default: // convert to string
3895
+ if (v !== null) {
3896
+ v += '';
3897
+ }
3898
+ }
3899
+
3900
+ preferences[k] = v;
3901
+ } else if (k in preferences) {
3902
+ delete preferences[k];
3903
+ }
3904
+ });
3905
+ },
3906
+
3907
+ /**
3908
+ * Returns preference value
3909
+ * @param {String} name
3910
+ * @returns {String} Returns <code>undefined</code> if preference is
3911
+ * not defined
3912
+ */
3913
+ get: function(name) {
3914
+ if (name in preferences) {
3915
+ return preferences[name];
3916
+ }
3917
+
3918
+ if (name in defaults) {
3919
+ return defaults[name].value;
3920
+ }
3921
+
3922
+ return void 0;
3923
+ },
3924
+
3925
+ /**
3926
+ * Returns comma-separated preference value as array of values
3927
+ * @param {String} name
3928
+ * @returns {Array} Returns <code>undefined</code> if preference is
3929
+ * not defined, <code>null</code> if string cannot be converted to array
3930
+ */
3931
+ getArray: function(name) {
3932
+ var val = this.get(name);
3933
+ if (typeof val === 'undefined' || val === null || val === '') {
3934
+ return null;
3935
+ }
3936
+
3937
+ val = val.split(',').map(utils.trim);
3938
+ if (!val.length) {
3939
+ return null;
3940
+ }
3941
+
3942
+ return val;
3943
+ },
3944
+
3945
+ /**
3946
+ * Returns comma and colon-separated preference value as dictionary
3947
+ * @param {String} name
3948
+ * @returns {Object}
3949
+ */
3950
+ getDict: function(name) {
3951
+ var result = {};
3952
+ this.getArray(name).forEach(function(val) {
3953
+ var parts = val.split(':');
3954
+ result[parts[0]] = parts[1];
3955
+ });
3956
+
3957
+ return result;
3958
+ },
3959
+
3960
+ /**
3961
+ * Returns description of preference item
3962
+ * @param {String} name Preference name
3963
+ * @returns {Object}
3964
+ */
3965
+ description: function(name) {
3966
+ return name in defaults ? defaults[name].description : void 0;
3967
+ },
3968
+
3969
+ /**
3970
+ * Completely removes specified preference(s)
3971
+ * @param {String} name Preference name (or array of names)
3972
+ */
3973
+ remove: function(name) {
3974
+ if (!Array.isArray(name)) {
3975
+ name = [name];
3976
+ }
3977
+
3978
+ name.forEach(function(key) {
3979
+ if (key in preferences) {
3980
+ delete preferences[key];
3981
+ }
3982
+
3983
+ if (key in defaults) {
3984
+ delete defaults[key];
3985
+ }
3986
+ });
3987
+ },
3988
+
3989
+ /**
3990
+ * Returns sorted list of all available properties
3991
+ * @returns {Array}
3992
+ */
3993
+ list: function() {
3994
+ return Object.keys(defaults).sort().map(function(key) {
3995
+ return {
3996
+ name: key,
3997
+ value: this.get(key),
3998
+ type: typeof defaults[key].value,
3999
+ description: defaults[key].description
4000
+ };
4001
+ }, this);
4002
+ },
4003
+
4004
+ /**
4005
+ * Loads user-defined preferences from JSON
4006
+ * @param {Object} json
4007
+ * @returns
4008
+ */
4009
+ load: function(json) {
4010
+ Object.keys(json).forEach(function(key) {
4011
+ this.set(key, json[key]);
4012
+ }, this);
4013
+ },
4014
+
4015
+ /**
4016
+ * Returns hash of user-modified preferences
4017
+ * @returns {Object}
4018
+ */
4019
+ exportModified: function() {
4020
+ return utils.extend({}, preferences);
4021
+ },
4022
+
4023
+ /**
4024
+ * Reset to defaults
4025
+ * @returns
4026
+ */
4027
+ reset: function() {
4028
+ preferences = {};
4029
+ },
4030
+
4031
+ /**
4032
+ * For unit testing: use empty storage
4033
+ */
4034
+ _startTest: function() {
4035
+ _dbgDefaults = defaults;
4036
+ _dbgPreferences = preferences;
4037
+ defaults = {};
4038
+ preferences = {};
4039
+ },
4040
+
4041
+ /**
4042
+ * For unit testing: restore original storage
4043
+ */
4044
+ _stopTest: function() {
4045
+ defaults = _dbgDefaults;
4046
+ preferences = _dbgPreferences;
4047
+ }
4048
+ };
4049
+ });
4050
+ },{"../utils/common":73}],29:[function(require,module,exports){
4051
+ /**
4052
+ * Output profile module.
4053
+ * Profile defines how XHTML output data should look like
4054
+ */
4055
+ if (typeof module === 'object' && typeof define !== 'function') {
4056
+ var define = function (factory) {
4057
+ module.exports = factory(require, exports, module);
4058
+ };
4059
+ }
4060
+
4061
+ define(function(require, exports, module) {
4062
+ var utils = require('../utils/common');
4063
+ var resources = require('./resources');
4064
+ var prefs = require('./preferences');
4065
+
4066
+ prefs.define('profile.allowCompactBoolean', true,
4067
+ 'This option can be used to globally disable compact form of boolean ' +
4068
+ 'attribues (attributes where name and value are equal). With compact' +
4069
+ 'form enabled, HTML tags can be outputted as <code>&lt;div contenteditable&gt;</code> ' +
4070
+ 'instead of <code>&lt;div contenteditable="contenteditable"&gt;</code>');
4071
+
4072
+ prefs.define('profile.booleanAttributes', '^contenteditable|seamless$',
4073
+ 'A regular expression for attributes that should be boolean by default.' +
4074
+ 'If attribute name matches this expression, you don’t have to write dot ' +
4075
+ 'after attribute name in Emmet abbreviation to mark it as boolean.');
4076
+
4077
+ var profiles = {};
4078
+
4079
+ var defaultProfile = {
4080
+ tag_case: 'asis',
4081
+ attr_case: 'asis',
4082
+ attr_quotes: 'double',
4083
+
4084
+ // Each tag on new line
4085
+ tag_nl: 'decide',
4086
+
4087
+ // With tag_nl === true, defines if leaf node (e.g. node with no children)
4088
+ // should have formatted line breaks
4089
+ tag_nl_leaf: false,
4090
+
4091
+ place_cursor: true,
4092
+
4093
+ // Indent tags
4094
+ indent: true,
4095
+
4096
+ // How many inline elements should be to force line break
4097
+ // (set to 0 to disable)
4098
+ inline_break: 3,
4099
+
4100
+ // Produce compact notation of boolean attribues:
4101
+ // attributes where name and value are equal.
4102
+ // With this option enabled, HTML filter will
4103
+ // produce <div contenteditable> instead of <div contenteditable="contenteditable">
4104
+ compact_bool: false,
4105
+
4106
+ // Use self-closing style for writing empty elements, e.g. <br /> or <br>
4107
+ self_closing_tag: 'xhtml',
4108
+
4109
+ // Profile-level output filters, re-defines syntax filters
4110
+ filters: '',
4111
+
4112
+ // Additional filters applied to abbreviation.
4113
+ // Unlike "filters", this preference doesn't override default filters
4114
+ // but add the instead every time given profile is chosen
4115
+ extraFilters: ''
4116
+ };
4117
+
4118
+ /**
4119
+ * @constructor
4120
+ * @type OutputProfile
4121
+ * @param {Object} options
4122
+ */
4123
+ function OutputProfile(options) {
4124
+ utils.extend(this, defaultProfile, options);
4125
+ }
4126
+
4127
+ OutputProfile.prototype = {
4128
+ /**
4129
+ * Transforms tag name case depending on current profile settings
4130
+ * @param {String} name String to transform
4131
+ * @returns {String}
4132
+ */
4133
+ tagName: function(name) {
4134
+ return stringCase(name, this.tag_case);
4135
+ },
4136
+
4137
+ /**
4138
+ * Transforms attribute name case depending on current profile settings
4139
+ * @param {String} name String to transform
4140
+ * @returns {String}
4141
+ */
4142
+ attributeName: function(name) {
4143
+ return stringCase(name, this.attr_case);
4144
+ },
4145
+
4146
+ /**
4147
+ * Returns quote character for current profile
4148
+ * @returns {String}
4149
+ */
4150
+ attributeQuote: function() {
4151
+ return this.attr_quotes == 'single' ? "'" : '"';
4152
+ },
4153
+
4154
+ /**
4155
+ * Returns self-closing tag symbol for current profile
4156
+ * @returns {String}
4157
+ */
4158
+ selfClosing: function() {
4159
+ if (this.self_closing_tag == 'xhtml')
4160
+ return ' /';
4161
+
4162
+ if (this.self_closing_tag === true)
4163
+ return '/';
4164
+
4165
+ return '';
4166
+ },
4167
+
4168
+ /**
4169
+ * Returns cursor token based on current profile settings
4170
+ * @returns {String}
4171
+ */
4172
+ cursor: function() {
4173
+ return this.place_cursor ? utils.getCaretPlaceholder() : '';
4174
+ },
4175
+
4176
+ /**
4177
+ * Check if attribute with given name is boolean,
4178
+ * e.g. written as `contenteditable` instead of
4179
+ * `contenteditable="contenteditable"`
4180
+ * @param {String} name Attribute name
4181
+ * @return {Boolean}
4182
+ */
4183
+ isBoolean: function(name, value) {
4184
+ if (name == value) {
4185
+ return true;
4186
+ }
4187
+
4188
+ var boolAttrs = prefs.get('profile.booleanAttributes');
4189
+ if (!value && boolAttrs) {
4190
+ boolAttrs = new RegExp(boolAttrs, 'i');
4191
+ return boolAttrs.test(name);
4192
+ }
4193
+
4194
+ return false;
4195
+ },
4196
+
4197
+ /**
4198
+ * Check if compact boolean attribute record is
4199
+ * allowed for current profile
4200
+ * @return {Boolean}
4201
+ */
4202
+ allowCompactBoolean: function() {
4203
+ return this.compact_bool && prefs.get('profile.allowCompactBoolean');
4204
+ }
4205
+ };
4206
+
4207
+ /**
4208
+ * Helper function that converts string case depending on
4209
+ * <code>caseValue</code>
4210
+ * @param {String} str String to transform
4211
+ * @param {String} caseValue Case value: can be <i>lower</i>,
4212
+ * <i>upper</i> and <i>leave</i>
4213
+ * @returns {String}
4214
+ */
4215
+ function stringCase(str, caseValue) {
4216
+ switch (String(caseValue || '').toLowerCase()) {
4217
+ case 'lower':
4218
+ return str.toLowerCase();
4219
+ case 'upper':
4220
+ return str.toUpperCase();
4221
+ }
4222
+
4223
+ return str;
4224
+ }
4225
+
4226
+ /**
4227
+ * Creates new output profile
4228
+ * @param {String} name Profile name
4229
+ * @param {Object} options Profile options
4230
+ */
4231
+ function createProfile(name, options) {
4232
+ return profiles[name.toLowerCase()] = new OutputProfile(options);
4233
+ }
4234
+
4235
+ function createDefaultProfiles() {
4236
+ createProfile('xhtml');
4237
+ createProfile('html', {self_closing_tag: false, compact_bool: true});
4238
+ createProfile('xml', {self_closing_tag: true, tag_nl: true});
4239
+ createProfile('plain', {tag_nl: false, indent: false, place_cursor: false});
4240
+ createProfile('line', {tag_nl: false, indent: false, extraFilters: 's'});
4241
+ createProfile('css', {tag_nl: true});
4242
+ createProfile('css_line', {tag_nl: false});
4243
+ }
4244
+
4245
+ createDefaultProfiles();
4246
+
4247
+ return {
4248
+ /**
4249
+ * Creates new output profile and adds it into internal dictionary
4250
+ * @param {String} name Profile name
4251
+ * @param {Object} options Profile options
4252
+ * @memberOf emmet.profile
4253
+ * @returns {Object} New profile
4254
+ */
4255
+ create: function(name, options) {
4256
+ if (arguments.length == 2)
4257
+ return createProfile(name, options);
4258
+ else
4259
+ // create profile object only
4260
+ return new OutputProfile(utils.defaults(name || {}, defaultProfile));
4261
+ },
4262
+
4263
+ /**
4264
+ * Returns profile by its name. If profile wasn't found, returns
4265
+ * 'plain' profile
4266
+ * @param {String} name Profile name. Might be profile itself
4267
+ * @param {String} syntax. Optional. Current editor syntax. If defined,
4268
+ * profile is searched in resources first, then in predefined profiles
4269
+ * @returns {Object}
4270
+ */
4271
+ get: function(name, syntax) {
4272
+ if (!name && syntax) {
4273
+ // search in user resources first
4274
+ var profile = resources.findItem(syntax, 'profile');
4275
+ if (profile) {
4276
+ name = profile;
4277
+ }
4278
+ }
4279
+
4280
+ if (!name) {
4281
+ return profiles.plain;
4282
+ }
4283
+
4284
+ if (name instanceof OutputProfile) {
4285
+ return name;
4286
+ }
4287
+
4288
+ if (typeof name === 'string' && name.toLowerCase() in profiles) {
4289
+ return profiles[name.toLowerCase()];
4290
+ }
4291
+
4292
+ return this.create(name);
4293
+ },
4294
+
4295
+ /**
4296
+ * Deletes profile with specified name
4297
+ * @param {String} name Profile name
4298
+ */
4299
+ remove: function(name) {
4300
+ name = (name || '').toLowerCase();
4301
+ if (name in profiles)
4302
+ delete profiles[name];
4303
+ },
4304
+
4305
+ /**
4306
+ * Resets all user-defined profiles
4307
+ */
4308
+ reset: function() {
4309
+ profiles = {};
4310
+ createDefaultProfiles();
4311
+ },
4312
+
4313
+ /**
4314
+ * Helper function that converts string case depending on
4315
+ * <code>caseValue</code>
4316
+ * @param {String} str String to transform
4317
+ * @param {String} caseValue Case value: can be <i>lower</i>,
4318
+ * <i>upper</i> and <i>leave</i>
4319
+ * @returns {String}
4320
+ */
4321
+ stringCase: stringCase
4322
+ };
4323
+ });
4324
+ },{"../utils/common":73,"./preferences":28,"./resources":31}],30:[function(require,module,exports){
4325
+ /**
4326
+ * Helper module to work with ranges
4327
+ */
4328
+ if (typeof module === 'object' && typeof define !== 'function') {
4329
+ var define = function (factory) {
4330
+ module.exports = factory(require, exports, module);
4331
+ };
4332
+ }
4333
+
4334
+ define(function(require, exports, module) {
4335
+ function cmp(a, b, op) {
4336
+ switch (op) {
4337
+ case 'eq':
4338
+ case '==':
4339
+ return a === b;
4340
+ case 'lt':
4341
+ case '<':
4342
+ return a < b;
4343
+ case 'lte':
4344
+ case '<=':
4345
+ return a <= b;
4346
+ case 'gt':
4347
+ case '>':
4348
+ return a > b;
4349
+ case 'gte':
4350
+ case '>=':
4351
+ return a >= b;
4352
+ }
4353
+ }
4354
+
4355
+
4356
+ /**
4357
+ * @type Range
4358
+ * @constructor
4359
+ * @param {Object} start
4360
+ * @param {Number} len
4361
+ */
4362
+ function Range(start, len) {
4363
+ if (typeof start === 'object' && 'start' in start) {
4364
+ // create range from object stub
4365
+ this.start = Math.min(start.start, start.end);
4366
+ this.end = Math.max(start.start, start.end);
4367
+ } else if (Array.isArray(start)) {
4368
+ this.start = start[0];
4369
+ this.end = start[1];
4370
+ } else {
4371
+ len = typeof len === 'string' ? len.length : +len;
4372
+ this.start = start;
4373
+ this.end = start + len;
4374
+ }
4375
+ }
4376
+
4377
+ Range.prototype = {
4378
+ length: function() {
4379
+ return Math.abs(this.end - this.start);
4380
+ },
4381
+
4382
+ /**
4383
+ * Returns <code>true</code> if passed range is equals to current one
4384
+ * @param {Range} range
4385
+ * @returns {Boolean}
4386
+ */
4387
+ equal: function(range) {
4388
+ return this.cmp(range, 'eq', 'eq');
4389
+ // return this.start === range.start && this.end === range.end;
4390
+ },
4391
+
4392
+ /**
4393
+ * Shifts indexes position with passed <code>delta</code>
4394
+ * @param {Number} delta
4395
+ * @returns {Range} range itself
4396
+ */
4397
+ shift: function(delta) {
4398
+ this.start += delta;
4399
+ this.end += delta;
4400
+ return this;
4401
+ },
4402
+
4403
+ /**
4404
+ * Check if two ranges are overlapped
4405
+ * @param {Range} range
4406
+ * @returns {Boolean}
4407
+ */
4408
+ overlap: function(range) {
4409
+ return range.start <= this.end && range.end >= this.start;
4410
+ },
4411
+
4412
+ /**
4413
+ * Finds intersection of two ranges
4414
+ * @param {Range} range
4415
+ * @returns {Range} <code>null</code> if ranges does not overlap
4416
+ */
4417
+ intersection: function(range) {
4418
+ if (this.overlap(range)) {
4419
+ var start = Math.max(range.start, this.start);
4420
+ var end = Math.min(range.end, this.end);
4421
+ return new Range(start, end - start);
4422
+ }
4423
+
4424
+ return null;
4425
+ },
4426
+
4427
+ /**
4428
+ * Returns the union of the thow ranges.
4429
+ * @param {Range} range
4430
+ * @returns {Range} <code>null</code> if ranges are not overlapped
4431
+ */
4432
+ union: function(range) {
4433
+ if (this.overlap(range)) {
4434
+ var start = Math.min(range.start, this.start);
4435
+ var end = Math.max(range.end, this.end);
4436
+ return new Range(start, end - start);
4437
+ }
4438
+
4439
+ return null;
4440
+ },
4441
+
4442
+ /**
4443
+ * Returns a Boolean value that indicates whether a specified position
4444
+ * is in a given range.
4445
+ * @param {Number} loc
4446
+ */
4447
+ inside: function(loc) {
4448
+ return this.cmp(loc, 'lte', 'gt');
4449
+ // return this.start <= loc && this.end > loc;
4450
+ },
4451
+
4452
+ /**
4453
+ * Returns a Boolean value that indicates whether a specified position
4454
+ * is in a given range, but not equals bounds.
4455
+ * @param {Number} loc
4456
+ */
4457
+ contains: function(loc) {
4458
+ return this.cmp(loc, 'lt', 'gt');
4459
+ },
4460
+
4461
+ /**
4462
+ * Check if current range completely includes specified one
4463
+ * @param {Range} r
4464
+ * @returns {Boolean}
4465
+ */
4466
+ include: function(r) {
4467
+ return this.cmp(r, 'lte', 'gte');
4468
+ // return this.start <= r.start && this.end >= r.end;
4469
+ },
4470
+
4471
+ /**
4472
+ * Low-level comparision method
4473
+ * @param {Number} loc
4474
+ * @param {String} left Left comparison operator
4475
+ * @param {String} right Right comaprison operator
4476
+ */
4477
+ cmp: function(loc, left, right) {
4478
+ var a, b;
4479
+ if (loc instanceof Range) {
4480
+ a = loc.start;
4481
+ b = loc.end;
4482
+ } else {
4483
+ a = b = loc;
4484
+ }
4485
+
4486
+ return cmp(this.start, a, left || '<=') && cmp(this.end, b, right || '>');
4487
+ },
4488
+
4489
+ /**
4490
+ * Returns substring of specified <code>str</code> for current range
4491
+ * @param {String} str
4492
+ * @returns {String}
4493
+ */
4494
+ substring: function(str) {
4495
+ return this.length() > 0
4496
+ ? str.substring(this.start, this.end)
4497
+ : '';
4498
+ },
4499
+
4500
+ /**
4501
+ * Creates copy of current range
4502
+ * @returns {Range}
4503
+ */
4504
+ clone: function() {
4505
+ return new Range(this.start, this.length());
4506
+ },
4507
+
4508
+ /**
4509
+ * @returns {Array}
4510
+ */
4511
+ toArray: function() {
4512
+ return [this.start, this.end];
4513
+ },
4514
+
4515
+ toString: function() {
4516
+ return this.valueOf();
4517
+ },
4518
+
4519
+ valueOf: function() {
4520
+ return '{' + this.start + ', ' + this.length() + '}';
4521
+ }
4522
+ };
4523
+
4524
+ /**
4525
+ * Creates new range object instance
4526
+ * @param {Object} start Range start or array with 'start' and 'end'
4527
+ * as two first indexes or object with 'start' and 'end' properties
4528
+ * @param {Number} len Range length or string to produce range from
4529
+ * @returns {Range}
4530
+ */
4531
+ module.exports = function(start, len) {
4532
+ if (typeof start == 'undefined' || start === null)
4533
+ return null;
4534
+
4535
+ if (start instanceof Range)
4536
+ return start;
4537
+
4538
+ if (typeof start == 'object' && 'start' in start && 'end' in start) {
4539
+ len = start.end - start.start;
4540
+ start = start.start;
4541
+ }
4542
+
4543
+ return new Range(start, len);
4544
+ };
4545
+
4546
+ module.exports.create = module.exports;
4547
+
4548
+ module.exports.isRange = function(val) {
4549
+ return val instanceof Range;
4550
+ };
4551
+
4552
+ /**
4553
+ * <code>Range</code> object factory, the same as <code>this.create()</code>
4554
+ * but last argument represents end of range, not length
4555
+ * @returns {Range}
4556
+ */
4557
+ module.exports.create2 = function(start, end) {
4558
+ if (typeof start === 'number' && typeof end === 'number') {
4559
+ end -= start;
4560
+ }
4561
+
4562
+ return this.create(start, end);
4563
+ };
4564
+
4565
+ /**
4566
+ * Helper function that sorts ranges in order as they
4567
+ * appear in text
4568
+ * @param {Array} ranges
4569
+ * @return {Array}
4570
+ */
4571
+ module.exports.sort = function(ranges, reverse) {
4572
+ ranges = ranges.sort(function(a, b) {
4573
+ if (a.start === b.start) {
4574
+ return b.end - a.end;
4575
+ }
4576
+
4577
+ return a.start - b.start;
4578
+ });
4579
+
4580
+ reverse && ranges.reverse();
4581
+ return ranges;
4582
+ };
4583
+
4584
+ return module.exports;
4585
+ });
4586
+ },{}],31:[function(require,module,exports){
4587
+ /**
4588
+ * Parsed resources (snippets, abbreviations, variables, etc.) for Emmet.
4589
+ * Contains convenient method to get access for snippets with respect of
4590
+ * inheritance. Also provides ability to store data in different vocabularies
4591
+ * ('system' and 'user') for fast and safe resource update
4592
+ * @author Sergey Chikuyonok (serge.che@gmail.com)
4593
+ * @link http://chikuyonok.ru
4594
+ */
4595
+ if (typeof module === 'object' && typeof define !== 'function') {
4596
+ var define = function (factory) {
4597
+ module.exports = factory(require, exports, module);
4598
+ };
4599
+ }
4600
+
4601
+ define(function(require, exports, module) {
4602
+ var handlerList = require('./handlerList');
4603
+ var utils = require('../utils/common');
4604
+ var elements = require('./elements');
4605
+ var logger = require('../assets/logger');
4606
+ var stringScore = require('../vendor/stringScore');
4607
+ var cssResolver = require('../resolver/css');
4608
+
4609
+ var VOC_SYSTEM = 'system';
4610
+ var VOC_USER = 'user';
4611
+
4612
+ var cache = {};
4613
+
4614
+ /** Regular expression for XML tag matching */
4615
+ var reTag = /^<(\w+\:?[\w\-]*)((?:\s+[@\!]?[\w\:\-]+\s*=\s*(['"]).*?\3)*)\s*(\/?)>/;
4616
+
4617
+ var systemSettings = {};
4618
+ var userSettings = {};
4619
+
4620
+ /** @type HandlerList List of registered abbreviation resolvers */
4621
+ var resolvers = handlerList.create();
4622
+
4623
+ function each(obj, fn) {
4624
+ if (!obj) {
4625
+ return;
4626
+ }
4627
+
4628
+ Object.keys(obj).forEach(function(key) {
4629
+ fn(obj[key], key);
4630
+ });
4631
+ }
4632
+
4633
+ /**
4634
+ * Normalizes caret plceholder in passed text: replaces | character with
4635
+ * default caret placeholder
4636
+ * @param {String} text
4637
+ * @returns {String}
4638
+ */
4639
+ function normalizeCaretPlaceholder(text) {
4640
+ return utils.replaceUnescapedSymbol(text, '|', utils.getCaretPlaceholder());
4641
+ }
4642
+
4643
+ function parseItem(name, value, type) {
4644
+ value = normalizeCaretPlaceholder(value);
4645
+
4646
+ if (type == 'snippets') {
4647
+ return elements.create('snippet', value);
4648
+ }
4649
+
4650
+ if (type == 'abbreviations') {
4651
+ return parseAbbreviation(name, value);
4652
+ }
4653
+ }
4654
+
4655
+ /**
4656
+ * Parses single abbreviation
4657
+ * @param {String} key Abbreviation name
4658
+ * @param {String} value Abbreviation value
4659
+ * @return {Object}
4660
+ */
4661
+ function parseAbbreviation(key, value) {
4662
+ key = utils.trim(key);
4663
+ var m;
4664
+ if ((m = reTag.exec(value))) {
4665
+ return elements.create('element', m[1], m[2], m[4] == '/');
4666
+ } else {
4667
+ // assume it's reference to another abbreviation
4668
+ return elements.create('reference', value);
4669
+ }
4670
+ }
4671
+
4672
+ /**
4673
+ * Normalizes snippet key name for better fuzzy search
4674
+ * @param {String} str
4675
+ * @returns {String}
4676
+ */
4677
+ function normalizeName(str) {
4678
+ return str.replace(/:$/, '').replace(/:/g, '-');
4679
+ }
4680
+
4681
+ function expandSnippetsDefinition(snippets) {
4682
+ var out = {};
4683
+ each(snippets, function(val, key) {
4684
+ var items = key.split('|');
4685
+ // do not use iterators for better performance
4686
+ for (var i = items.length - 1; i >= 0; i--) {
4687
+ out[items[i]] = val;
4688
+ }
4689
+ });
4690
+
4691
+ return out;
4692
+ }
4693
+
4694
+ utils.extend(exports, {
4695
+ /**
4696
+ * Sets new unparsed data for specified settings vocabulary
4697
+ * @param {Object} data
4698
+ * @param {String} type Vocabulary type ('system' or 'user')
4699
+ * @memberOf resources
4700
+ */
4701
+ setVocabulary: function(data, type) {
4702
+ cache = {};
4703
+
4704
+ // sections like "snippets" and "abbreviations" could have
4705
+ // definitions like `"f|fs": "fieldset"` which is the same as distinct
4706
+ // "f" and "fs" keys both equals to "fieldset".
4707
+ // We should parse these definitions first
4708
+ var voc = {};
4709
+ each(data, function(section, syntax) {
4710
+ var _section = {};
4711
+ each(section, function(subsection, name) {
4712
+ if (name == 'abbreviations' || name == 'snippets') {
4713
+ subsection = expandSnippetsDefinition(subsection);
4714
+ }
4715
+ _section[name] = subsection;
4716
+ });
4717
+
4718
+ voc[syntax] = _section;
4719
+ });
4720
+
4721
+
4722
+ if (type == VOC_SYSTEM) {
4723
+ systemSettings = voc;
4724
+ } else {
4725
+ userSettings = voc;
4726
+ }
4727
+ },
4728
+
4729
+ /**
4730
+ * Returns resource vocabulary by its name
4731
+ * @param {String} name Vocabulary name ('system' or 'user')
4732
+ * @return {Object}
4733
+ */
4734
+ getVocabulary: function(name) {
4735
+ return name == VOC_SYSTEM ? systemSettings : userSettings;
4736
+ },
4737
+
4738
+ /**
4739
+ * Returns resource (abbreviation, snippet, etc.) matched for passed
4740
+ * abbreviation
4741
+ * @param {AbbreviationNode} node
4742
+ * @param {String} syntax
4743
+ * @returns {Object}
4744
+ */
4745
+ getMatchedResource: function(node, syntax) {
4746
+ return resolvers.exec(null, utils.toArray(arguments))
4747
+ || this.findSnippet(syntax, node.name());
4748
+ },
4749
+
4750
+ /**
4751
+ * Returns variable value
4752
+ * @return {String}
4753
+ */
4754
+ getVariable: function(name) {
4755
+ return (this.getSection('variables') || {})[name];
4756
+ },
4757
+
4758
+ /**
4759
+ * Store runtime variable in user storage
4760
+ * @param {String} name Variable name
4761
+ * @param {String} value Variable value
4762
+ */
4763
+ setVariable: function(name, value){
4764
+ var voc = this.getVocabulary('user') || {};
4765
+ if (!('variables' in voc))
4766
+ voc.variables = {};
4767
+
4768
+ voc.variables[name] = value;
4769
+ this.setVocabulary(voc, 'user');
4770
+ },
4771
+
4772
+ /**
4773
+ * Check if there are resources for specified syntax
4774
+ * @param {String} syntax
4775
+ * @return {Boolean}
4776
+ */
4777
+ hasSyntax: function(syntax) {
4778
+ return syntax in this.getVocabulary(VOC_USER)
4779
+ || syntax in this.getVocabulary(VOC_SYSTEM);
4780
+ },
4781
+
4782
+ /**
4783
+ * Registers new abbreviation resolver.
4784
+ * @param {Function} fn Abbreviation resolver which will receive
4785
+ * abbreviation as first argument and should return parsed abbreviation
4786
+ * object if abbreviation has handled successfully, <code>null</code>
4787
+ * otherwise
4788
+ * @param {Object} options Options list as described in
4789
+ * {@link HandlerList#add()} method
4790
+ */
4791
+ addResolver: function(fn, options) {
4792
+ resolvers.add(fn, options);
4793
+ },
4794
+
4795
+ removeResolver: function(fn) {
4796
+ resolvers.remove(fn);
4797
+ },
4798
+
4799
+ /**
4800
+ * Returns actual section data, merged from both
4801
+ * system and user data
4802
+ * @param {String} name Section name (syntax)
4803
+ * @param {String} ...args Subsections
4804
+ * @returns
4805
+ */
4806
+ getSection: function(name) {
4807
+ if (!name)
4808
+ return null;
4809
+
4810
+ if (!(name in cache)) {
4811
+ cache[name] = utils.deepMerge({}, systemSettings[name], userSettings[name]);
4812
+ }
4813
+
4814
+ var data = cache[name], subsections = utils.toArray(arguments, 1), key;
4815
+ while (data && (key = subsections.shift())) {
4816
+ if (key in data) {
4817
+ data = data[key];
4818
+ } else {
4819
+ return null;
4820
+ }
4821
+ }
4822
+
4823
+ return data;
4824
+ },
4825
+
4826
+ /**
4827
+ * Recursively searches for a item inside top level sections (syntaxes)
4828
+ * with respect of `extends` attribute
4829
+ * @param {String} topSection Top section name (syntax)
4830
+ * @param {String} subsection Inner section name
4831
+ * @returns {Object}
4832
+ */
4833
+ findItem: function(topSection, subsection) {
4834
+ var data = this.getSection(topSection);
4835
+ while (data) {
4836
+ if (subsection in data)
4837
+ return data[subsection];
4838
+
4839
+ data = this.getSection(data['extends']);
4840
+ }
4841
+ },
4842
+
4843
+ /**
4844
+ * Recursively searches for a snippet definition inside syntax section.
4845
+ * Definition is searched inside `snippets` and `abbreviations`
4846
+ * subsections
4847
+ * @param {String} syntax Top-level section name (syntax)
4848
+ * @param {String} name Snippet name
4849
+ * @returns {Object}
4850
+ */
4851
+ findSnippet: function(syntax, name, memo) {
4852
+ if (!syntax || !name)
4853
+ return null;
4854
+
4855
+ memo = memo || [];
4856
+
4857
+ var names = [name];
4858
+ // create automatic aliases to properties with colons,
4859
+ // e.g. pos-a == pos:a
4860
+ if (~name.indexOf('-')) {
4861
+ names.push(name.replace(/\-/g, ':'));
4862
+ }
4863
+
4864
+ var data = this.getSection(syntax), matchedItem = null;
4865
+ ['snippets', 'abbreviations'].some(function(sectionName) {
4866
+ var data = this.getSection(syntax, sectionName);
4867
+ if (data) {
4868
+ return names.some(function(n) {
4869
+ if (data[n]) {
4870
+ return matchedItem = parseItem(n, data[n], sectionName);
4871
+ }
4872
+ });
4873
+ }
4874
+ }, this);
4875
+
4876
+ memo.push(syntax);
4877
+ if (!matchedItem && data['extends'] && !~memo.indexOf(data['extends'])) {
4878
+ // try to find item in parent syntax section
4879
+ return this.findSnippet(data['extends'], name, memo);
4880
+ }
4881
+
4882
+ return matchedItem;
4883
+ },
4884
+
4885
+ /**
4886
+ * Performs fuzzy search of snippet definition
4887
+ * @param {String} syntax Top-level section name (syntax)
4888
+ * @param {String} name Snippet name
4889
+ * @returns
4890
+ */
4891
+ fuzzyFindSnippet: function(syntax, name, minScore) {
4892
+ var result = this.fuzzyFindMatches(syntax, name, minScore)[0];
4893
+ if (result) {
4894
+ return result.value.parsedValue;
4895
+ }
4896
+ },
4897
+
4898
+ fuzzyFindMatches: function(syntax, name, minScore) {
4899
+ minScore = minScore || 0.3;
4900
+ name = normalizeName(name);
4901
+ var snippets = this.getAllSnippets(syntax);
4902
+
4903
+ return Object.keys(snippets)
4904
+ .map(function(key) {
4905
+ var value = snippets[key];
4906
+ return {
4907
+ key: key,
4908
+ score: stringScore.score(value.nk, name, 0.1),
4909
+ value: value
4910
+ };
4911
+ })
4912
+ .filter(function(item) {
4913
+ return item.score >= minScore;
4914
+ })
4915
+ .sort(function(a, b) {
4916
+ return a.score - b.score;
4917
+ })
4918
+ .reverse();
4919
+ },
4920
+
4921
+ /**
4922
+ * Returns plain dictionary of all available abbreviations and snippets
4923
+ * for specified syntax with respect of inheritance
4924
+ * @param {String} syntax
4925
+ * @returns {Object}
4926
+ */
4927
+ getAllSnippets: function(syntax) {
4928
+ var cacheKey = 'all-' + syntax;
4929
+ if (!cache[cacheKey]) {
4930
+ var stack = [], sectionKey = syntax;
4931
+ var memo = [];
4932
+
4933
+ do {
4934
+ var section = this.getSection(sectionKey);
4935
+ if (!section)
4936
+ break;
4937
+
4938
+ ['snippets', 'abbreviations'].forEach(function(sectionName) {
4939
+ var stackItem = {};
4940
+ each(section[sectionName] || null, function(v, k) {
4941
+ stackItem[k] = {
4942
+ nk: normalizeName(k),
4943
+ value: v,
4944
+ parsedValue: parseItem(k, v, sectionName),
4945
+ type: sectionName
4946
+ };
4947
+ });
4948
+
4949
+ stack.push(stackItem);
4950
+ });
4951
+
4952
+ memo.push(sectionKey);
4953
+ sectionKey = section['extends'];
4954
+ } while (sectionKey && !~memo.indexOf(sectionKey));
4955
+
4956
+
4957
+ cache[cacheKey] = utils.extend.apply(utils, stack.reverse());
4958
+ }
4959
+
4960
+ return cache[cacheKey];
4961
+ },
4962
+
4963
+ /**
4964
+ * Returns newline character
4965
+ * @returns {String}
4966
+ */
4967
+ getNewline: function() {
4968
+ var nl = this.getVariable('newline');
4969
+ return typeof nl === 'string' ? nl : '\n';
4970
+ },
4971
+
4972
+ /**
4973
+ * Sets new newline character that will be used in output
4974
+ * @param {String} str
4975
+ */
4976
+ setNewline: function(str) {
4977
+ this.setVariable('newline', str);
4978
+ this.setVariable('nl', str);
4979
+ }
4980
+ });
4981
+
4982
+ // XXX add default resolvers
4983
+ exports.addResolver(cssResolver.resolve.bind(cssResolver));
4984
+
4985
+ // try to load snippets
4986
+ // hide it from Require.JS parser
4987
+ (function(r) {
4988
+ if (typeof define === 'undefined' || !define.amd) {
4989
+ try {
4990
+ var fs = r('fs');
4991
+ var path = r('path');
4992
+
4993
+ var defaultSnippets = fs.readFileSync(path.join(__dirname, '../snippets.json'), {encoding: 'utf8'});
4994
+ exports.setVocabulary(JSON.parse(defaultSnippets), VOC_SYSTEM);
4995
+ } catch (e) {}
4996
+ }
4997
+ })(require);
4998
+
4999
+
5000
+ return exports;
5001
+ });
5002
+ },{"../assets/logger":27,"../resolver/css":64,"../utils/common":73,"../vendor/stringScore":79,"./elements":24,"./handlerList":25}],32:[function(require,module,exports){
5003
+ /**
5004
+ * A trimmed version of CodeMirror's StringStream module for string parsing
5005
+ */
5006
+ if (typeof module === 'object' && typeof define !== 'function') {
5007
+ var define = function (factory) {
5008
+ module.exports = factory(require, exports, module);
5009
+ };
5010
+ }
5011
+
5012
+ define(function(require, exports, module) {
5013
+ /**
5014
+ * @type StringStream
5015
+ * @constructor
5016
+ * @param {String} string Assuming that bound string should be
5017
+ * immutable
5018
+ */
5019
+ function StringStream(string) {
5020
+ this.pos = this.start = 0;
5021
+ this.string = string;
5022
+ this._length = string.length;
5023
+ }
5024
+
5025
+ StringStream.prototype = {
5026
+ /**
5027
+ * Returns true only if the stream is at the end of the line.
5028
+ * @returns {Boolean}
5029
+ */
5030
+ eol: function() {
5031
+ return this.pos >= this._length;
5032
+ },
5033
+
5034
+ /**
5035
+ * Returns true only if the stream is at the start of the line
5036
+ * @returns {Boolean}
5037
+ */
5038
+ sol: function() {
5039
+ return this.pos === 0;
5040
+ },
5041
+
5042
+ /**
5043
+ * Returns the next character in the stream without advancing it.
5044
+ * Will return <code>undefined</code> at the end of the line.
5045
+ * @returns {String}
5046
+ */
5047
+ peek: function() {
5048
+ return this.string.charAt(this.pos);
5049
+ },
5050
+
5051
+ /**
5052
+ * Returns the next character in the stream and advances it.
5053
+ * Also returns <code>undefined</code> when no more characters are available.
5054
+ * @returns {String}
5055
+ */
5056
+ next: function() {
5057
+ if (this.pos < this._length)
5058
+ return this.string.charAt(this.pos++);
5059
+ },
5060
+
5061
+ /**
5062
+ * match can be a character, a regular expression, or a function that
5063
+ * takes a character and returns a boolean. If the next character in the
5064
+ * stream 'matches' the given argument, it is consumed and returned.
5065
+ * Otherwise, undefined is returned.
5066
+ * @param {Object} match
5067
+ * @returns {String}
5068
+ */
5069
+ eat: function(match) {
5070
+ var ch = this.string.charAt(this.pos), ok;
5071
+ if (typeof match == "string")
5072
+ ok = ch == match;
5073
+ else
5074
+ ok = ch && (match.test ? match.test(ch) : match(ch));
5075
+
5076
+ if (ok) {
5077
+ ++this.pos;
5078
+ return ch;
5079
+ }
5080
+ },
5081
+
5082
+ /**
5083
+ * Repeatedly calls <code>eat</code> with the given argument, until it
5084
+ * fails. Returns <code>true</code> if any characters were eaten.
5085
+ * @param {Object} match
5086
+ * @returns {Boolean}
5087
+ */
5088
+ eatWhile: function(match) {
5089
+ var start = this.pos;
5090
+ while (this.eat(match)) {}
5091
+ return this.pos > start;
5092
+ },
5093
+
5094
+ /**
5095
+ * Shortcut for <code>eatWhile</code> when matching white-space.
5096
+ * @returns {Boolean}
5097
+ */
5098
+ eatSpace: function() {
5099
+ var start = this.pos;
5100
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos)))
5101
+ ++this.pos;
5102
+ return this.pos > start;
5103
+ },
5104
+
5105
+ /**
5106
+ * Moves the position to the end of the line.
5107
+ */
5108
+ skipToEnd: function() {
5109
+ this.pos = this._length;
5110
+ },
5111
+
5112
+ /**
5113
+ * Skips to the next occurrence of the given character, if found on the
5114
+ * current line (doesn't advance the stream if the character does not
5115
+ * occur on the line). Returns true if the character was found.
5116
+ * @param {String} ch
5117
+ * @returns {Boolean}
5118
+ */
5119
+ skipTo: function(ch) {
5120
+ var found = this.string.indexOf(ch, this.pos);
5121
+ if (found > -1) {
5122
+ this.pos = found;
5123
+ return true;
5124
+ }
5125
+ },
5126
+
5127
+ /**
5128
+ * Skips to <code>close</code> character which is pair to <code>open</code>
5129
+ * character, considering possible pair nesting. This function is used
5130
+ * to consume pair of characters, like opening and closing braces
5131
+ * @param {String} open
5132
+ * @param {String} close
5133
+ * @returns {Boolean} Returns <code>true</code> if pair was successfully
5134
+ * consumed
5135
+ */
5136
+ skipToPair: function(open, close, skipString) {
5137
+ var braceCount = 0, ch;
5138
+ var pos = this.pos, len = this._length;
5139
+ while (pos < len) {
5140
+ ch = this.string.charAt(pos++);
5141
+ if (ch == open) {
5142
+ braceCount++;
5143
+ } else if (ch == close) {
5144
+ braceCount--;
5145
+ if (braceCount < 1) {
5146
+ this.pos = pos;
5147
+ return true;
5148
+ }
5149
+ } else if (skipString && (ch == '"' || ch == "'")) {
5150
+ this.skipString(ch);
5151
+ }
5152
+ }
5153
+
5154
+ return false;
5155
+ },
5156
+
5157
+ /**
5158
+ * A helper function which, in case of either single or
5159
+ * double quote was found in current position, skips entire
5160
+ * string (quoted value)
5161
+ * @return {Boolean} Wether quoted string was skipped
5162
+ */
5163
+ skipQuoted: function(noBackup) {
5164
+ var ch = this.string.charAt(noBackup ? this.pos : this.pos - 1);
5165
+ if (ch === '"' || ch === "'") {
5166
+ if (noBackup) {
5167
+ this.pos++;
5168
+ }
5169
+ return this.skipString(ch);
5170
+ }
5171
+ },
5172
+
5173
+ /**
5174
+ * A custom function to skip string literal, e.g. a "double-quoted"
5175
+ * or 'single-quoted' value
5176
+ * @param {String} quote An opening quote
5177
+ * @return {Boolean}
5178
+ */
5179
+ skipString: function(quote) {
5180
+ var pos = this.pos, len = this._length, ch;
5181
+ while (pos < len) {
5182
+ ch = this.string.charAt(pos++);
5183
+ if (ch == '\\') {
5184
+ continue;
5185
+ } else if (ch == quote) {
5186
+ this.pos = pos;
5187
+ return true;
5188
+ }
5189
+ }
5190
+
5191
+ return false;
5192
+ },
5193
+
5194
+ /**
5195
+ * Backs up the stream n characters. Backing it up further than the
5196
+ * start of the current token will cause things to break, so be careful.
5197
+ * @param {Number} n
5198
+ */
5199
+ backUp : function(n) {
5200
+ this.pos -= n;
5201
+ },
5202
+
5203
+ /**
5204
+ * Act like a multi-character <code>eat</code>—if <code>consume</code> is true or
5205
+ * not given—or a look-ahead that doesn't update the stream position—if
5206
+ * it is false. <code>pattern</code> can be either a string or a
5207
+ * regular expression starting with ^. When it is a string,
5208
+ * <code>caseInsensitive</code> can be set to true to make the match
5209
+ * case-insensitive. When successfully matching a regular expression,
5210
+ * the returned value will be the array returned by <code>match</code>,
5211
+ * in case you need to extract matched groups.
5212
+ *
5213
+ * @param {RegExp} pattern
5214
+ * @param {Boolean} consume
5215
+ * @param {Boolean} caseInsensitive
5216
+ * @returns
5217
+ */
5218
+ match: function(pattern, consume, caseInsensitive) {
5219
+ if (typeof pattern == "string") {
5220
+ var cased = caseInsensitive
5221
+ ? function(str) {return str.toLowerCase();}
5222
+ : function(str) {return str;};
5223
+
5224
+ if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
5225
+ if (consume !== false)
5226
+ this.pos += pattern.length;
5227
+ return true;
5228
+ }
5229
+ } else {
5230
+ var match = this.string.slice(this.pos).match(pattern);
5231
+ if (match && consume !== false)
5232
+ this.pos += match[0].length;
5233
+ return match;
5234
+ }
5235
+ },
5236
+
5237
+ /**
5238
+ * Get the string between the start of the current token and the
5239
+ * current stream position.
5240
+ * @returns {String}
5241
+ */
5242
+ current: function(backUp) {
5243
+ return this.string.slice(this.start, this.pos - (backUp ? 1 : 0));
5244
+ }
5245
+ };
5246
+
5247
+ module.exports = function(string) {
5248
+ return new StringStream(string);
5249
+ };
5250
+
5251
+ /** @deprecated */
5252
+ module.exports.create = module.exports;
5253
+ return module.exports;
5254
+ });
5255
+ },{}],33:[function(require,module,exports){
5256
+ /**
5257
+ * Utility module for handling tabstops tokens generated by Emmet's
5258
+ * "Expand Abbreviation" action. The main <code>extract</code> method will take
5259
+ * raw text (for example: <i>${0} some ${1:text}</i>), find all tabstops
5260
+ * occurrences, replace them with tokens suitable for your editor of choice and
5261
+ * return object with processed text and list of found tabstops and their ranges.
5262
+ * For sake of portability (Objective-C/Java) the tabstops list is a plain
5263
+ * sorted array with plain objects.
5264
+ *
5265
+ * Placeholders with the same are meant to be <i>linked</i> in your editor.
5266
+ */
5267
+ if (typeof module === 'object' && typeof define !== 'function') {
5268
+ var define = function (factory) {
5269
+ module.exports = factory(require, exports, module);
5270
+ };
5271
+ }
5272
+
5273
+ define(function(require, exports, module) {
5274
+ var utils = require('../utils/common');
5275
+ var stringStream = require('./stringStream');
5276
+ var resources = require('./resources');
5277
+
5278
+ /**
5279
+ * Global placeholder value, automatically incremented by
5280
+ * <code>variablesResolver()</code> function
5281
+ */
5282
+ var startPlaceholderNum = 100;
5283
+ var tabstopIndex = 0;
5284
+
5285
+ var defaultOptions = {
5286
+ replaceCarets: false,
5287
+ escape: function(ch) {
5288
+ return '\\' + ch;
5289
+ },
5290
+ tabstop: function(data) {
5291
+ return data.token;
5292
+ },
5293
+ variable: function(data) {
5294
+ return data.token;
5295
+ }
5296
+ };
5297
+
5298
+ return {
5299
+ /**
5300
+ * Main function that looks for a tabstops in provided <code>text</code>
5301
+ * and returns a processed version of <code>text</code> with expanded
5302
+ * placeholders and list of tabstops found.
5303
+ * @param {String} text Text to process
5304
+ * @param {Object} options List of processor options:<br>
5305
+ *
5306
+ * <b>replaceCarets</b> : <code>Boolean</code> — replace all default
5307
+ * caret placeholders (like <i>{%::emmet-caret::%}</i>) with <i>${0:caret}</i><br>
5308
+ *
5309
+ * <b>escape</b> : <code>Function</code> — function that handle escaped
5310
+ * characters (mostly '$'). By default, it returns the character itself
5311
+ * to be displayed as is in output, but sometimes you will use
5312
+ * <code>extract</code> method as intermediate solution for further
5313
+ * processing and want to keep character escaped. Thus, you should override
5314
+ * <code>escape</code> method to return escaped symbol (e.g. '\\$')<br>
5315
+ *
5316
+ * <b>tabstop</b> : <code>Function</code> – a tabstop handler. Receives
5317
+ * a single argument – an object describing token: its position, number
5318
+ * group, placeholder and token itself. Should return a replacement
5319
+ * string that will appear in final output
5320
+ *
5321
+ * <b>variable</b> : <code>Function</code> – variable handler. Receives
5322
+ * a single argument – an object describing token: its position, name
5323
+ * and original token itself. Should return a replacement
5324
+ * string that will appear in final output
5325
+ *
5326
+ * @returns {Object} Object with processed <code>text</code> property
5327
+ * and array of <code>tabstops</code> found
5328
+ * @memberOf tabStops
5329
+ */
5330
+ extract: function(text, options) {
5331
+ // prepare defaults
5332
+ var placeholders = {carets: ''};
5333
+ var marks = [];
5334
+
5335
+ options = utils.extend({}, defaultOptions, options, {
5336
+ tabstop: function(data) {
5337
+ var token = data.token;
5338
+ var ret = '';
5339
+ if (data.placeholder == 'cursor') {
5340
+ marks.push({
5341
+ start: data.start,
5342
+ end: data.start + token.length,
5343
+ group: 'carets',
5344
+ value: ''
5345
+ });
5346
+ } else {
5347
+ // unify placeholder value for single group
5348
+ if ('placeholder' in data)
5349
+ placeholders[data.group] = data.placeholder;
5350
+
5351
+ if (data.group in placeholders)
5352
+ ret = placeholders[data.group];
5353
+
5354
+ marks.push({
5355
+ start: data.start,
5356
+ end: data.start + token.length,
5357
+ group: data.group,
5358
+ value: ret
5359
+ });
5360
+ }
5361
+
5362
+ return token;
5363
+ }
5364
+ });
5365
+
5366
+ if (options.replaceCarets) {
5367
+ text = text.replace(new RegExp( utils.escapeForRegexp( utils.getCaretPlaceholder() ), 'g'), '${0:cursor}');
5368
+ }
5369
+
5370
+ // locate tabstops and unify group's placeholders
5371
+ text = this.processText(text, options);
5372
+
5373
+ // now, replace all tabstops with placeholders
5374
+ var buf = '', lastIx = 0;
5375
+ var tabStops = marks.map(function(mark) {
5376
+ buf += text.substring(lastIx, mark.start);
5377
+
5378
+ var pos = buf.length;
5379
+ var ph = placeholders[mark.group] || '';
5380
+
5381
+ buf += ph;
5382
+ lastIx = mark.end;
5383
+
5384
+ return {
5385
+ group: mark.group,
5386
+ start: pos,
5387
+ end: pos + ph.length
5388
+ };
5389
+ });
5390
+
5391
+ buf += text.substring(lastIx);
5392
+
5393
+ return {
5394
+ text: buf,
5395
+ tabstops: tabStops.sort(function(a, b) {
5396
+ return a.start - b.start;
5397
+ })
5398
+ };
5399
+ },
5400
+
5401
+ /**
5402
+ * Text processing routine. Locates escaped characters and tabstops and
5403
+ * replaces them with values returned by handlers defined in
5404
+ * <code>options</code>
5405
+ * @param {String} text
5406
+ * @param {Object} options See <code>extract</code> method options
5407
+ * description
5408
+ * @returns {String}
5409
+ */
5410
+ processText: function(text, options) {
5411
+ options = utils.extend({}, defaultOptions, options);
5412
+
5413
+ var buf = '';
5414
+ /** @type StringStream */
5415
+ var stream = stringStream.create(text);
5416
+ var ch, m, a;
5417
+
5418
+ while ((ch = stream.next())) {
5419
+ if (ch == '\\' && !stream.eol()) {
5420
+ // handle escaped character
5421
+ buf += options.escape(stream.next());
5422
+ continue;
5423
+ }
5424
+
5425
+ a = ch;
5426
+
5427
+ if (ch == '$') {
5428
+ // looks like a tabstop
5429
+ stream.start = stream.pos - 1;
5430
+
5431
+ if ((m = stream.match(/^[0-9]+/))) {
5432
+ // it's $N
5433
+ a = options.tabstop({
5434
+ start: buf.length,
5435
+ group: stream.current().substr(1),
5436
+ token: stream.current()
5437
+ });
5438
+ } else if ((m = stream.match(/^\{([a-z_\-][\w\-]*)\}/))) {
5439
+ // ${variable}
5440
+ a = options.variable({
5441
+ start: buf.length,
5442
+ name: m[1],
5443
+ token: stream.current()
5444
+ });
5445
+ } else if ((m = stream.match(/^\{([0-9]+)(:.+?)?\}/, false))) {
5446
+ // ${N:value} or ${N} placeholder
5447
+ // parse placeholder, including nested ones
5448
+ stream.skipToPair('{', '}');
5449
+
5450
+ var obj = {
5451
+ start: buf.length,
5452
+ group: m[1],
5453
+ token: stream.current()
5454
+ };
5455
+
5456
+ var placeholder = obj.token.substring(obj.group.length + 2, obj.token.length - 1);
5457
+
5458
+ if (placeholder) {
5459
+ obj.placeholder = placeholder.substr(1);
5460
+ }
5461
+
5462
+ a = options.tabstop(obj);
5463
+ }
5464
+ }
5465
+
5466
+ buf += a;
5467
+ }
5468
+
5469
+ return buf;
5470
+ },
5471
+
5472
+ /**
5473
+ * Upgrades tabstops in output node in order to prevent naming conflicts
5474
+ * @param {AbbreviationNode} node
5475
+ * @param {Number} offset Tab index offset
5476
+ * @returns {Number} Maximum tabstop index in element
5477
+ */
5478
+ upgrade: function(node, offset) {
5479
+ var maxNum = 0;
5480
+ var options = {
5481
+ tabstop: function(data) {
5482
+ var group = parseInt(data.group, 10);
5483
+ if (group > maxNum) maxNum = group;
5484
+
5485
+ if (data.placeholder)
5486
+ return '${' + (group + offset) + ':' + data.placeholder + '}';
5487
+ else
5488
+ return '${' + (group + offset) + '}';
5489
+ }
5490
+ };
5491
+
5492
+ ['start', 'end', 'content'].forEach(function(p) {
5493
+ node[p] = this.processText(node[p], options);
5494
+ }, this);
5495
+
5496
+ return maxNum;
5497
+ },
5498
+
5499
+ /**
5500
+ * Helper function that produces a callback function for
5501
+ * <code>replaceVariables()</code> method from {@link utils}
5502
+ * module. This callback will replace variable definitions (like
5503
+ * ${var_name}) with their value defined in <i>resource</i> module,
5504
+ * or outputs tabstop with variable name otherwise.
5505
+ * @param {AbbreviationNode} node Context node
5506
+ * @returns {Function}
5507
+ */
5508
+ variablesResolver: function(node) {
5509
+ var placeholderMemo = {};
5510
+ return function(str, varName) {
5511
+ // do not mark `child` variable as placeholder – it‘s a reserved
5512
+ // variable name
5513
+ if (varName == 'child') {
5514
+ return str;
5515
+ }
5516
+
5517
+ if (varName == 'cursor') {
5518
+ return utils.getCaretPlaceholder();
5519
+ }
5520
+
5521
+ var attr = node.attribute(varName);
5522
+ if (typeof attr !== 'undefined' && attr !== str) {
5523
+ return attr;
5524
+ }
5525
+
5526
+ var varValue = resources.getVariable(varName);
5527
+ if (varValue) {
5528
+ return varValue;
5529
+ }
5530
+
5531
+ // output as placeholder
5532
+ if (!placeholderMemo[varName]) {
5533
+ placeholderMemo[varName] = startPlaceholderNum++;
5534
+ }
5535
+
5536
+ return '${' + placeholderMemo[varName] + ':' + varName + '}';
5537
+ };
5538
+ },
5539
+
5540
+ /**
5541
+ * Replace variables like ${var} in string
5542
+ * @param {String} str
5543
+ * @param {Object} vars Variable set (defaults to variables defined in
5544
+ * <code>snippets.json</code>) or variable resolver (<code>Function</code>)
5545
+ * @return {String}
5546
+ */
5547
+ replaceVariables: function(str, vars) {
5548
+ vars = vars || {};
5549
+ var resolver = typeof vars === 'function' ? vars : function(str, p1) {
5550
+ return p1 in vars ? vars[p1] : null;
5551
+ };
5552
+
5553
+ return this.processText(str, {
5554
+ variable: function(data) {
5555
+ var newValue = resolver(data.token, data.name, data);
5556
+ if (newValue === null) {
5557
+ // try to find variable in resources
5558
+ newValue = resources.getVariable(data.name);
5559
+ }
5560
+
5561
+ if (newValue === null || typeof newValue === 'undefined')
5562
+ // nothing found, return token itself
5563
+ newValue = data.token;
5564
+ return newValue;
5565
+ }
5566
+ });
5567
+ },
5568
+
5569
+ /**
5570
+ * Resets global tabstop index. When parsed tree is converted to output
5571
+ * string (<code>AbbreviationNode.toString()</code>), all tabstops
5572
+ * defined in snippets and elements are upgraded in order to prevent
5573
+ * naming conflicts of nested. For example, <code>${1}</code> of a node
5574
+ * should not be linked with the same placehilder of the child node.
5575
+ * By default, <code>AbbreviationNode.toString()</code> automatically
5576
+ * upgrades tabstops of the same index for each node and writes maximum
5577
+ * tabstop index into the <code>tabstopIndex</code> variable. To keep
5578
+ * this variable at reasonable value, it is recommended to call
5579
+ * <code>resetTabstopIndex()</code> method each time you expand variable
5580
+ * @returns
5581
+ */
5582
+ resetTabstopIndex: function() {
5583
+ tabstopIndex = 0;
5584
+ startPlaceholderNum = 100;
5585
+ },
5586
+
5587
+ /**
5588
+ * Output processor for abbreviation parser that will upgrade tabstops
5589
+ * of parsed node in order to prevent tabstop index conflicts
5590
+ */
5591
+ abbrOutputProcessor: function(text, node, type) {
5592
+ var maxNum = 0;
5593
+ var that = this;
5594
+
5595
+ var tsOptions = {
5596
+ tabstop: function(data) {
5597
+ var group = parseInt(data.group, 10);
5598
+ if (group === 0)
5599
+ return '${0}';
5600
+
5601
+ if (group > maxNum) maxNum = group;
5602
+ if (data.placeholder) {
5603
+ // respect nested placeholders
5604
+ var ix = group + tabstopIndex;
5605
+ var placeholder = that.processText(data.placeholder, tsOptions);
5606
+ return '${' + ix + ':' + placeholder + '}';
5607
+ } else {
5608
+ return '${' + (group + tabstopIndex) + '}';
5609
+ }
5610
+ }
5611
+ };
5612
+
5613
+ // upgrade tabstops
5614
+ text = this.processText(text, tsOptions);
5615
+
5616
+ // resolve variables
5617
+ text = this.replaceVariables(text, this.variablesResolver(node));
5618
+
5619
+ tabstopIndex += maxNum + 1;
5620
+ return text;
5621
+ }
5622
+ };
5623
+ });
5624
+ },{"../utils/common":73,"./resources":31,"./stringStream":32}],34:[function(require,module,exports){
5625
+ /**
5626
+ * Helper class for convenient token iteration
5627
+ */
5628
+ if (typeof module === 'object' && typeof define !== 'function') {
5629
+ var define = function (factory) {
5630
+ module.exports = factory(require, exports, module);
5631
+ };
5632
+ }
5633
+
5634
+ define(function(require, exports, module) {
5635
+ /**
5636
+ * @type TokenIterator
5637
+ * @param {Array} tokens
5638
+ * @type TokenIterator
5639
+ * @constructor
5640
+ */
5641
+ function TokenIterator(tokens) {
5642
+ /** @type Array */
5643
+ this.tokens = tokens;
5644
+ this._position = 0;
5645
+ this.reset();
5646
+ }
5647
+
5648
+ TokenIterator.prototype = {
5649
+ next: function() {
5650
+ if (this.hasNext()) {
5651
+ var token = this.tokens[++this._i];
5652
+ this._position = token.start;
5653
+ return token;
5654
+ } else {
5655
+ this._i = this._il;
5656
+ }
5657
+
5658
+ return null;
5659
+ },
5660
+
5661
+ current: function() {
5662
+ return this.tokens[this._i];
5663
+ },
5664
+
5665
+ peek: function() {
5666
+ return this.tokens[this._i + i];
5667
+ },
5668
+
5669
+ position: function() {
5670
+ return this._position;
5671
+ },
5672
+
5673
+ hasNext: function() {
5674
+ return this._i < this._il - 1;
5675
+ },
5676
+
5677
+ reset: function() {
5678
+ this._i = 0;
5679
+ this._il = this.tokens.length;
5680
+ },
5681
+
5682
+ item: function() {
5683
+ return this.tokens[this._i];
5684
+ },
5685
+
5686
+ itemNext: function() {
5687
+ return this.tokens[this._i + 1];
5688
+ },
5689
+
5690
+ itemPrev: function() {
5691
+ return this.tokens[this._i - 1];
5692
+ },
5693
+
5694
+ nextUntil: function(type, callback) {
5695
+ var token;
5696
+ var test = typeof type == 'string'
5697
+ ? function(t){return t.type == type;}
5698
+ : type;
5699
+
5700
+ while ((token = this.next())) {
5701
+ if (callback)
5702
+ callback.call(this, token);
5703
+ if (test.call(this, token))
5704
+ break;
5705
+ }
5706
+ }
5707
+ };
5708
+
5709
+ return {
5710
+ create: function(tokens) {
5711
+ return new TokenIterator(tokens);
5712
+ }
5713
+ };
5714
+ });
5715
+ },{}],35:[function(require,module,exports){
5716
+ module.exports={
5717
+ "eras": {
5718
+ "e-26": "26 versions back",
5719
+ "e-25": "25 versions back",
5720
+ "e-24": "24 versions back",
5721
+ "e-23": "23 versions back",
5722
+ "e-22": "22 versions back",
5723
+ "e-21": "21 versions back",
5724
+ "e-20": "20 versions back",
5725
+ "e-19": "19 versions back",
5726
+ "e-18": "18 versions back",
5727
+ "e-17": "17 versions back",
5728
+ "e-16": "16 versions back",
5729
+ "e-15": "15 versions back",
5730
+ "e-14": "14 versions back",
5731
+ "e-13": "13 versions back",
5732
+ "e-12": "12 versions back",
5733
+ "e-11": "11 versions back",
5734
+ "e-10": "10 versions back",
5735
+ "e-9": "9 versions back",
5736
+ "e-8": "8 versions back",
5737
+ "e-7": "7 versions back",
5738
+ "e-6": "6 versions back",
5739
+ "e-5": "5 versions back",
5740
+ "e-4": "4 versions back",
5741
+ "e-3": "3 versions back",
5742
+ "e-2": "2 versions back",
5743
+ "e-1": "Previous version",
5744
+ "e0": "Current",
5745
+ "e1": "Near future",
5746
+ "e2": "Farther future"
5747
+ },
5748
+ "agents": {
5749
+ "ie": {
5750
+ "browser": "IE",
5751
+ "abbr": "IE",
5752
+ "prefix": "ms",
5753
+ "type": "desktop",
5754
+ "usage_global": {
5755
+ "10": 10.7866,
5756
+ "11": 0.114751,
5757
+ "5.5": 0.009298,
5758
+ "6": 0.204912,
5759
+ "7": 0.508182,
5760
+ "8": 8.31124,
5761
+ "9": 5.21297
5762
+ },
5763
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "5.5", "6", "7", "8", "9", "10", "11", null, null],
5764
+ "current_version": ""
5765
+ },
5766
+ "firefox": {
5767
+ "browser": "Firefox",
5768
+ "abbr": "FF",
5769
+ "prefix": "moz",
5770
+ "type": "desktop",
5771
+ "usage_global": {
5772
+ "10": 0.112406,
5773
+ "11": 0.088319,
5774
+ "12": 0.208754,
5775
+ "13": 0.096348,
5776
+ "14": 0.096348,
5777
+ "15": 0.136493,
5778
+ "16": 0.264957,
5779
+ "17": 0.192696,
5780
+ "18": 0.112406,
5781
+ "19": 0.128464,
5782
+ "2": 0.016058,
5783
+ "20": 0.16058,
5784
+ "21": 0.216783,
5785
+ "22": 0.256928,
5786
+ "23": 0.907277,
5787
+ "24": 11.0318,
5788
+ "25": 0.529914,
5789
+ "26": 0.016058,
5790
+ "27": 0.016058,
5791
+ "3": 0.088319,
5792
+ "3.5": 0.040145,
5793
+ "3.6": 0.305102,
5794
+ "4": 0.072261,
5795
+ "5": 0.048174,
5796
+ "6": 0.048174,
5797
+ "7": 0.040145,
5798
+ "8": 0.072261,
5799
+ "9": 0.056203
5800
+ },
5801
+ "versions": [null, "2", "3", "3.5", "3.6", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27"],
5802
+ "current_version": ""
5803
+ },
5804
+ "chrome": {
5805
+ "browser": "Chrome",
5806
+ "abbr": "Chr.",
5807
+ "prefix": "webkit",
5808
+ "type": "desktop",
5809
+ "usage_global": {
5810
+ "10": 0.048174,
5811
+ "11": 0.112406,
5812
+ "12": 0.064232,
5813
+ "13": 0.056203,
5814
+ "14": 0.056203,
5815
+ "15": 0.072261,
5816
+ "16": 0.048174,
5817
+ "17": 0.040145,
5818
+ "18": 0.08029,
5819
+ "19": 0.040145,
5820
+ "20": 0.040145,
5821
+ "21": 0.48174,
5822
+ "22": 0.248899,
5823
+ "23": 0.216783,
5824
+ "24": 0.200725,
5825
+ "25": 0.361305,
5826
+ "26": 0.353276,
5827
+ "27": 0.369334,
5828
+ "28": 0.610204,
5829
+ "29": 5.08236,
5830
+ "30": 24.6089,
5831
+ "31": 0.16058,
5832
+ "32": 0.064232,
5833
+ "4": 0.024087,
5834
+ "5": 0.024087,
5835
+ "6": 0.032116,
5836
+ "7": 0.024087,
5837
+ "8": 0.032116,
5838
+ "9": 0.024087
5839
+ },
5840
+ "versions": ["4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32"],
5841
+ "current_version": ""
5842
+ },
5843
+ "safari": {
5844
+ "browser": "Safari",
5845
+ "abbr": "Saf.",
5846
+ "prefix": "webkit",
5847
+ "type": "desktop",
5848
+ "usage_global": {
5849
+ "3.1": 0,
5850
+ "3.2": 0.008692,
5851
+ "4": 0.104377,
5852
+ "5": 0.305102,
5853
+ "5.1": 1.28464,
5854
+ "6": 2.04739,
5855
+ "6.1": 0.064232,
5856
+ "7": 0.16058
5857
+ },
5858
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "3.1", "3.2", "4", "5", "5.1", "6", "6.1", "7", null, null],
5859
+ "current_version": ""
5860
+ },
5861
+ "opera": {
5862
+ "browser": "Opera",
5863
+ "abbr": "Op.",
5864
+ "prefix": "o",
5865
+ "type": "desktop",
5866
+ "usage_global": {
5867
+ "10.0-10.1": 0.016058,
5868
+ "10.5": 0.008392,
5869
+ "10.6": 0.008029,
5870
+ "11": 0.008219,
5871
+ "11.1": 0.008219,
5872
+ "11.5": 0.016058,
5873
+ "11.6": 0.032116,
5874
+ "12": 0.040145,
5875
+ "12.1": 0.48174,
5876
+ "15": 0.032116,
5877
+ "16": 0.104377,
5878
+ "17": 0.16058,
5879
+ "18": 0,
5880
+ "9.5-9.6": 0.008219
5881
+ },
5882
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, "9.5-9.6", "10.0-10.1", "10.5", "10.6", "11", "11.1", "11.5", "11.6", "12", "12.1", "15", "16", "17", "18", null],
5883
+ "current_version": "",
5884
+ "prefix_exceptions": {
5885
+ "15": "webkit",
5886
+ "16": "webkit",
5887
+ "17": "webkit",
5888
+ "18": "webkit"
5889
+ }
5890
+ },
5891
+ "ios_saf": {
5892
+ "browser": "iOS Safari",
5893
+ "abbr": "iOS",
5894
+ "prefix": "webkit",
5895
+ "type": "mobile",
5896
+ "usage_global": {
5897
+ "3.2": 0.00400113,
5898
+ "4.0-4.1": 0.00800226,
5899
+ "4.2-4.3": 0.0280079,
5900
+ "5.0-5.1": 0.28408,
5901
+ "6.0-6.1": 1.15633,
5902
+ "7.0": 2.52071
5903
+ },
5904
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "3.2", "4.0-4.1", "4.2-4.3", "5.0-5.1", "6.0-6.1", "7.0", null, null],
5905
+ "current_version": ""
5906
+ },
5907
+ "op_mini": {
5908
+ "browser": "Opera Mini",
5909
+ "abbr": "O.Mini",
5910
+ "prefix": "o",
5911
+ "type": "mobile",
5912
+ "usage_global": {
5913
+ "5.0-7.0": 4.58374
5914
+ },
5915
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "5.0-7.0", null, null],
5916
+ "current_version": ""
5917
+ },
5918
+ "android": {
5919
+ "browser": "Android Browser",
5920
+ "abbr": "And.",
5921
+ "prefix": "webkit",
5922
+ "type": "mobile",
5923
+ "usage_global": {
5924
+ "2.1": 0.0251229,
5925
+ "2.2": 0.0854178,
5926
+ "2.3": 1.32146,
5927
+ "3": 0.00502458,
5928
+ "4": 0.994867,
5929
+ "4.1": 1.87417,
5930
+ "4.2-4.3": 0.743638,
5931
+ "4.4": 0
5932
+ },
5933
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "2.1", "2.2", "2.3", "3", "4", "4.1", "4.2-4.3", "4.4", null],
5934
+ "current_version": ""
5935
+ },
5936
+ "op_mob": {
5937
+ "browser": "Opera Mobile",
5938
+ "abbr": "O.Mob",
5939
+ "prefix": "o",
5940
+ "type": "mobile",
5941
+ "usage_global": {
5942
+ "0": 0,
5943
+ "10": 0,
5944
+ "11.5": 0.00726525,
5945
+ "12": 0.0363263,
5946
+ "12.1": 0.101714
5947
+ },
5948
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "10", null, null, "11.5", "12", "12.1", "0", null, null],
5949
+ "current_version": "16",
5950
+ "prefix_exceptions": {
5951
+ "0": "webkit"
5952
+ }
5953
+ },
5954
+ "bb": {
5955
+ "browser": "Blackberry Browser",
5956
+ "abbr": "BB",
5957
+ "prefix": "webkit",
5958
+ "type": "mobile",
5959
+ "usage_global": {
5960
+ "10": 0,
5961
+ "7": 0.141419
5962
+ },
5963
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "7", "10", null, null],
5964
+ "current_version": ""
5965
+ },
5966
+ "and_chr": {
5967
+ "browser": "Chrome for Android",
5968
+ "abbr": "Chr/And.",
5969
+ "prefix": "webkit",
5970
+ "type": "mobile",
5971
+ "usage_global": {
5972
+ "0": 1.38176
5973
+ },
5974
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "0", null, null],
5975
+ "current_version": "30"
5976
+ },
5977
+ "and_ff": {
5978
+ "browser": "Firefox for Android",
5979
+ "abbr": "FF/And.",
5980
+ "prefix": "moz",
5981
+ "type": "mobile",
5982
+ "usage_global": {
5983
+ "0": 0.070956
5984
+ },
5985
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "0", null, null],
5986
+ "current_version": "25"
5987
+ },
5988
+ "ie_mob": {
5989
+ "browser": "IE Mobile",
5990
+ "abbr": "IE.Mob",
5991
+ "prefix": "ms",
5992
+ "type": "mobile",
5993
+ "usage_global": {
5994
+ "10": 0.205595
5995
+ },
5996
+ "versions": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "10", null, null],
5997
+ "current_version": ""
5998
+ }
5999
+ },
6000
+ "statuses": {
6001
+ "rec": "Recommendation",
6002
+ "pr": "Proposed Recommendation",
6003
+ "cr": "Candidate Recommendation",
6004
+ "wd": "Working Draft",
6005
+ "other": "Other",
6006
+ "unoff": "Unofficial / Note"
6007
+ },
6008
+ "cats": {
6009
+ "CSS": ["CSS", "CSS2", "CSS3"],
6010
+ "HTML5": ["Canvas", "HTML5"],
6011
+ "JS API": ["JS API"],
6012
+ "Other": ["PNG", "Other", "DOM"],
6013
+ "SVG": ["SVG"]
6014
+ },
6015
+ "updated": 1383587152,
6016
+ "data": {
6017
+ "png-alpha": {
6018
+ "title": "PNG alpha transparency",
6019
+ "description": "Semi-transparent areas in PNG files",
6020
+ "spec": "http://www.w3.org/TR/PNG/",
6021
+ "status": "rec",
6022
+ "links": [{
6023
+ "url": "http://dillerdesign.com/experiment/DD_belatedPNG/",
6024
+ "title": "Workaround for IE6"
6025
+ }, {
6026
+ "url": "http://en.wikipedia.org/wiki/Portable_Network_Graphics",
6027
+ "title": "Wikipedia"
6028
+ }],
6029
+ "categories": ["PNG"],
6030
+ "stats": {
6031
+ "ie": {
6032
+ "5.5": "n",
6033
+ "6": "p",
6034
+ "7": "y",
6035
+ "8": "y",
6036
+ "9": "y",
6037
+ "10": "y",
6038
+ "11": "y"
6039
+ },
6040
+ "firefox": {
6041
+ "2": "y",
6042
+ "3": "y",
6043
+ "3.5": "y",
6044
+ "3.6": "y",
6045
+ "4": "y",
6046
+ "5": "y",
6047
+ "6": "y",
6048
+ "7": "y",
6049
+ "8": "y",
6050
+ "9": "y",
6051
+ "10": "y",
6052
+ "11": "y",
6053
+ "12": "y",
6054
+ "13": "y",
6055
+ "14": "y",
6056
+ "15": "y",
6057
+ "16": "y",
6058
+ "17": "y",
6059
+ "18": "y",
6060
+ "19": "y",
6061
+ "20": "y",
6062
+ "21": "y",
6063
+ "22": "y",
6064
+ "23": "y",
6065
+ "24": "y",
6066
+ "25": "y",
6067
+ "26": "y",
6068
+ "27": "y"
6069
+ },
6070
+ "chrome": {
6071
+ "4": "y",
6072
+ "5": "y",
6073
+ "6": "y",
6074
+ "7": "y",
6075
+ "8": "y",
6076
+ "9": "y",
6077
+ "10": "y",
6078
+ "11": "y",
6079
+ "12": "y",
6080
+ "13": "y",
6081
+ "14": "y",
6082
+ "15": "y",
6083
+ "16": "y",
6084
+ "17": "y",
6085
+ "18": "y",
6086
+ "19": "y",
6087
+ "20": "y",
6088
+ "21": "y",
6089
+ "22": "y",
6090
+ "23": "y",
6091
+ "24": "y",
6092
+ "25": "y",
6093
+ "26": "y",
6094
+ "27": "y",
6095
+ "28": "y",
6096
+ "29": "y",
6097
+ "30": "y",
6098
+ "31": "y",
6099
+ "32": "y"
6100
+ },
6101
+ "safari": {
6102
+ "3.1": "y",
6103
+ "3.2": "y",
6104
+ "4": "y",
6105
+ "5": "y",
6106
+ "5.1": "y",
6107
+ "6": "y",
6108
+ "6.1": "y",
6109
+ "7": "y"
6110
+ },
6111
+ "opera": {
6112
+ "9": "y",
6113
+ "9.5-9.6": "y",
6114
+ "10.0-10.1": "y",
6115
+ "10.5": "y",
6116
+ "10.6": "y",
6117
+ "11": "y",
6118
+ "11.1": "y",
6119
+ "11.5": "y",
6120
+ "11.6": "y",
6121
+ "12": "y",
6122
+ "12.1": "y",
6123
+ "15": "y",
6124
+ "16": "y",
6125
+ "17": "y",
6126
+ "18": "y"
6127
+ },
6128
+ "ios_saf": {
6129
+ "3.2": "y",
6130
+ "4.0-4.1": "y",
6131
+ "4.2-4.3": "y",
6132
+ "5.0-5.1": "y",
6133
+ "6.0-6.1": "y",
6134
+ "7.0": "y"
6135
+ },
6136
+ "op_mini": {
6137
+ "5.0-7.0": "y"
6138
+ },
6139
+ "android": {
6140
+ "2.1": "y",
6141
+ "2.2": "y",
6142
+ "2.3": "y",
6143
+ "3": "y",
6144
+ "4": "y",
6145
+ "4.1": "y",
6146
+ "4.2-4.3": "y",
6147
+ "4.4": "y"
6148
+ },
6149
+ "bb": {
6150
+ "7": "y",
6151
+ "10": "y"
6152
+ },
6153
+ "op_mob": {
6154
+ "10": "y",
6155
+ "11": "y",
6156
+ "11.1": "y",
6157
+ "11.5": "y",
6158
+ "12": "y",
6159
+ "12.1": "y",
6160
+ "0": "y"
6161
+ },
6162
+ "and_chr": {
6163
+ "0": "y"
6164
+ },
6165
+ "and_ff": {
6166
+ "0": "y"
6167
+ },
6168
+ "ie_mob": {
6169
+ "10": "y"
6170
+ }
6171
+ },
6172
+ "notes": "IE6 does support full transparency in 8-bit PNGs, which can sometimes be an alternative to 24-bit PNGs.",
6173
+ "usage_perc_y": 94.36,
6174
+ "usage_perc_a": 0,
6175
+ "ucprefix": false,
6176
+ "parent": "",
6177
+ "keywords": ""
6178
+ },
6179
+ "apng": {
6180
+ "title": "Animated PNG (APNG)",
6181
+ "description": "Like animated GIFs, but allowing 24-bit colors and alpha transparency",
6182
+ "spec": "https://wiki.mozilla.org/APNG_Specification",
6183
+ "status": "unoff",
6184
+ "links": [{
6185
+ "url": "http://en.wikipedia.org/wiki/APNG",
6186
+ "title": "Wikipedia"
6187
+ }, {
6188
+ "url": "https://github.com/davidmz/apng-canvas",
6189
+ "title": "Polyfill using canvas"
6190
+ }, {
6191
+ "url": "https://chrome.google.com/webstore/detail/ehkepjiconegkhpodgoaeamnpckdbblp",
6192
+ "title": "Chrome extension providing support"
6193
+ }, {
6194
+ "url": "http://www.truekolor.net/learn-how-to-create-an-animated-png/",
6195
+ "title": "APNG tutorial"
6196
+ }],
6197
+ "categories": ["PNG"],
6198
+ "stats": {
6199
+ "ie": {
6200
+ "5.5": "n",
6201
+ "6": "n",
6202
+ "7": "n",
6203
+ "8": "n",
6204
+ "9": "n",
6205
+ "10": "n",
6206
+ "11": "n"
6207
+ },
6208
+ "firefox": {
6209
+ "2": "n",
6210
+ "3": "y",
6211
+ "3.5": "y",
6212
+ "3.6": "y",
6213
+ "4": "y",
6214
+ "5": "y",
6215
+ "6": "y",
6216
+ "7": "y",
6217
+ "8": "y",
6218
+ "9": "y",
6219
+ "10": "y",
6220
+ "11": "y",
6221
+ "12": "y",
6222
+ "13": "y",
6223
+ "14": "y",
6224
+ "15": "y",
6225
+ "16": "y",
6226
+ "17": "y",
6227
+ "18": "y",
6228
+ "19": "y",
6229
+ "20": "y",
6230
+ "21": "y",
6231
+ "22": "y",
6232
+ "23": "y",
6233
+ "24": "y",
6234
+ "25": "y",
6235
+ "26": "y",
6236
+ "27": "y"
6237
+ },
6238
+ "chrome": {
6239
+ "4": "n",
6240
+ "5": "n",
6241
+ "6": "n",
6242
+ "7": "n",
6243
+ "8": "n",
6244
+ "9": "n",
6245
+ "10": "n",
6246
+ "11": "n",
6247
+ "12": "n",
6248
+ "13": "n",
6249
+ "14": "n",
6250
+ "15": "n",
6251
+ "16": "n",
6252
+ "17": "n",
6253
+ "18": "n",
6254
+ "19": "n",
6255
+ "20": "n",
6256
+ "21": "n",
6257
+ "22": "n",
6258
+ "23": "n",
6259
+ "24": "n",
6260
+ "25": "n",
6261
+ "26": "n",
6262
+ "27": "n",
6263
+ "28": "n",
6264
+ "29": "n",
6265
+ "30": "n",
6266
+ "31": "n",
6267
+ "32": "n"
6268
+ },
6269
+ "safari": {
6270
+ "3.1": "n",
6271
+ "3.2": "n",
6272
+ "4": "n",
6273
+ "5": "n",
6274
+ "5.1": "n",
6275
+ "6": "n",
6276
+ "6.1": "n",
6277
+ "7": "n"
6278
+ },
6279
+ "opera": {
6280
+ "9": "n",
6281
+ "9.5-9.6": "y",
6282
+ "10.0-10.1": "y",
6283
+ "10.5": "y",
6284
+ "10.6": "y",
6285
+ "11": "y",
6286
+ "11.1": "y",
6287
+ "11.5": "y",
6288
+ "11.6": "y",
6289
+ "12": "y",
6290
+ "12.1": "y",
6291
+ "15": "n",
6292
+ "16": "n",
6293
+ "17": "n",
6294
+ "18": "n"
6295
+ },
6296
+ "ios_saf": {
6297
+ "3.2": "n",
6298
+ "4.0-4.1": "n",
6299
+ "4.2-4.3": "n",
6300
+ "5.0-5.1": "n",
6301
+ "6.0-6.1": "n",
6302
+ "7.0": "n"
6303
+ },
6304
+ "op_mini": {
6305
+ "5.0-7.0": "n"
6306
+ },
6307
+ "android": {
6308
+ "2.1": "n",
6309
+ "2.2": "n",
6310
+ "2.3": "n",
6311
+ "3": "n",
6312
+ "4": "n",
6313
+ "4.1": "n",
6314
+ "4.2-4.3": "n",
6315
+ "4.4": "n"
6316
+ },
6317
+ "bb": {
6318
+ "7": "n",
6319
+ "10": "n"
6320
+ },
6321
+ "op_mob": {
6322
+ "10": "y",
6323
+ "11": "y",
6324
+ "11.1": "y",
6325
+ "11.5": "y",
6326
+ "12": "y",
6327
+ "12.1": "y",
6328
+ "0": "n"
6329
+ },
6330
+ "and_chr": {
6331
+ "0": "n"
6332
+ },
6333
+ "and_ff": {
6334
+ "0": "y"
6335
+ },
6336
+ "ie_mob": {
6337
+ "10": "n"
6338
+ }
6339
+ },
6340
+ "notes": "Where support for APNG is missing, only the first frame is displayed",
6341
+ "usage_perc_y": 16.19,
6342
+ "usage_perc_a": 0,
6343
+ "ucprefix": false,
6344
+ "parent": "",
6345
+ "keywords": ""
6346
+ },
6347
+ "video": {
6348
+ "title": "Video element",
6349
+ "description": "Method of playing videos on webpages (without requiring a plug-in)",
6350
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#video",
6351
+ "status": "wd",
6352
+ "links": [{
6353
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/video.js#video",
6354
+ "title": "has.js test"
6355
+ }, {
6356
+ "url": "http://webmproject.org",
6357
+ "title": "WebM format information"
6358
+ }, {
6359
+ "url": "http://docs.webplatform.org/wiki/html/elements/video",
6360
+ "title": "WebPlatform Docs"
6361
+ }, {
6362
+ "url": "http://camendesign.co.uk/code/video_for_everybody",
6363
+ "title": "Video for Everybody"
6364
+ }, {
6365
+ "url": "http://diveinto.org/html5/video.html",
6366
+ "title": "Video on the Web - includes info on Android support"
6367
+ }, {
6368
+ "url": "http://dev.opera.com/articles/view/everything-you-need-to-know-about-html5-video-and-audio/",
6369
+ "title": "Detailed article on video/audio elements"
6370
+ }],
6371
+ "categories": ["HTML5"],
6372
+ "stats": {
6373
+ "ie": {
6374
+ "5.5": "n",
6375
+ "6": "n",
6376
+ "7": "n",
6377
+ "8": "n",
6378
+ "9": "y",
6379
+ "10": "y",
6380
+ "11": "y"
6381
+ },
6382
+ "firefox": {
6383
+ "2": "n",
6384
+ "3": "n",
6385
+ "3.5": "y",
6386
+ "3.6": "y",
6387
+ "4": "y",
6388
+ "5": "y",
6389
+ "6": "y",
6390
+ "7": "y",
6391
+ "8": "y",
6392
+ "9": "y",
6393
+ "10": "y",
6394
+ "11": "y",
6395
+ "12": "y",
6396
+ "13": "y",
6397
+ "14": "y",
6398
+ "15": "y",
6399
+ "16": "y",
6400
+ "17": "y",
6401
+ "18": "y",
6402
+ "19": "y",
6403
+ "20": "y",
6404
+ "21": "y",
6405
+ "22": "y",
6406
+ "23": "y",
6407
+ "24": "y",
6408
+ "25": "y",
6409
+ "26": "y",
6410
+ "27": "y"
6411
+ },
6412
+ "chrome": {
6413
+ "4": "y",
6414
+ "5": "y",
6415
+ "6": "y",
6416
+ "7": "y",
6417
+ "8": "y",
6418
+ "9": "y",
6419
+ "10": "y",
6420
+ "11": "y",
6421
+ "12": "y",
6422
+ "13": "y",
6423
+ "14": "y",
6424
+ "15": "y",
6425
+ "16": "y",
6426
+ "17": "y",
6427
+ "18": "y",
6428
+ "19": "y",
6429
+ "20": "y",
6430
+ "21": "y",
6431
+ "22": "y",
6432
+ "23": "y",
6433
+ "24": "y",
6434
+ "25": "y",
6435
+ "26": "y",
6436
+ "27": "y",
6437
+ "28": "y",
6438
+ "29": "y",
6439
+ "30": "y",
6440
+ "31": "y",
6441
+ "32": "y"
6442
+ },
6443
+ "safari": {
6444
+ "3.1": "n",
6445
+ "3.2": "n",
6446
+ "4": "y",
6447
+ "5": "y",
6448
+ "5.1": "y",
6449
+ "6": "y",
6450
+ "6.1": "y",
6451
+ "7": "y"
6452
+ },
6453
+ "opera": {
6454
+ "9": "n",
6455
+ "9.5-9.6": "n",
6456
+ "10.0-10.1": "n",
6457
+ "10.5": "y",
6458
+ "10.6": "y",
6459
+ "11": "y",
6460
+ "11.1": "y",
6461
+ "11.5": "y",
6462
+ "11.6": "y",
6463
+ "12": "y",
6464
+ "12.1": "y",
6465
+ "15": "y",
6466
+ "16": "y",
6467
+ "17": "y",
6468
+ "18": "y"
6469
+ },
6470
+ "ios_saf": {
6471
+ "3.2": "y",
6472
+ "4.0-4.1": "y",
6473
+ "4.2-4.3": "y",
6474
+ "5.0-5.1": "y",
6475
+ "6.0-6.1": "y",
6476
+ "7.0": "y"
6477
+ },
6478
+ "op_mini": {
6479
+ "5.0-7.0": "n"
6480
+ },
6481
+ "android": {
6482
+ "2.1": "a",
6483
+ "2.2": "a",
6484
+ "2.3": "y",
6485
+ "3": "y",
6486
+ "4": "y",
6487
+ "4.1": "y",
6488
+ "4.2-4.3": "y",
6489
+ "4.4": "y"
6490
+ },
6491
+ "bb": {
6492
+ "7": "y",
6493
+ "10": "y"
6494
+ },
6495
+ "op_mob": {
6496
+ "10": "n",
6497
+ "11": "y",
6498
+ "11.1": "y",
6499
+ "11.5": "y",
6500
+ "12": "y",
6501
+ "12.1": "y",
6502
+ "0": "y"
6503
+ },
6504
+ "and_chr": {
6505
+ "0": "y"
6506
+ },
6507
+ "and_ff": {
6508
+ "0": "y"
6509
+ },
6510
+ "ie_mob": {
6511
+ "10": "y"
6512
+ }
6513
+ },
6514
+ "notes": "Different browsers have support for different video formats, see sub-features for details. \r\n\r\nThe Android browser (before 2.3) requires <a href=\"http://www.broken-links.com/2010/07/08/making-html5-video-work-on-android-phones/\">specific handling</a> to run the video element.",
6515
+ "usage_perc_y": 80.71,
6516
+ "usage_perc_a": 0.11,
6517
+ "ucprefix": false,
6518
+ "parent": "",
6519
+ "keywords": "<video>"
6520
+ },
6521
+ "audio": {
6522
+ "title": "Audio element",
6523
+ "description": "Method of playing sound on webpages (without requiring a plug-in)",
6524
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#audio",
6525
+ "status": "wd",
6526
+ "links": [{
6527
+ "url": "http://html5doctor.com/native-audio-in-the-browser/",
6528
+ "title": "HTML5 Doctor article"
6529
+ }, {
6530
+ "url": "http://textopia.org/androidsoundformats.html",
6531
+ "title": "File format test page"
6532
+ }, {
6533
+ "url": "http://www.jplayer.org/latest/demos/",
6534
+ "title": "Demos of audio player that uses &lt;audio>"
6535
+ }, {
6536
+ "url": "http://www.phoboslab.org/log/2011/03/the-state-of-html5-audio",
6537
+ "title": "The State of HTML5 Audio"
6538
+ }, {
6539
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/audio.js#audio",
6540
+ "title": "has.js test"
6541
+ }, {
6542
+ "url": "http://dev.opera.com/articles/view/everything-you-need-to-know-about-html5-video-and-audio/",
6543
+ "title": "Detailed article on video/audio elements"
6544
+ }, {
6545
+ "url": "http://docs.webplatform.org/wiki/html/elements/audio",
6546
+ "title": "WebPlatform Docs"
6547
+ }, {
6548
+ "url": "http://24ways.org/2010/the-state-of-html5-audio",
6549
+ "title": "Detailed article on support"
6550
+ }],
6551
+ "categories": ["HTML5"],
6552
+ "stats": {
6553
+ "ie": {
6554
+ "5.5": "n",
6555
+ "6": "n",
6556
+ "7": "n",
6557
+ "8": "n",
6558
+ "9": "y",
6559
+ "10": "y",
6560
+ "11": "y"
6561
+ },
6562
+ "firefox": {
6563
+ "2": "n",
6564
+ "3": "n",
6565
+ "3.5": "y",
6566
+ "3.6": "y",
6567
+ "4": "y",
6568
+ "5": "y",
6569
+ "6": "y",
6570
+ "7": "y",
6571
+ "8": "y",
6572
+ "9": "y",
6573
+ "10": "y",
6574
+ "11": "y",
6575
+ "12": "y",
6576
+ "13": "y",
6577
+ "14": "y",
6578
+ "15": "y",
6579
+ "16": "y",
6580
+ "17": "y",
6581
+ "18": "y",
6582
+ "19": "y",
6583
+ "20": "y",
6584
+ "21": "y",
6585
+ "22": "y",
6586
+ "23": "y",
6587
+ "24": "y",
6588
+ "25": "y",
6589
+ "26": "y",
6590
+ "27": "y"
6591
+ },
6592
+ "chrome": {
6593
+ "4": "y",
6594
+ "5": "y",
6595
+ "6": "y",
6596
+ "7": "y",
6597
+ "8": "y",
6598
+ "9": "y",
6599
+ "10": "y",
6600
+ "11": "y",
6601
+ "12": "y",
6602
+ "13": "y",
6603
+ "14": "y",
6604
+ "15": "y",
6605
+ "16": "y",
6606
+ "17": "y",
6607
+ "18": "y",
6608
+ "19": "y",
6609
+ "20": "y",
6610
+ "21": "y",
6611
+ "22": "y",
6612
+ "23": "y",
6613
+ "24": "y",
6614
+ "25": "y",
6615
+ "26": "y",
6616
+ "27": "y",
6617
+ "28": "y",
6618
+ "29": "y",
6619
+ "30": "y",
6620
+ "31": "y",
6621
+ "32": "y"
6622
+ },
6623
+ "safari": {
6624
+ "3.1": "n",
6625
+ "3.2": "n",
6626
+ "4": "y",
6627
+ "5": "y",
6628
+ "5.1": "y",
6629
+ "6": "y",
6630
+ "6.1": "y",
6631
+ "7": "y"
6632
+ },
6633
+ "opera": {
6634
+ "9": "n",
6635
+ "9.5-9.6": "a",
6636
+ "10.0-10.1": "a",
6637
+ "10.5": "y",
6638
+ "10.6": "y",
6639
+ "11": "y",
6640
+ "11.1": "y",
6641
+ "11.5": "y",
6642
+ "11.6": "y",
6643
+ "12": "y",
6644
+ "12.1": "y",
6645
+ "15": "y",
6646
+ "16": "y",
6647
+ "17": "y",
6648
+ "18": "y"
6649
+ },
6650
+ "ios_saf": {
6651
+ "3.2": "n",
6652
+ "4.0-4.1": "y",
6653
+ "4.2-4.3": "y",
6654
+ "5.0-5.1": "y",
6655
+ "6.0-6.1": "y",
6656
+ "7.0": "y"
6657
+ },
6658
+ "op_mini": {
6659
+ "5.0-7.0": "n"
6660
+ },
6661
+ "android": {
6662
+ "2.1": "n",
6663
+ "2.2": "n",
6664
+ "2.3": "y",
6665
+ "3": "y",
6666
+ "4": "y",
6667
+ "4.1": "y",
6668
+ "4.2-4.3": "y",
6669
+ "4.4": "y"
6670
+ },
6671
+ "bb": {
6672
+ "7": "y",
6673
+ "10": "y"
6674
+ },
6675
+ "op_mob": {
6676
+ "10": "n",
6677
+ "11": "y",
6678
+ "11.1": "y",
6679
+ "11.5": "y",
6680
+ "12": "y",
6681
+ "12.1": "y",
6682
+ "0": "y"
6683
+ },
6684
+ "and_chr": {
6685
+ "0": "y"
6686
+ },
6687
+ "and_ff": {
6688
+ "0": "y"
6689
+ },
6690
+ "ie_mob": {
6691
+ "10": "y"
6692
+ }
6693
+ },
6694
+ "notes": "",
6695
+ "usage_perc_y": 80.7,
6696
+ "usage_perc_a": 0.02,
6697
+ "ucprefix": false,
6698
+ "parent": "",
6699
+ "keywords": ""
6700
+ },
6701
+ "contenteditable": {
6702
+ "title": "contenteditable attribute (basic support)",
6703
+ "description": "Method of making any HTML element editable",
6704
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#contenteditable",
6705
+ "status": "wd",
6706
+ "links": [{
6707
+ "url": "http://accessgarage.wordpress.com/2009/05/08/how-to-hack-your-app-to-make-contenteditable-work/",
6708
+ "title": "Blog post on usage problems"
6709
+ }, {
6710
+ "url": "http://html5demos.com/contenteditable",
6711
+ "title": "Demo page"
6712
+ }, {
6713
+ "url": "http://blog.whatwg.org/the-road-to-html-5-contenteditable",
6714
+ "title": "WHATWG blog post"
6715
+ }, {
6716
+ "url": "http://docs.webplatform.org/wiki/html/attributes/contentEditable",
6717
+ "title": "WebPlatform Docs"
6718
+ }],
6719
+ "categories": ["HTML5"],
6720
+ "stats": {
6721
+ "ie": {
6722
+ "5.5": "y",
6723
+ "6": "y",
6724
+ "7": "y",
6725
+ "8": "y",
6726
+ "9": "y",
6727
+ "10": "y",
6728
+ "11": "y"
6729
+ },
6730
+ "firefox": {
6731
+ "2": "n",
6732
+ "3": "a",
6733
+ "3.5": "y",
6734
+ "3.6": "y",
6735
+ "4": "y",
6736
+ "5": "y",
6737
+ "6": "y",
6738
+ "7": "y",
6739
+ "8": "y",
6740
+ "9": "y",
6741
+ "10": "y",
6742
+ "11": "y",
6743
+ "12": "y",
6744
+ "13": "y",
6745
+ "14": "y",
6746
+ "15": "y",
6747
+ "16": "y",
6748
+ "17": "y",
6749
+ "18": "y",
6750
+ "19": "y",
6751
+ "20": "y",
6752
+ "21": "y",
6753
+ "22": "y",
6754
+ "23": "y",
6755
+ "24": "y",
6756
+ "25": "y",
6757
+ "26": "y",
6758
+ "27": "y"
6759
+ },
6760
+ "chrome": {
6761
+ "4": "y",
6762
+ "5": "y",
6763
+ "6": "y",
6764
+ "7": "y",
6765
+ "8": "y",
6766
+ "9": "y",
6767
+ "10": "y",
6768
+ "11": "y",
6769
+ "12": "y",
6770
+ "13": "y",
6771
+ "14": "y",
6772
+ "15": "y",
6773
+ "16": "y",
6774
+ "17": "y",
6775
+ "18": "y",
6776
+ "19": "y",
6777
+ "20": "y",
6778
+ "21": "y",
6779
+ "22": "y",
6780
+ "23": "y",
6781
+ "24": "y",
6782
+ "25": "y",
6783
+ "26": "y",
6784
+ "27": "y",
6785
+ "28": "y",
6786
+ "29": "y",
6787
+ "30": "y",
6788
+ "31": "y",
6789
+ "32": "y"
6790
+ },
6791
+ "safari": {
6792
+ "3.1": "y",
6793
+ "3.2": "y",
6794
+ "4": "y",
6795
+ "5": "y",
6796
+ "5.1": "y",
6797
+ "6": "y",
6798
+ "6.1": "y",
6799
+ "7": "y"
6800
+ },
6801
+ "opera": {
6802
+ "9": "y",
6803
+ "9.5-9.6": "y",
6804
+ "10.0-10.1": "y",
6805
+ "10.5": "y",
6806
+ "10.6": "y",
6807
+ "11": "y",
6808
+ "11.1": "y",
6809
+ "11.5": "y",
6810
+ "11.6": "y",
6811
+ "12": "y",
6812
+ "12.1": "y",
6813
+ "15": "y",
6814
+ "16": "y",
6815
+ "17": "y",
6816
+ "18": "y"
6817
+ },
6818
+ "ios_saf": {
6819
+ "3.2": "n",
6820
+ "4.0-4.1": "n",
6821
+ "4.2-4.3": "n",
6822
+ "5.0-5.1": "y",
6823
+ "6.0-6.1": "y",
6824
+ "7.0": "y"
6825
+ },
6826
+ "op_mini": {
6827
+ "5.0-7.0": "n"
6828
+ },
6829
+ "android": {
6830
+ "2.1": "n",
6831
+ "2.2": "n",
6832
+ "2.3": "n",
6833
+ "3": "y",
6834
+ "4": "y",
6835
+ "4.1": "y",
6836
+ "4.2-4.3": "y",
6837
+ "4.4": "y"
6838
+ },
6839
+ "bb": {
6840
+ "7": "y",
6841
+ "10": "y"
6842
+ },
6843
+ "op_mob": {
6844
+ "10": "n",
6845
+ "11": "n",
6846
+ "11.1": "n",
6847
+ "11.5": "n",
6848
+ "12": "n",
6849
+ "12.1": "y",
6850
+ "0": "y"
6851
+ },
6852
+ "and_chr": {
6853
+ "0": "y"
6854
+ },
6855
+ "and_ff": {
6856
+ "0": "y"
6857
+ },
6858
+ "ie_mob": {
6859
+ "10": "y"
6860
+ }
6861
+ },
6862
+ "notes": "This support only refers to very basic editing capability, implementations vary significantly on how certain elements can be edited.",
6863
+ "usage_perc_y": 88.37,
6864
+ "usage_perc_a": 0.09,
6865
+ "ucprefix": false,
6866
+ "parent": "",
6867
+ "keywords": ""
6868
+ },
6869
+ "dragndrop": {
6870
+ "title": "Drag and Drop",
6871
+ "description": "Method of easily dragging and dropping elements on a page, requiring minimal JavaScript.",
6872
+ "spec": "http://www.w3.org/TR/html5/editing.html#dnd",
6873
+ "status": "wd",
6874
+ "links": [{
6875
+ "url": "http://html5demos.com/drag",
6876
+ "title": "Demo with link blocks"
6877
+ }, {
6878
+ "url": "http://html5doctor.com/native-drag-and-drop/",
6879
+ "title": "HTML5 Doctor article"
6880
+ }, {
6881
+ "url": "http://docs.webplatform.org/wiki/dom/events/drag",
6882
+ "title": "WebPlatform Docs"
6883
+ }, {
6884
+ "url": "http://nettutsplus.s3.amazonaws.com/64_html5dragdrop/demo/index.html",
6885
+ "title": "Shopping cart demo"
6886
+ }],
6887
+ "categories": ["HTML5"],
6888
+ "stats": {
6889
+ "ie": {
6890
+ "5.5": "a",
6891
+ "6": "a",
6892
+ "7": "a",
6893
+ "8": "a",
6894
+ "9": "a",
6895
+ "10": "y",
6896
+ "11": "y"
6897
+ },
6898
+ "firefox": {
6899
+ "2": "p",
6900
+ "3": "p",
6901
+ "3.5": "y",
6902
+ "3.6": "y",
6903
+ "4": "y",
6904
+ "5": "y",
6905
+ "6": "y",
6906
+ "7": "y",
6907
+ "8": "y",
6908
+ "9": "y",
6909
+ "10": "y",
6910
+ "11": "y",
6911
+ "12": "y",
6912
+ "13": "y",
6913
+ "14": "y",
6914
+ "15": "y",
6915
+ "16": "y",
6916
+ "17": "y",
6917
+ "18": "y",
6918
+ "19": "y",
6919
+ "20": "y",
6920
+ "21": "y",
6921
+ "22": "y",
6922
+ "23": "y",
6923
+ "24": "y",
6924
+ "25": "y",
6925
+ "26": "y",
6926
+ "27": "y"
6927
+ },
6928
+ "chrome": {
6929
+ "4": "y",
6930
+ "5": "y",
6931
+ "6": "y",
6932
+ "7": "y",
6933
+ "8": "y",
6934
+ "9": "y",
6935
+ "10": "y",
6936
+ "11": "y",
6937
+ "12": "y",
6938
+ "13": "y",
6939
+ "14": "y",
6940
+ "15": "y",
6941
+ "16": "y",
6942
+ "17": "y",
6943
+ "18": "y",
6944
+ "19": "y",
6945
+ "20": "y",
6946
+ "21": "y",
6947
+ "22": "y",
6948
+ "23": "y",
6949
+ "24": "y",
6950
+ "25": "y",
6951
+ "26": "y",
6952
+ "27": "y",
6953
+ "28": "y",
6954
+ "29": "y",
6955
+ "30": "y",
6956
+ "31": "y",
6957
+ "32": "y"
6958
+ },
6959
+ "safari": {
6960
+ "3.1": "y",
6961
+ "3.2": "y",
6962
+ "4": "y",
6963
+ "5": "y",
6964
+ "5.1": "y",
6965
+ "6": "y",
6966
+ "6.1": "y",
6967
+ "7": "y"
6968
+ },
6969
+ "opera": {
6970
+ "9": "p",
6971
+ "9.5-9.6": "p",
6972
+ "10.0-10.1": "p",
6973
+ "10.5": "p",
6974
+ "10.6": "p",
6975
+ "11": "p",
6976
+ "11.1": "p",
6977
+ "11.5": "p",
6978
+ "11.6": "p",
6979
+ "12": "y",
6980
+ "12.1": "y",
6981
+ "15": "y",
6982
+ "16": "y",
6983
+ "17": "y",
6984
+ "18": "y"
6985
+ },
6986
+ "ios_saf": {
6987
+ "3.2": "n",
6988
+ "4.0-4.1": "n",
6989
+ "4.2-4.3": "n",
6990
+ "5.0-5.1": "n",
6991
+ "6.0-6.1": "n",
6992
+ "7.0": "n"
6993
+ },
6994
+ "op_mini": {
6995
+ "5.0-7.0": "n"
6996
+ },
6997
+ "android": {
6998
+ "2.1": "n",
6999
+ "2.2": "n",
7000
+ "2.3": "n",
7001
+ "3": "n",
7002
+ "4": "n",
7003
+ "4.1": "n",
7004
+ "4.2-4.3": "n",
7005
+ "4.4": "n"
7006
+ },
7007
+ "bb": {
7008
+ "7": "n",
7009
+ "10": "n"
7010
+ },
7011
+ "op_mob": {
7012
+ "10": "p",
7013
+ "11": "p",
7014
+ "11.1": "p",
7015
+ "11.5": "p",
7016
+ "12": "p",
7017
+ "12.1": "y",
7018
+ "0": "n"
7019
+ },
7020
+ "and_chr": {
7021
+ "0": "n"
7022
+ },
7023
+ "and_ff": {
7024
+ "0": "n"
7025
+ },
7026
+ "ie_mob": {
7027
+ "10": "y"
7028
+ }
7029
+ },
7030
+ "notes": "Partial support in older IE refers to no support for the dataTransfer.files or .types objects and limited supported formats for dataTransfer.setData/getData.",
7031
+ "usage_perc_y": 64.83,
7032
+ "usage_perc_a": 14.25,
7033
+ "ucprefix": false,
7034
+ "parent": "",
7035
+ "keywords": "draganddrop"
7036
+ },
7037
+ "queryselector": {
7038
+ "title": "querySelector/querySelectorAll",
7039
+ "description": "Method of accessing DOM elements using CSS selectors",
7040
+ "spec": "http://www.w3.org/TR/selectors-api/",
7041
+ "status": "rec",
7042
+ "links": [{
7043
+ "url": "http://docs.webplatform.org/wiki/css/selectors_api/querySelector",
7044
+ "title": "WebPlatform Docs"
7045
+ }, {
7046
+ "url": "http://cjihrig.com/blog/javascripts-selectors-api/",
7047
+ "title": "Blog post"
7048
+ }, {
7049
+ "url": "https://developer.mozilla.org/En/DOM/Element.querySelectorAll",
7050
+ "title": "MDN article on querySelectorAll"
7051
+ }, {
7052
+ "url": "https://developer.mozilla.org/en/DOM/element.querySelector",
7053
+ "title": "MDN article on querySelector"
7054
+ }],
7055
+ "categories": ["DOM"],
7056
+ "stats": {
7057
+ "ie": {
7058
+ "5.5": "n",
7059
+ "6": "p",
7060
+ "7": "p",
7061
+ "8": "y",
7062
+ "9": "y",
7063
+ "10": "y",
7064
+ "11": "y"
7065
+ },
7066
+ "firefox": {
7067
+ "2": "p",
7068
+ "3": "p",
7069
+ "3.5": "y",
7070
+ "3.6": "y",
7071
+ "4": "y",
7072
+ "5": "y",
7073
+ "6": "y",
7074
+ "7": "y",
7075
+ "8": "y",
7076
+ "9": "y",
7077
+ "10": "y",
7078
+ "11": "y",
7079
+ "12": "y",
7080
+ "13": "y",
7081
+ "14": "y",
7082
+ "15": "y",
7083
+ "16": "y",
7084
+ "17": "y",
7085
+ "18": "y",
7086
+ "19": "y",
7087
+ "20": "y",
7088
+ "21": "y",
7089
+ "22": "y",
7090
+ "23": "y",
7091
+ "24": "y",
7092
+ "25": "y",
7093
+ "26": "y",
7094
+ "27": "y"
7095
+ },
7096
+ "chrome": {
7097
+ "4": "y",
7098
+ "5": "y",
7099
+ "6": "y",
7100
+ "7": "y",
7101
+ "8": "y",
7102
+ "9": "y",
7103
+ "10": "y",
7104
+ "11": "y",
7105
+ "12": "y",
7106
+ "13": "y",
7107
+ "14": "y",
7108
+ "15": "y",
7109
+ "16": "y",
7110
+ "17": "y",
7111
+ "18": "y",
7112
+ "19": "y",
7113
+ "20": "y",
7114
+ "21": "y",
7115
+ "22": "y",
7116
+ "23": "y",
7117
+ "24": "y",
7118
+ "25": "y",
7119
+ "26": "y",
7120
+ "27": "y",
7121
+ "28": "y",
7122
+ "29": "y",
7123
+ "30": "y",
7124
+ "31": "y",
7125
+ "32": "y"
7126
+ },
7127
+ "safari": {
7128
+ "3.1": "y",
7129
+ "3.2": "y",
7130
+ "4": "y",
7131
+ "5": "y",
7132
+ "5.1": "y",
7133
+ "6": "y",
7134
+ "6.1": "y",
7135
+ "7": "y"
7136
+ },
7137
+ "opera": {
7138
+ "9": "p",
7139
+ "9.5-9.6": "p",
7140
+ "10.0-10.1": "y",
7141
+ "10.5": "y",
7142
+ "10.6": "y",
7143
+ "11": "y",
7144
+ "11.1": "y",
7145
+ "11.5": "y",
7146
+ "11.6": "y",
7147
+ "12": "y",
7148
+ "12.1": "y",
7149
+ "15": "y",
7150
+ "16": "y",
7151
+ "17": "y",
7152
+ "18": "y"
7153
+ },
7154
+ "ios_saf": {
7155
+ "3.2": "y",
7156
+ "4.0-4.1": "y",
7157
+ "4.2-4.3": "y",
7158
+ "5.0-5.1": "y",
7159
+ "6.0-6.1": "y",
7160
+ "7.0": "y"
7161
+ },
7162
+ "op_mini": {
7163
+ "5.0-7.0": "y"
7164
+ },
7165
+ "android": {
7166
+ "2.1": "y",
7167
+ "2.2": "y",
7168
+ "2.3": "y",
7169
+ "3": "y",
7170
+ "4": "y",
7171
+ "4.1": "y",
7172
+ "4.2-4.3": "y",
7173
+ "4.4": "y"
7174
+ },
7175
+ "bb": {
7176
+ "7": "y",
7177
+ "10": "y"
7178
+ },
7179
+ "op_mob": {
7180
+ "10": "y",
7181
+ "11": "y",
7182
+ "11.1": "y",
7183
+ "11.5": "y",
7184
+ "12": "y",
7185
+ "12.1": "y",
7186
+ "0": "y"
7187
+ },
7188
+ "and_chr": {
7189
+ "0": "y"
7190
+ },
7191
+ "and_ff": {
7192
+ "0": "y"
7193
+ },
7194
+ "ie_mob": {
7195
+ "10": "y"
7196
+ }
7197
+ },
7198
+ "notes": "Only works for the CSS selectors available. Thus the IE8 implementation is limited to the CSS 2.1 selectors",
7199
+ "usage_perc_y": 93.74,
7200
+ "usage_perc_a": 0,
7201
+ "ucprefix": false,
7202
+ "parent": "",
7203
+ "keywords": "query,selectors,selectors api"
7204
+ },
7205
+ "getelementsbyclassname": {
7206
+ "title": "getElementsByClassName",
7207
+ "description": "Method of accessing DOM elements by class name",
7208
+ "spec": "http://www.w3.org/TR/dom/#dom-document-getelementsbyclassname",
7209
+ "status": "wd",
7210
+ "links": [{
7211
+ "url": "http://www.quirksmode.org/dom/tests/basics.html#getElementsByClassName",
7212
+ "title": "Test page"
7213
+ }, {
7214
+ "url": "http://docs.webplatform.org/wiki/dom/methods/getElementsByClassName",
7215
+ "title": "WebPlatform Docs"
7216
+ }],
7217
+ "categories": ["DOM", "HTML5"],
7218
+ "stats": {
7219
+ "ie": {
7220
+ "5.5": "n",
7221
+ "6": "p",
7222
+ "7": "p",
7223
+ "8": "p",
7224
+ "9": "y",
7225
+ "10": "y",
7226
+ "11": "y"
7227
+ },
7228
+ "firefox": {
7229
+ "2": "p",
7230
+ "3": "y",
7231
+ "3.5": "y",
7232
+ "3.6": "y",
7233
+ "4": "y",
7234
+ "5": "y",
7235
+ "6": "y",
7236
+ "7": "y",
7237
+ "8": "y",
7238
+ "9": "y",
7239
+ "10": "y",
7240
+ "11": "y",
7241
+ "12": "y",
7242
+ "13": "y",
7243
+ "14": "y",
7244
+ "15": "y",
7245
+ "16": "y",
7246
+ "17": "y",
7247
+ "18": "y",
7248
+ "19": "y",
7249
+ "20": "y",
7250
+ "21": "y",
7251
+ "22": "y",
7252
+ "23": "y",
7253
+ "24": "y",
7254
+ "25": "y",
7255
+ "26": "y",
7256
+ "27": "y"
7257
+ },
7258
+ "chrome": {
7259
+ "4": "y",
7260
+ "5": "y",
7261
+ "6": "y",
7262
+ "7": "y",
7263
+ "8": "y",
7264
+ "9": "y",
7265
+ "10": "y",
7266
+ "11": "y",
7267
+ "12": "y",
7268
+ "13": "y",
7269
+ "14": "y",
7270
+ "15": "y",
7271
+ "16": "y",
7272
+ "17": "y",
7273
+ "18": "y",
7274
+ "19": "y",
7275
+ "20": "y",
7276
+ "21": "y",
7277
+ "22": "y",
7278
+ "23": "y",
7279
+ "24": "y",
7280
+ "25": "y",
7281
+ "26": "y",
7282
+ "27": "y",
7283
+ "28": "y",
7284
+ "29": "y",
7285
+ "30": "y",
7286
+ "31": "y",
7287
+ "32": "y"
7288
+ },
7289
+ "safari": {
7290
+ "3.1": "y",
7291
+ "3.2": "y",
7292
+ "4": "y",
7293
+ "5": "y",
7294
+ "5.1": "y",
7295
+ "6": "y",
7296
+ "6.1": "y",
7297
+ "7": "y"
7298
+ },
7299
+ "opera": {
7300
+ "9": "n",
7301
+ "9.5-9.6": "y",
7302
+ "10.0-10.1": "y",
7303
+ "10.5": "y",
7304
+ "10.6": "y",
7305
+ "11": "y",
7306
+ "11.1": "y",
7307
+ "11.5": "y",
7308
+ "11.6": "y",
7309
+ "12": "y",
7310
+ "12.1": "y",
7311
+ "15": "y",
7312
+ "16": "y",
7313
+ "17": "y",
7314
+ "18": "y"
7315
+ },
7316
+ "ios_saf": {
7317
+ "3.2": "y",
7318
+ "4.0-4.1": "y",
7319
+ "4.2-4.3": "y",
7320
+ "5.0-5.1": "y",
7321
+ "6.0-6.1": "y",
7322
+ "7.0": "y"
7323
+ },
7324
+ "op_mini": {
7325
+ "5.0-7.0": "y"
7326
+ },
7327
+ "android": {
7328
+ "2.1": "y",
7329
+ "2.2": "y",
7330
+ "2.3": "y",
7331
+ "3": "y",
7332
+ "4": "y",
7333
+ "4.1": "y",
7334
+ "4.2-4.3": "y",
7335
+ "4.4": "y"
7336
+ },
7337
+ "bb": {
7338
+ "7": "y",
7339
+ "10": "y"
7340
+ },
7341
+ "op_mob": {
7342
+ "10": "y",
7343
+ "11": "y",
7344
+ "11.1": "y",
7345
+ "11.5": "y",
7346
+ "12": "y",
7347
+ "12.1": "y",
7348
+ "0": "y"
7349
+ },
7350
+ "and_chr": {
7351
+ "0": "y"
7352
+ },
7353
+ "and_ff": {
7354
+ "0": "y"
7355
+ },
7356
+ "ie_mob": {
7357
+ "10": "y"
7358
+ }
7359
+ },
7360
+ "notes": "",
7361
+ "usage_perc_y": 85.52,
7362
+ "usage_perc_a": 0,
7363
+ "ucprefix": false,
7364
+ "parent": "",
7365
+ "keywords": "byclassname"
7366
+ },
7367
+ "forms": {
7368
+ "title": "HTML5 form features",
7369
+ "description": "Expanded form options, including things like date pickers, sliders, validation, placeholders and multiple file uploads. Previously known as \"Web forms 2.0\".",
7370
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html",
7371
+ "status": "wd",
7372
+ "links": [{
7373
+ "url": "https://github.com/westonruter/webforms2",
7374
+ "title": "Cross-browser JS implementation (based on original spec)"
7375
+ }, {
7376
+ "url": "http://www.miketaylr.com/code/input-type-attr.html",
7377
+ "title": "HTML5 inputs and attribute support page"
7378
+ }],
7379
+ "categories": ["HTML5"],
7380
+ "stats": {
7381
+ "ie": {
7382
+ "5.5": "n",
7383
+ "6": "p",
7384
+ "7": "p",
7385
+ "8": "p",
7386
+ "9": "p",
7387
+ "10": "a",
7388
+ "11": "a"
7389
+ },
7390
+ "firefox": {
7391
+ "2": "p",
7392
+ "3": "p",
7393
+ "3.5": "p",
7394
+ "3.6": "p",
7395
+ "4": "a",
7396
+ "5": "a",
7397
+ "6": "a",
7398
+ "7": "a",
7399
+ "8": "a",
7400
+ "9": "a",
7401
+ "10": "a",
7402
+ "11": "a",
7403
+ "12": "a",
7404
+ "13": "a",
7405
+ "14": "a",
7406
+ "15": "a",
7407
+ "16": "a",
7408
+ "17": "a",
7409
+ "18": "a",
7410
+ "19": "a",
7411
+ "20": "a",
7412
+ "21": "a",
7413
+ "22": "a",
7414
+ "23": "a",
7415
+ "24": "a",
7416
+ "25": "a",
7417
+ "26": "a",
7418
+ "27": "a"
7419
+ },
7420
+ "chrome": {
7421
+ "4": "a",
7422
+ "5": "a",
7423
+ "6": "a",
7424
+ "7": "a",
7425
+ "8": "a",
7426
+ "9": "a",
7427
+ "10": "a",
7428
+ "11": "a",
7429
+ "12": "a",
7430
+ "13": "a",
7431
+ "14": "a",
7432
+ "15": "a",
7433
+ "16": "a",
7434
+ "17": "a",
7435
+ "18": "a",
7436
+ "19": "a",
7437
+ "20": "a",
7438
+ "21": "a",
7439
+ "22": "a",
7440
+ "23": "a",
7441
+ "24": "a",
7442
+ "25": "a",
7443
+ "26": "a",
7444
+ "27": "a",
7445
+ "28": "a",
7446
+ "29": "a",
7447
+ "30": "a",
7448
+ "31": "a",
7449
+ "32": "a"
7450
+ },
7451
+ "safari": {
7452
+ "3.1": "p",
7453
+ "3.2": "p",
7454
+ "4": "a",
7455
+ "5": "a",
7456
+ "5.1": "a",
7457
+ "6": "a",
7458
+ "6.1": "a",
7459
+ "7": "a"
7460
+ },
7461
+ "opera": {
7462
+ "9": "y",
7463
+ "9.5-9.6": "y",
7464
+ "10.0-10.1": "y",
7465
+ "10.5": "y",
7466
+ "10.6": "y",
7467
+ "11": "y",
7468
+ "11.1": "y",
7469
+ "11.5": "y",
7470
+ "11.6": "y",
7471
+ "12": "y",
7472
+ "12.1": "y",
7473
+ "15": "a",
7474
+ "16": "a",
7475
+ "17": "a",
7476
+ "18": "a"
7477
+ },
7478
+ "ios_saf": {
7479
+ "3.2": "n",
7480
+ "4.0-4.1": "a",
7481
+ "4.2-4.3": "a",
7482
+ "5.0-5.1": "y",
7483
+ "6.0-6.1": "y",
7484
+ "7.0": "y"
7485
+ },
7486
+ "op_mini": {
7487
+ "5.0-7.0": "n"
7488
+ },
7489
+ "android": {
7490
+ "2.1": "n",
7491
+ "2.2": "n",
7492
+ "2.3": "n",
7493
+ "3": "n",
7494
+ "4": "n",
7495
+ "4.1": "n",
7496
+ "4.2-4.3": "n",
7497
+ "4.4": "a"
7498
+ },
7499
+ "bb": {
7500
+ "7": "n",
7501
+ "10": "a"
7502
+ },
7503
+ "op_mob": {
7504
+ "10": "y",
7505
+ "11": "y",
7506
+ "11.1": "y",
7507
+ "11.5": "y",
7508
+ "12": "y",
7509
+ "12.1": "y",
7510
+ "0": "a"
7511
+ },
7512
+ "and_chr": {
7513
+ "0": "a"
7514
+ },
7515
+ "and_ff": {
7516
+ "0": "a"
7517
+ },
7518
+ "ie_mob": {
7519
+ "10": "a"
7520
+ }
7521
+ },
7522
+ "notes": "",
7523
+ "usage_perc_y": 4.75,
7524
+ "usage_perc_a": 65.35,
7525
+ "ucprefix": false,
7526
+ "parent": "",
7527
+ "keywords": "input,datepicker"
7528
+ },
7529
+ "html5semantic": {
7530
+ "title": "New semantic elements",
7531
+ "description": "HTML5 offers some new elements, primarily for semantic purposes. The elements include: section, article, aside, header, footer, nav, figure, figcaption, time, mark.",
7532
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#sections",
7533
+ "status": "wd",
7534
+ "links": [{
7535
+ "url": "http://oli.jp/2009/html5-structure3/",
7536
+ "title": "Article on structural elements"
7537
+ }, {
7538
+ "url": "http://blog.whatwg.org/supporting-new-elements-in-ie",
7539
+ "title": "Workaround for IE"
7540
+ }, {
7541
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/dom.js#dom-html5-elements",
7542
+ "title": "has.js test"
7543
+ }, {
7544
+ "url": "http://blog.whatwg.org/styling-ie-noscript",
7545
+ "title": "Alternate workaround"
7546
+ }],
7547
+ "categories": ["HTML5"],
7548
+ "stats": {
7549
+ "ie": {
7550
+ "5.5": "n",
7551
+ "6": "p",
7552
+ "7": "p",
7553
+ "8": "p",
7554
+ "9": "y",
7555
+ "10": "y",
7556
+ "11": "y"
7557
+ },
7558
+ "firefox": {
7559
+ "2": "n",
7560
+ "3": "a",
7561
+ "3.5": "a",
7562
+ "3.6": "a",
7563
+ "4": "y",
7564
+ "5": "y",
7565
+ "6": "y",
7566
+ "7": "y",
7567
+ "8": "y",
7568
+ "9": "y",
7569
+ "10": "y",
7570
+ "11": "y",
7571
+ "12": "y",
7572
+ "13": "y",
7573
+ "14": "y",
7574
+ "15": "y",
7575
+ "16": "y",
7576
+ "17": "y",
7577
+ "18": "y",
7578
+ "19": "y",
7579
+ "20": "y",
7580
+ "21": "y",
7581
+ "22": "y",
7582
+ "23": "y",
7583
+ "24": "y",
7584
+ "25": "y",
7585
+ "26": "y",
7586
+ "27": "y"
7587
+ },
7588
+ "chrome": {
7589
+ "4": "a",
7590
+ "5": "a",
7591
+ "6": "y",
7592
+ "7": "y",
7593
+ "8": "y",
7594
+ "9": "y",
7595
+ "10": "y",
7596
+ "11": "y",
7597
+ "12": "y",
7598
+ "13": "y",
7599
+ "14": "y",
7600
+ "15": "y",
7601
+ "16": "y",
7602
+ "17": "y",
7603
+ "18": "y",
7604
+ "19": "y",
7605
+ "20": "y",
7606
+ "21": "y",
7607
+ "22": "y",
7608
+ "23": "y",
7609
+ "24": "y",
7610
+ "25": "y",
7611
+ "26": "y",
7612
+ "27": "y",
7613
+ "28": "y",
7614
+ "29": "y",
7615
+ "30": "y",
7616
+ "31": "y",
7617
+ "32": "y"
7618
+ },
7619
+ "safari": {
7620
+ "3.1": "a",
7621
+ "3.2": "a",
7622
+ "4": "a",
7623
+ "5": "y",
7624
+ "5.1": "y",
7625
+ "6": "y",
7626
+ "6.1": "y",
7627
+ "7": "y"
7628
+ },
7629
+ "opera": {
7630
+ "9": "a",
7631
+ "9.5-9.6": "a",
7632
+ "10.0-10.1": "a",
7633
+ "10.5": "a",
7634
+ "10.6": "a",
7635
+ "11": "a",
7636
+ "11.1": "y",
7637
+ "11.5": "y",
7638
+ "11.6": "y",
7639
+ "12": "y",
7640
+ "12.1": "y",
7641
+ "15": "y",
7642
+ "16": "y",
7643
+ "17": "y",
7644
+ "18": "y"
7645
+ },
7646
+ "ios_saf": {
7647
+ "3.2": "a",
7648
+ "4.0-4.1": "y",
7649
+ "4.2-4.3": "y",
7650
+ "5.0-5.1": "y",
7651
+ "6.0-6.1": "y",
7652
+ "7.0": "y"
7653
+ },
7654
+ "op_mini": {
7655
+ "5.0-7.0": "a"
7656
+ },
7657
+ "android": {
7658
+ "2.1": "a",
7659
+ "2.2": "y",
7660
+ "2.3": "y",
7661
+ "3": "y",
7662
+ "4": "y",
7663
+ "4.1": "y",
7664
+ "4.2-4.3": "y",
7665
+ "4.4": "y"
7666
+ },
7667
+ "bb": {
7668
+ "7": "y",
7669
+ "10": "y"
7670
+ },
7671
+ "op_mob": {
7672
+ "10": "a",
7673
+ "11": "y",
7674
+ "11.1": "y",
7675
+ "11.5": "y",
7676
+ "12": "y",
7677
+ "12.1": "y",
7678
+ "0": "y"
7679
+ },
7680
+ "and_chr": {
7681
+ "0": "y"
7682
+ },
7683
+ "and_ff": {
7684
+ "0": "y"
7685
+ },
7686
+ "ie_mob": {
7687
+ "10": "y"
7688
+ }
7689
+ },
7690
+ "notes": "Partial support refers to missing the default styling. This is easily taken care of by using display:block for all new elements (except time and mark, these should be display:inline anyway).",
7691
+ "usage_perc_y": 80.26,
7692
+ "usage_perc_a": 5.26,
7693
+ "ucprefix": false,
7694
+ "parent": "",
7695
+ "keywords": ""
7696
+ },
7697
+ "offline-apps": {
7698
+ "title": "Offline web applications",
7699
+ "description": "Method of defining web page files to be cached using a cache manifest file, allowing them to work offline on subsequent visits to the page",
7700
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html",
7701
+ "status": "wd",
7702
+ "links": [{
7703
+ "url": "http://www.sitepoint.com/offline-web-application-tutorial/",
7704
+ "title": "Sitepoint tutorial"
7705
+ }, {
7706
+ "url": "http://diveinto.org/html5/offline.html",
7707
+ "title": "Dive Into HTML5 article"
7708
+ }, {
7709
+ "url": "http://docs.webplatform.org/wiki/apis/appcache/ApplicationCache",
7710
+ "title": "WebPlatform Docs"
7711
+ }, {
7712
+ "url": "http://hacks.mozilla.org/2010/01/offline-web-applications/",
7713
+ "title": "Mozilla Hacks article/demo"
7714
+ }],
7715
+ "categories": ["HTML5"],
7716
+ "stats": {
7717
+ "ie": {
7718
+ "5.5": "n",
7719
+ "6": "p",
7720
+ "7": "p",
7721
+ "8": "p",
7722
+ "9": "n",
7723
+ "10": "y",
7724
+ "11": "y"
7725
+ },
7726
+ "firefox": {
7727
+ "2": "p",
7728
+ "3": "a",
7729
+ "3.5": "y",
7730
+ "3.6": "y",
7731
+ "4": "y",
7732
+ "5": "y",
7733
+ "6": "y",
7734
+ "7": "y",
7735
+ "8": "y",
7736
+ "9": "y",
7737
+ "10": "y",
7738
+ "11": "y",
7739
+ "12": "y",
7740
+ "13": "y",
7741
+ "14": "y",
7742
+ "15": "y",
7743
+ "16": "y",
7744
+ "17": "y",
7745
+ "18": "y",
7746
+ "19": "y",
7747
+ "20": "y",
7748
+ "21": "y",
7749
+ "22": "y",
7750
+ "23": "y",
7751
+ "24": "y",
7752
+ "25": "y",
7753
+ "26": "y",
7754
+ "27": "y"
7755
+ },
7756
+ "chrome": {
7757
+ "4": "y",
7758
+ "5": "y",
7759
+ "6": "y",
7760
+ "7": "y",
7761
+ "8": "y",
7762
+ "9": "y",
7763
+ "10": "y",
7764
+ "11": "y",
7765
+ "12": "y",
7766
+ "13": "y",
7767
+ "14": "y",
7768
+ "15": "y",
7769
+ "16": "y",
7770
+ "17": "y",
7771
+ "18": "y",
7772
+ "19": "y",
7773
+ "20": "y",
7774
+ "21": "y",
7775
+ "22": "y",
7776
+ "23": "y",
7777
+ "24": "y",
7778
+ "25": "y",
7779
+ "26": "y",
7780
+ "27": "y",
7781
+ "28": "y",
7782
+ "29": "y",
7783
+ "30": "y",
7784
+ "31": "y",
7785
+ "32": "y"
7786
+ },
7787
+ "safari": {
7788
+ "3.1": "p",
7789
+ "3.2": "p",
7790
+ "4": "y",
7791
+ "5": "y",
7792
+ "5.1": "y",
7793
+ "6": "y",
7794
+ "6.1": "y",
7795
+ "7": "y"
7796
+ },
7797
+ "opera": {
7798
+ "9": "n",
7799
+ "9.5-9.6": "n",
7800
+ "10.0-10.1": "p",
7801
+ "10.5": "p",
7802
+ "10.6": "y",
7803
+ "11": "y",
7804
+ "11.1": "y",
7805
+ "11.5": "y",
7806
+ "11.6": "y",
7807
+ "12": "y",
7808
+ "12.1": "y",
7809
+ "15": "y",
7810
+ "16": "y",
7811
+ "17": "y",
7812
+ "18": "y"
7813
+ },
7814
+ "ios_saf": {
7815
+ "3.2": "y",
7816
+ "4.0-4.1": "y",
7817
+ "4.2-4.3": "y",
7818
+ "5.0-5.1": "y",
7819
+ "6.0-6.1": "y",
7820
+ "7.0": "y"
7821
+ },
7822
+ "op_mini": {
7823
+ "5.0-7.0": "n"
7824
+ },
7825
+ "android": {
7826
+ "2.1": "y",
7827
+ "2.2": "y",
7828
+ "2.3": "y",
7829
+ "3": "y",
7830
+ "4": "y",
7831
+ "4.1": "y",
7832
+ "4.2-4.3": "y",
7833
+ "4.4": "y"
7834
+ },
7835
+ "bb": {
7836
+ "7": "y",
7837
+ "10": "y"
7838
+ },
7839
+ "op_mob": {
7840
+ "10": "n",
7841
+ "11": "y",
7842
+ "11.1": "y",
7843
+ "11.5": "y",
7844
+ "12": "y",
7845
+ "12.1": "y",
7846
+ "0": "y"
7847
+ },
7848
+ "and_chr": {
7849
+ "0": "y"
7850
+ },
7851
+ "and_ff": {
7852
+ "0": "y"
7853
+ },
7854
+ "ie_mob": {
7855
+ "10": "y"
7856
+ }
7857
+ },
7858
+ "notes": "",
7859
+ "usage_perc_y": 75.59,
7860
+ "usage_perc_a": 0.09,
7861
+ "ucprefix": false,
7862
+ "parent": "",
7863
+ "keywords": "appcache,app cache,application cache,online"
7864
+ },
7865
+ "webworkers": {
7866
+ "title": "Web Workers",
7867
+ "description": "Method of running scripts in the background, isolated from the web page",
7868
+ "spec": "http://www.w3.org/TR/workers/",
7869
+ "status": "cr",
7870
+ "links": [{
7871
+ "url": "http://code.google.com/p/ie-web-worker/",
7872
+ "title": "Polyfill for IE (single threaded)"
7873
+ }, {
7874
+ "url": "http://net.tutsplus.com/tutorials/javascript-ajax/getting-started-with-web-workers/",
7875
+ "title": "Tutorial"
7876
+ }, {
7877
+ "url": "https://developer.mozilla.org/En/Using_web_workers",
7878
+ "title": "MDN article"
7879
+ }, {
7880
+ "url": "http://nerget.com/rayjs-mt/rayjs.html",
7881
+ "title": "Web Worker demo"
7882
+ }],
7883
+ "categories": ["JS API"],
7884
+ "stats": {
7885
+ "ie": {
7886
+ "5.5": "n",
7887
+ "6": "p",
7888
+ "7": "p",
7889
+ "8": "p",
7890
+ "9": "p",
7891
+ "10": "y",
7892
+ "11": "y"
7893
+ },
7894
+ "firefox": {
7895
+ "2": "p",
7896
+ "3": "p",
7897
+ "3.5": "y",
7898
+ "3.6": "y",
7899
+ "4": "y",
7900
+ "5": "y",
7901
+ "6": "y",
7902
+ "7": "y",
7903
+ "8": "y",
7904
+ "9": "y",
7905
+ "10": "y",
7906
+ "11": "y",
7907
+ "12": "y",
7908
+ "13": "y",
7909
+ "14": "y",
7910
+ "15": "y",
7911
+ "16": "y",
7912
+ "17": "y",
7913
+ "18": "y",
7914
+ "19": "y",
7915
+ "20": "y",
7916
+ "21": "y",
7917
+ "22": "y",
7918
+ "23": "y",
7919
+ "24": "y",
7920
+ "25": "y",
7921
+ "26": "y",
7922
+ "27": "y"
7923
+ },
7924
+ "chrome": {
7925
+ "4": "y",
7926
+ "5": "y",
7927
+ "6": "y",
7928
+ "7": "y",
7929
+ "8": "y",
7930
+ "9": "y",
7931
+ "10": "y",
7932
+ "11": "y",
7933
+ "12": "y",
7934
+ "13": "y",
7935
+ "14": "y",
7936
+ "15": "y",
7937
+ "16": "y",
7938
+ "17": "y",
7939
+ "18": "y",
7940
+ "19": "y",
7941
+ "20": "y",
7942
+ "21": "y",
7943
+ "22": "y",
7944
+ "23": "y",
7945
+ "24": "y",
7946
+ "25": "y",
7947
+ "26": "y",
7948
+ "27": "y",
7949
+ "28": "y",
7950
+ "29": "y",
7951
+ "30": "y",
7952
+ "31": "y",
7953
+ "32": "y"
7954
+ },
7955
+ "safari": {
7956
+ "3.1": "p",
7957
+ "3.2": "p",
7958
+ "4": "y",
7959
+ "5": "y",
7960
+ "5.1": "y",
7961
+ "6": "y",
7962
+ "6.1": "y",
7963
+ "7": "y"
7964
+ },
7965
+ "opera": {
7966
+ "9": "n",
7967
+ "9.5-9.6": "n",
7968
+ "10.0-10.1": "p",
7969
+ "10.5": "p",
7970
+ "10.6": "y",
7971
+ "11": "y",
7972
+ "11.1": "y",
7973
+ "11.5": "y",
7974
+ "11.6": "y",
7975
+ "12": "y",
7976
+ "12.1": "y",
7977
+ "15": "y",
7978
+ "16": "y",
7979
+ "17": "y",
7980
+ "18": "y"
7981
+ },
7982
+ "ios_saf": {
7983
+ "3.2": "n",
7984
+ "4.0-4.1": "n",
7985
+ "4.2-4.3": "n",
7986
+ "5.0-5.1": "y",
7987
+ "6.0-6.1": "y",
7988
+ "7.0": "y"
7989
+ },
7990
+ "op_mini": {
7991
+ "5.0-7.0": "n"
7992
+ },
7993
+ "android": {
7994
+ "2.1": "y",
7995
+ "2.2": "n",
7996
+ "2.3": "n",
7997
+ "3": "n",
7998
+ "4": "n",
7999
+ "4.1": "n",
8000
+ "4.2-4.3": "n",
8001
+ "4.4": "y"
8002
+ },
8003
+ "bb": {
8004
+ "7": "y",
8005
+ "10": "y"
8006
+ },
8007
+ "op_mob": {
8008
+ "10": "p",
8009
+ "11": "y",
8010
+ "11.1": "y",
8011
+ "11.5": "y",
8012
+ "12": "y",
8013
+ "12.1": "y",
8014
+ "0": "y"
8015
+ },
8016
+ "and_chr": {
8017
+ "0": "y"
8018
+ },
8019
+ "and_ff": {
8020
+ "0": "y"
8021
+ },
8022
+ "ie_mob": {
8023
+ "10": "y"
8024
+ }
8025
+ },
8026
+ "notes": "",
8027
+ "usage_perc_y": 70.53,
8028
+ "usage_perc_a": 0,
8029
+ "ucprefix": false,
8030
+ "parent": "",
8031
+ "keywords": ""
8032
+ },
8033
+ "fontface": {
8034
+ "title": "@font-face Web fonts",
8035
+ "description": "Method of displaying fonts downloaded from websites",
8036
+ "spec": "http://www.w3.org/TR/css3-webfonts/",
8037
+ "status": "wd",
8038
+ "links": [{
8039
+ "url": "http://docs.webplatform.org/wiki/css/atrules/@font-face",
8040
+ "title": "WebPlatform Docs"
8041
+ }, {
8042
+ "url": "http://www.css3files.com/font/",
8043
+ "title": "Information page"
8044
+ }, {
8045
+ "url": "http://webfonts.info",
8046
+ "title": "News and information site"
8047
+ }, {
8048
+ "url": "http://en.wikipedia.org/wiki/Web_typography",
8049
+ "title": "Wikipedia"
8050
+ }],
8051
+ "categories": ["CSS3"],
8052
+ "stats": {
8053
+ "ie": {
8054
+ "5.5": "a",
8055
+ "6": "a",
8056
+ "7": "a",
8057
+ "8": "a",
8058
+ "9": "y",
8059
+ "10": "y",
8060
+ "11": "y"
8061
+ },
8062
+ "firefox": {
8063
+ "2": "n",
8064
+ "3": "n",
8065
+ "3.5": "y",
8066
+ "3.6": "y",
8067
+ "4": "y",
8068
+ "5": "y",
8069
+ "6": "y",
8070
+ "7": "y",
8071
+ "8": "y",
8072
+ "9": "y",
8073
+ "10": "y",
8074
+ "11": "y",
8075
+ "12": "y",
8076
+ "13": "y",
8077
+ "14": "y",
8078
+ "15": "y",
8079
+ "16": "y",
8080
+ "17": "y",
8081
+ "18": "y",
8082
+ "19": "y",
8083
+ "20": "y",
8084
+ "21": "y",
8085
+ "22": "y",
8086
+ "23": "y",
8087
+ "24": "y",
8088
+ "25": "y",
8089
+ "26": "y",
8090
+ "27": "y"
8091
+ },
8092
+ "chrome": {
8093
+ "4": "y",
8094
+ "5": "y",
8095
+ "6": "y",
8096
+ "7": "y",
8097
+ "8": "y",
8098
+ "9": "y",
8099
+ "10": "y",
8100
+ "11": "y",
8101
+ "12": "y",
8102
+ "13": "y",
8103
+ "14": "y",
8104
+ "15": "y",
8105
+ "16": "y",
8106
+ "17": "y",
8107
+ "18": "y",
8108
+ "19": "y",
8109
+ "20": "y",
8110
+ "21": "y",
8111
+ "22": "y",
8112
+ "23": "y",
8113
+ "24": "y",
8114
+ "25": "y",
8115
+ "26": "y",
8116
+ "27": "y",
8117
+ "28": "y",
8118
+ "29": "y",
8119
+ "30": "y",
8120
+ "31": "y",
8121
+ "32": "y"
8122
+ },
8123
+ "safari": {
8124
+ "3.1": "n",
8125
+ "3.2": "y",
8126
+ "4": "y",
8127
+ "5": "y",
8128
+ "5.1": "y",
8129
+ "6": "y",
8130
+ "6.1": "y",
8131
+ "7": "y"
8132
+ },
8133
+ "opera": {
8134
+ "9": "n",
8135
+ "9.5-9.6": "n",
8136
+ "10.0-10.1": "y",
8137
+ "10.5": "y",
8138
+ "10.6": "y",
8139
+ "11": "y",
8140
+ "11.1": "y",
8141
+ "11.5": "y",
8142
+ "11.6": "y",
8143
+ "12": "y",
8144
+ "12.1": "y",
8145
+ "15": "y",
8146
+ "16": "y",
8147
+ "17": "y",
8148
+ "18": "y"
8149
+ },
8150
+ "ios_saf": {
8151
+ "3.2": "a",
8152
+ "4.0-4.1": "a",
8153
+ "4.2-4.3": "y",
8154
+ "5.0-5.1": "y",
8155
+ "6.0-6.1": "y",
8156
+ "7.0": "y"
8157
+ },
8158
+ "op_mini": {
8159
+ "5.0-7.0": "n"
8160
+ },
8161
+ "android": {
8162
+ "2.1": "n",
8163
+ "2.2": "a",
8164
+ "2.3": "a",
8165
+ "3": "a",
8166
+ "4": "y",
8167
+ "4.1": "y",
8168
+ "4.2-4.3": "y",
8169
+ "4.4": "y"
8170
+ },
8171
+ "bb": {
8172
+ "7": "a",
8173
+ "10": "y"
8174
+ },
8175
+ "op_mob": {
8176
+ "10": "y",
8177
+ "11": "y",
8178
+ "11.1": "y",
8179
+ "11.5": "y",
8180
+ "12": "y",
8181
+ "12.1": "y",
8182
+ "0": "y"
8183
+ },
8184
+ "and_chr": {
8185
+ "0": "y"
8186
+ },
8187
+ "and_ff": {
8188
+ "0": "y"
8189
+ },
8190
+ "ie_mob": {
8191
+ "10": "y"
8192
+ }
8193
+ },
8194
+ "notes": "Partial support before IE8 refers to only supporting EOT fonts. Safari for iOS 4.1 and below only supports SVG fonts.",
8195
+ "usage_perc_y": 79.25,
8196
+ "usage_perc_a": 10.6,
8197
+ "ucprefix": false,
8198
+ "parent": "",
8199
+ "keywords": "font face"
8200
+ },
8201
+ "eot": {
8202
+ "title": "EOT - Embedded OpenType fonts",
8203
+ "description": "Type of font that can be derived from a regular font, allowing small files and legal use of high-quality fonts. Usage is restricted by the file being tied to the website",
8204
+ "spec": "http://www.w3.org/Submission/EOT/",
8205
+ "status": "unoff",
8206
+ "links": [{
8207
+ "url": "http://www.microsoft.com/typography/web/embedding/default.aspx",
8208
+ "title": "Example pages"
8209
+ }, {
8210
+ "url": "http://en.wikipedia.org/wiki/Embedded_OpenType",
8211
+ "title": "Wikipedia"
8212
+ }],
8213
+ "categories": ["Other"],
8214
+ "stats": {
8215
+ "ie": {
8216
+ "5.5": "n",
8217
+ "6": "y",
8218
+ "7": "y",
8219
+ "8": "y",
8220
+ "9": "y",
8221
+ "10": "y",
8222
+ "11": "y"
8223
+ },
8224
+ "firefox": {
8225
+ "2": "n",
8226
+ "3": "n",
8227
+ "3.5": "n",
8228
+ "3.6": "n",
8229
+ "4": "n",
8230
+ "5": "n",
8231
+ "6": "n",
8232
+ "7": "n",
8233
+ "8": "n",
8234
+ "9": "n",
8235
+ "10": "n",
8236
+ "11": "n",
8237
+ "12": "n",
8238
+ "13": "n",
8239
+ "14": "n",
8240
+ "15": "n",
8241
+ "16": "n",
8242
+ "17": "n",
8243
+ "18": "n",
8244
+ "19": "n",
8245
+ "20": "n",
8246
+ "21": "n",
8247
+ "22": "n",
8248
+ "23": "n",
8249
+ "24": "n",
8250
+ "25": "n",
8251
+ "26": "n",
8252
+ "27": "n"
8253
+ },
8254
+ "chrome": {
8255
+ "4": "n",
8256
+ "5": "n",
8257
+ "6": "n",
8258
+ "7": "n",
8259
+ "8": "n",
8260
+ "9": "n",
8261
+ "10": "n",
8262
+ "11": "n",
8263
+ "12": "n",
8264
+ "13": "n",
8265
+ "14": "n",
8266
+ "15": "n",
8267
+ "16": "n",
8268
+ "17": "n",
8269
+ "18": "n",
8270
+ "19": "n",
8271
+ "20": "n",
8272
+ "21": "n",
8273
+ "22": "n",
8274
+ "23": "n",
8275
+ "24": "n",
8276
+ "25": "n",
8277
+ "26": "n",
8278
+ "27": "n",
8279
+ "28": "n",
8280
+ "29": "n",
8281
+ "30": "n",
8282
+ "31": "n",
8283
+ "32": "n"
8284
+ },
8285
+ "safari": {
8286
+ "3.1": "n",
8287
+ "3.2": "n",
8288
+ "4": "n",
8289
+ "5": "n",
8290
+ "5.1": "n",
8291
+ "6": "n",
8292
+ "6.1": "n",
8293
+ "7": "n"
8294
+ },
8295
+ "opera": {
8296
+ "9": "n",
8297
+ "9.5-9.6": "n",
8298
+ "10.0-10.1": "n",
8299
+ "10.5": "n",
8300
+ "10.6": "n",
8301
+ "11": "n",
8302
+ "11.1": "n",
8303
+ "11.5": "n",
8304
+ "11.6": "n",
8305
+ "12": "n",
8306
+ "12.1": "n",
8307
+ "15": "n",
8308
+ "16": "n",
8309
+ "17": "n",
8310
+ "18": "n"
8311
+ },
8312
+ "ios_saf": {
8313
+ "3.2": "n",
8314
+ "4.0-4.1": "n",
8315
+ "4.2-4.3": "n",
8316
+ "5.0-5.1": "n",
8317
+ "6.0-6.1": "n",
8318
+ "7.0": "n"
8319
+ },
8320
+ "op_mini": {
8321
+ "5.0-7.0": "n"
8322
+ },
8323
+ "android": {
8324
+ "2.1": "n",
8325
+ "2.2": "n",
8326
+ "2.3": "n",
8327
+ "3": "n",
8328
+ "4": "n",
8329
+ "4.1": "n",
8330
+ "4.2-4.3": "n",
8331
+ "4.4": "n"
8332
+ },
8333
+ "bb": {
8334
+ "7": "n",
8335
+ "10": "n"
8336
+ },
8337
+ "op_mob": {
8338
+ "10": "n",
8339
+ "11": "n",
8340
+ "11.1": "n",
8341
+ "11.5": "n",
8342
+ "12": "n",
8343
+ "12.1": "n",
8344
+ "0": "n"
8345
+ },
8346
+ "and_chr": {
8347
+ "0": "n"
8348
+ },
8349
+ "and_ff": {
8350
+ "0": "n"
8351
+ },
8352
+ "ie_mob": {
8353
+ "10": "n"
8354
+ }
8355
+ },
8356
+ "notes": "Proposal by Microsoft, being considered for W3C standardization.",
8357
+ "usage_perc_y": 25.14,
8358
+ "usage_perc_a": 0,
8359
+ "ucprefix": false,
8360
+ "parent": "fontface",
8361
+ "keywords": ""
8362
+ },
8363
+ "woff": {
8364
+ "title": "WOFF - Web Open Font Format",
8365
+ "description": "Compressed TrueType/OpenType font that contains information about the font's source.",
8366
+ "spec": "http://www.w3.org/TR/WOFF/",
8367
+ "status": "rec",
8368
+ "links": [{
8369
+ "url": "http://hacks.mozilla.org/2009/10/woff/",
8370
+ "title": "Mozilla hacks blog post"
8371
+ }],
8372
+ "categories": ["Other"],
8373
+ "stats": {
8374
+ "ie": {
8375
+ "5.5": "n",
8376
+ "6": "n",
8377
+ "7": "n",
8378
+ "8": "n",
8379
+ "9": "y",
8380
+ "10": "y",
8381
+ "11": "y"
8382
+ },
8383
+ "firefox": {
8384
+ "2": "n",
8385
+ "3": "n",
8386
+ "3.5": "n",
8387
+ "3.6": "y",
8388
+ "4": "y",
8389
+ "5": "y",
8390
+ "6": "y",
8391
+ "7": "y",
8392
+ "8": "y",
8393
+ "9": "y",
8394
+ "10": "y",
8395
+ "11": "y",
8396
+ "12": "y",
8397
+ "13": "y",
8398
+ "14": "y",
8399
+ "15": "y",
8400
+ "16": "y",
8401
+ "17": "y",
8402
+ "18": "y",
8403
+ "19": "y",
8404
+ "20": "y",
8405
+ "21": "y",
8406
+ "22": "y",
8407
+ "23": "y",
8408
+ "24": "y",
8409
+ "25": "y",
8410
+ "26": "y",
8411
+ "27": "y"
8412
+ },
8413
+ "chrome": {
8414
+ "4": "n",
8415
+ "5": "y",
8416
+ "6": "y",
8417
+ "7": "y",
8418
+ "8": "y",
8419
+ "9": "y",
8420
+ "10": "y",
8421
+ "11": "y",
8422
+ "12": "y",
8423
+ "13": "y",
8424
+ "14": "y",
8425
+ "15": "y",
8426
+ "16": "y",
8427
+ "17": "y",
8428
+ "18": "y",
8429
+ "19": "y",
8430
+ "20": "y",
8431
+ "21": "y",
8432
+ "22": "y",
8433
+ "23": "y",
8434
+ "24": "y",
8435
+ "25": "y",
8436
+ "26": "y",
8437
+ "27": "y",
8438
+ "28": "y",
8439
+ "29": "y",
8440
+ "30": "y",
8441
+ "31": "y",
8442
+ "32": "y"
8443
+ },
8444
+ "safari": {
8445
+ "3.1": "n",
8446
+ "3.2": "n",
8447
+ "4": "n",
8448
+ "5": "n",
8449
+ "5.1": "y",
8450
+ "6": "y",
8451
+ "6.1": "y",
8452
+ "7": "y"
8453
+ },
8454
+ "opera": {
8455
+ "9": "n",
8456
+ "9.5-9.6": "n",
8457
+ "10.0-10.1": "n",
8458
+ "10.5": "n",
8459
+ "10.6": "n",
8460
+ "11": "n",
8461
+ "11.1": "y",
8462
+ "11.5": "y",
8463
+ "11.6": "y",
8464
+ "12": "y",
8465
+ "12.1": "y",
8466
+ "15": "y",
8467
+ "16": "y",
8468
+ "17": "y",
8469
+ "18": "y"
8470
+ },
8471
+ "ios_saf": {
8472
+ "3.2": "n",
8473
+ "4.0-4.1": "n",
8474
+ "4.2-4.3": "n",
8475
+ "5.0-5.1": "y",
8476
+ "6.0-6.1": "y",
8477
+ "7.0": "y"
8478
+ },
8479
+ "op_mini": {
8480
+ "5.0-7.0": "n"
8481
+ },
8482
+ "android": {
8483
+ "2.1": "n",
8484
+ "2.2": "n",
8485
+ "2.3": "n",
8486
+ "3": "n",
8487
+ "4": "n",
8488
+ "4.1": "n",
8489
+ "4.2-4.3": "n",
8490
+ "4.4": "y"
8491
+ },
8492
+ "bb": {
8493
+ "7": "y",
8494
+ "10": "y"
8495
+ },
8496
+ "op_mob": {
8497
+ "10": "n",
8498
+ "11": "y",
8499
+ "11.1": "y",
8500
+ "11.5": "y",
8501
+ "12": "y",
8502
+ "12.1": "y",
8503
+ "0": "y"
8504
+ },
8505
+ "and_chr": {
8506
+ "0": "y"
8507
+ },
8508
+ "and_ff": {
8509
+ "0": "y"
8510
+ },
8511
+ "ie_mob": {
8512
+ "10": "y"
8513
+ }
8514
+ },
8515
+ "notes": "Reported to be supported in some modified versions of the Android 4.0 browser.",
8516
+ "usage_perc_y": 75.23,
8517
+ "usage_perc_a": 0,
8518
+ "ucprefix": false,
8519
+ "parent": "fontface",
8520
+ "keywords": ""
8521
+ },
8522
+ "multibackgrounds": {
8523
+ "title": "CSS3 Multiple backgrounds",
8524
+ "description": "Method of using multiple images as a background",
8525
+ "spec": "http://www.w3.org/TR/css3-background/",
8526
+ "status": "cr",
8527
+ "links": [{
8528
+ "url": "http://www.css3.info/preview/multiple-backgrounds/",
8529
+ "title": "Demo & information page"
8530
+ }, {
8531
+ "url": "http://www.css3files.com/background/",
8532
+ "title": "Information page"
8533
+ }, {
8534
+ "url": "http://docs.webplatform.org/wiki/css/properties/background-image",
8535
+ "title": "WebPlatform Docs"
8536
+ }],
8537
+ "categories": ["CSS3"],
8538
+ "stats": {
8539
+ "ie": {
8540
+ "5.5": "n",
8541
+ "6": "n",
8542
+ "7": "n",
8543
+ "8": "n",
8544
+ "9": "y",
8545
+ "10": "y",
8546
+ "11": "y"
8547
+ },
8548
+ "firefox": {
8549
+ "2": "n",
8550
+ "3": "n",
8551
+ "3.5": "n",
8552
+ "3.6": "y",
8553
+ "4": "y",
8554
+ "5": "y",
8555
+ "6": "y",
8556
+ "7": "y",
8557
+ "8": "y",
8558
+ "9": "y",
8559
+ "10": "y",
8560
+ "11": "y",
8561
+ "12": "y",
8562
+ "13": "y",
8563
+ "14": "y",
8564
+ "15": "y",
8565
+ "16": "y",
8566
+ "17": "y",
8567
+ "18": "y",
8568
+ "19": "y",
8569
+ "20": "y",
8570
+ "21": "y",
8571
+ "22": "y",
8572
+ "23": "y",
8573
+ "24": "y",
8574
+ "25": "y",
8575
+ "26": "y",
8576
+ "27": "y"
8577
+ },
8578
+ "chrome": {
8579
+ "4": "y",
8580
+ "5": "y",
8581
+ "6": "y",
8582
+ "7": "y",
8583
+ "8": "y",
8584
+ "9": "y",
8585
+ "10": "y",
8586
+ "11": "y",
8587
+ "12": "y",
8588
+ "13": "y",
8589
+ "14": "y",
8590
+ "15": "y",
8591
+ "16": "y",
8592
+ "17": "y",
8593
+ "18": "y",
8594
+ "19": "y",
8595
+ "20": "y",
8596
+ "21": "y",
8597
+ "22": "y",
8598
+ "23": "y",
8599
+ "24": "y",
8600
+ "25": "y",
8601
+ "26": "y",
8602
+ "27": "y",
8603
+ "28": "y",
8604
+ "29": "y",
8605
+ "30": "y",
8606
+ "31": "y",
8607
+ "32": "y"
8608
+ },
8609
+ "safari": {
8610
+ "3.1": "y",
8611
+ "3.2": "y",
8612
+ "4": "y",
8613
+ "5": "y",
8614
+ "5.1": "y",
8615
+ "6": "y",
8616
+ "6.1": "y",
8617
+ "7": "y"
8618
+ },
8619
+ "opera": {
8620
+ "9": "n",
8621
+ "9.5-9.6": "n",
8622
+ "10.0-10.1": "n",
8623
+ "10.5": "y",
8624
+ "10.6": "y",
8625
+ "11": "y",
8626
+ "11.1": "y",
8627
+ "11.5": "y",
8628
+ "11.6": "y",
8629
+ "12": "y",
8630
+ "12.1": "y",
8631
+ "15": "y",
8632
+ "16": "y",
8633
+ "17": "y",
8634
+ "18": "y"
8635
+ },
8636
+ "ios_saf": {
8637
+ "3.2": "y",
8638
+ "4.0-4.1": "y",
8639
+ "4.2-4.3": "y",
8640
+ "5.0-5.1": "y",
8641
+ "6.0-6.1": "y",
8642
+ "7.0": "y"
8643
+ },
8644
+ "op_mini": {
8645
+ "5.0-7.0": "y"
8646
+ },
8647
+ "android": {
8648
+ "2.1": "y",
8649
+ "2.2": "y",
8650
+ "2.3": "y",
8651
+ "3": "y",
8652
+ "4": "y",
8653
+ "4.1": "y",
8654
+ "4.2-4.3": "y",
8655
+ "4.4": "y"
8656
+ },
8657
+ "bb": {
8658
+ "7": "y",
8659
+ "10": "y"
8660
+ },
8661
+ "op_mob": {
8662
+ "10": "y",
8663
+ "11": "y",
8664
+ "11.1": "y",
8665
+ "11.5": "y",
8666
+ "12": "y",
8667
+ "12.1": "y",
8668
+ "0": "y"
8669
+ },
8670
+ "and_chr": {
8671
+ "0": "y"
8672
+ },
8673
+ "and_ff": {
8674
+ "0": "y"
8675
+ },
8676
+ "ie_mob": {
8677
+ "10": "y"
8678
+ }
8679
+ },
8680
+ "notes": "",
8681
+ "usage_perc_y": 85.37,
8682
+ "usage_perc_a": 0,
8683
+ "ucprefix": false,
8684
+ "parent": "",
8685
+ "keywords": ""
8686
+ },
8687
+ "border-image": {
8688
+ "title": "CSS3 Border images",
8689
+ "description": "Method of using images for borders",
8690
+ "spec": "http://www.w3.org/TR/css3-background/#the-border-image",
8691
+ "status": "cr",
8692
+ "links": [{
8693
+ "url": "http://www.css3files.com/border/",
8694
+ "title": "Information page"
8695
+ }, {
8696
+ "url": "http://docs.webplatform.org/wiki/css/properties/border-image",
8697
+ "title": "WebPlatform Docs"
8698
+ }],
8699
+ "categories": ["CSS3"],
8700
+ "stats": {
8701
+ "ie": {
8702
+ "5.5": "n",
8703
+ "6": "n",
8704
+ "7": "n",
8705
+ "8": "n",
8706
+ "9": "n",
8707
+ "10": "n",
8708
+ "11": "y"
8709
+ },
8710
+ "firefox": {
8711
+ "2": "n",
8712
+ "3": "n",
8713
+ "3.5": "a x",
8714
+ "3.6": "a x",
8715
+ "4": "a x",
8716
+ "5": "a x",
8717
+ "6": "a x",
8718
+ "7": "a x",
8719
+ "8": "a x",
8720
+ "9": "a x",
8721
+ "10": "a x",
8722
+ "11": "a x",
8723
+ "12": "a x",
8724
+ "13": "a x",
8725
+ "14": "a x",
8726
+ "15": "y",
8727
+ "16": "y",
8728
+ "17": "y",
8729
+ "18": "y",
8730
+ "19": "y",
8731
+ "20": "y",
8732
+ "21": "y",
8733
+ "22": "y",
8734
+ "23": "y",
8735
+ "24": "y",
8736
+ "25": "y",
8737
+ "26": "y",
8738
+ "27": "y"
8739
+ },
8740
+ "chrome": {
8741
+ "4": "a x",
8742
+ "5": "a x",
8743
+ "6": "a x",
8744
+ "7": "a x",
8745
+ "8": "a x",
8746
+ "9": "a x",
8747
+ "10": "a x",
8748
+ "11": "a x",
8749
+ "12": "a x",
8750
+ "13": "a x",
8751
+ "14": "a x",
8752
+ "15": "y x",
8753
+ "16": "y",
8754
+ "17": "y",
8755
+ "18": "y",
8756
+ "19": "y",
8757
+ "20": "y",
8758
+ "21": "y",
8759
+ "22": "y",
8760
+ "23": "y",
8761
+ "24": "y",
8762
+ "25": "y",
8763
+ "26": "y",
8764
+ "27": "y",
8765
+ "28": "y",
8766
+ "29": "y",
8767
+ "30": "y",
8768
+ "31": "y",
8769
+ "32": "y"
8770
+ },
8771
+ "safari": {
8772
+ "3.1": "a x",
8773
+ "3.2": "a x",
8774
+ "4": "a x",
8775
+ "5": "a x",
8776
+ "5.1": "a x",
8777
+ "6": "y",
8778
+ "6.1": "y",
8779
+ "7": "y"
8780
+ },
8781
+ "opera": {
8782
+ "9": "n",
8783
+ "9.5-9.6": "n",
8784
+ "10.0-10.1": "n",
8785
+ "10.5": "a",
8786
+ "10.6": "a",
8787
+ "11": "a x",
8788
+ "11.1": "a x",
8789
+ "11.5": "a x",
8790
+ "11.6": "a x",
8791
+ "12": "a x",
8792
+ "12.1": "a x",
8793
+ "15": "y",
8794
+ "16": "y",
8795
+ "17": "y",
8796
+ "18": "y"
8797
+ },
8798
+ "ios_saf": {
8799
+ "3.2": "a x",
8800
+ "4.0-4.1": "a x",
8801
+ "4.2-4.3": "a x",
8802
+ "5.0-5.1": "a x",
8803
+ "6.0-6.1": "y",
8804
+ "7.0": "y"
8805
+ },
8806
+ "op_mini": {
8807
+ "5.0-7.0": "n"
8808
+ },
8809
+ "android": {
8810
+ "2.1": "a x",
8811
+ "2.2": "a x",
8812
+ "2.3": "a x",
8813
+ "3": "a x",
8814
+ "4": "a x",
8815
+ "4.1": "a x",
8816
+ "4.2-4.3": "a x",
8817
+ "4.4": "y"
8818
+ },
8819
+ "bb": {
8820
+ "7": "a x",
8821
+ "10": "y"
8822
+ },
8823
+ "op_mob": {
8824
+ "10": "n",
8825
+ "11": "a x",
8826
+ "11.1": "a x",
8827
+ "11.5": "a x",
8828
+ "12": "a x",
8829
+ "12.1": "a x",
8830
+ "0": "y"
8831
+ },
8832
+ "and_chr": {
8833
+ "0": "y"
8834
+ },
8835
+ "and_ff": {
8836
+ "0": "y"
8837
+ },
8838
+ "ie_mob": {
8839
+ "10": "n"
8840
+ }
8841
+ },
8842
+ "notes": "In Firefox both the border-style and border-width must be specified for border-images to work. Partial support refers to supporting the shorthand syntax, but not the individual properties (border-image-source, border-image-slice, etc).",
8843
+ "usage_perc_y": 54.86,
8844
+ "usage_perc_a": 9.76,
8845
+ "ucprefix": false,
8846
+ "parent": "",
8847
+ "keywords": ""
8848
+ },
8849
+ "background-img-opts": {
8850
+ "title": "CSS3 Background-image options",
8851
+ "description": "New properties to affect background images, including background-clip, background-origin and background-size",
8852
+ "spec": "http://www.w3.org/TR/css3-background/#backgrounds",
8853
+ "status": "cr",
8854
+ "links": [{
8855
+ "url": "https://github.com/louisremi/background-size-polyfill",
8856
+ "title": "Polyfill for IE7-8"
8857
+ }, {
8858
+ "url": "http://www.standardista.com/css3/css3-background-properties",
8859
+ "title": "Detailed compatibility tables and demos"
8860
+ }, {
8861
+ "url": "http://www.css3files.com/background/",
8862
+ "title": "Information page"
8863
+ }],
8864
+ "categories": ["CSS3"],
8865
+ "stats": {
8866
+ "ie": {
8867
+ "5.5": "n",
8868
+ "6": "n",
8869
+ "7": "n",
8870
+ "8": "n",
8871
+ "9": "y",
8872
+ "10": "y",
8873
+ "11": "y"
8874
+ },
8875
+ "firefox": {
8876
+ "2": "n",
8877
+ "3": "n",
8878
+ "3.5": "n",
8879
+ "3.6": "a x",
8880
+ "4": "y",
8881
+ "5": "y",
8882
+ "6": "y",
8883
+ "7": "y",
8884
+ "8": "y",
8885
+ "9": "y",
8886
+ "10": "y",
8887
+ "11": "y",
8888
+ "12": "y",
8889
+ "13": "y",
8890
+ "14": "y",
8891
+ "15": "y",
8892
+ "16": "y",
8893
+ "17": "y",
8894
+ "18": "y",
8895
+ "19": "y",
8896
+ "20": "y",
8897
+ "21": "y",
8898
+ "22": "y",
8899
+ "23": "y",
8900
+ "24": "y",
8901
+ "25": "y",
8902
+ "26": "y",
8903
+ "27": "y"
8904
+ },
8905
+ "chrome": {
8906
+ "4": "y",
8907
+ "5": "y",
8908
+ "6": "y",
8909
+ "7": "y",
8910
+ "8": "y",
8911
+ "9": "y",
8912
+ "10": "y",
8913
+ "11": "y",
8914
+ "12": "y",
8915
+ "13": "y",
8916
+ "14": "y",
8917
+ "15": "y",
8918
+ "16": "y",
8919
+ "17": "y",
8920
+ "18": "y",
8921
+ "19": "y",
8922
+ "20": "y",
8923
+ "21": "y",
8924
+ "22": "y",
8925
+ "23": "y",
8926
+ "24": "y",
8927
+ "25": "y",
8928
+ "26": "y",
8929
+ "27": "y",
8930
+ "28": "y",
8931
+ "29": "y",
8932
+ "30": "y",
8933
+ "31": "y",
8934
+ "32": "y"
8935
+ },
8936
+ "safari": {
8937
+ "3.1": "a",
8938
+ "3.2": "a",
8939
+ "4": "a",
8940
+ "5": "y",
8941
+ "5.1": "y",
8942
+ "6": "a",
8943
+ "6.1": "a",
8944
+ "7": "a"
8945
+ },
8946
+ "opera": {
8947
+ "9": "n",
8948
+ "9.5-9.6": "n",
8949
+ "10.0-10.1": "a x",
8950
+ "10.5": "y",
8951
+ "10.6": "y",
8952
+ "11": "y",
8953
+ "11.1": "y",
8954
+ "11.5": "y",
8955
+ "11.6": "y",
8956
+ "12": "y",
8957
+ "12.1": "y",
8958
+ "15": "y",
8959
+ "16": "y",
8960
+ "17": "y",
8961
+ "18": "y"
8962
+ },
8963
+ "ios_saf": {
8964
+ "3.2": "a",
8965
+ "4.0-4.1": "y",
8966
+ "4.2-4.3": "y",
8967
+ "5.0-5.1": "y",
8968
+ "6.0-6.1": "y",
8969
+ "7.0": "y"
8970
+ },
8971
+ "op_mini": {
8972
+ "5.0-7.0": "a"
8973
+ },
8974
+ "android": {
8975
+ "2.1": "a x",
8976
+ "2.2": "y x",
8977
+ "2.3": "y x",
8978
+ "3": "y",
8979
+ "4": "y",
8980
+ "4.1": "y",
8981
+ "4.2-4.3": "y",
8982
+ "4.4": "y"
8983
+ },
8984
+ "bb": {
8985
+ "7": "y",
8986
+ "10": "y"
8987
+ },
8988
+ "op_mob": {
8989
+ "10": "y",
8990
+ "11": "y",
8991
+ "11.1": "y",
8992
+ "11.5": "y",
8993
+ "12": "y",
8994
+ "12.1": "y",
8995
+ "0": "y"
8996
+ },
8997
+ "and_chr": {
8998
+ "0": "y"
8999
+ },
9000
+ "and_ff": {
9001
+ "0": "y"
9002
+ },
9003
+ "ie_mob": {
9004
+ "10": "y"
9005
+ }
9006
+ },
9007
+ "notes": "Partial support in Opera Mini refers to not supporting background sizing or background attachments. Partial support in Safari 6 refers to not supporting background sizing offset from edges syntax.",
9008
+ "usage_perc_y": 78.07,
9009
+ "usage_perc_a": 7.32,
9010
+ "ucprefix": false,
9011
+ "parent": "",
9012
+ "keywords": ""
9013
+ },
9014
+ "css-table": {
9015
+ "title": "CSS Table display",
9016
+ "description": "Method of displaying elements as tables, rows, and cells",
9017
+ "spec": "http://www.w3.org/TR/CSS21/tables.html",
9018
+ "status": "rec",
9019
+ "links": [{
9020
+ "url": "http://blog.12spokes.com/web-design-development/when-to-choose-between-the-html-table-element-and-css-displaytable-property/",
9021
+ "title": "Deciding on HTML or CSS tables"
9022
+ }, {
9023
+ "url": "http://www.onenaught.com/posts/201/use-css-displaytable-for-layout",
9024
+ "title": "Blog post on usage"
9025
+ }],
9026
+ "categories": ["CSS2"],
9027
+ "stats": {
9028
+ "ie": {
9029
+ "5.5": "n",
9030
+ "6": "n",
9031
+ "7": "n",
9032
+ "8": "y",
9033
+ "9": "y",
9034
+ "10": "y",
9035
+ "11": "y"
9036
+ },
9037
+ "firefox": {
9038
+ "2": "y",
9039
+ "3": "y",
9040
+ "3.5": "y",
9041
+ "3.6": "y",
9042
+ "4": "y",
9043
+ "5": "y",
9044
+ "6": "y",
9045
+ "7": "y",
9046
+ "8": "y",
9047
+ "9": "y",
9048
+ "10": "y",
9049
+ "11": "y",
9050
+ "12": "y",
9051
+ "13": "y",
9052
+ "14": "y",
9053
+ "15": "y",
9054
+ "16": "y",
9055
+ "17": "y",
9056
+ "18": "y",
9057
+ "19": "y",
9058
+ "20": "y",
9059
+ "21": "y",
9060
+ "22": "y",
9061
+ "23": "y",
9062
+ "24": "y",
9063
+ "25": "y",
9064
+ "26": "y",
9065
+ "27": "y"
9066
+ },
9067
+ "chrome": {
9068
+ "4": "y",
9069
+ "5": "y",
9070
+ "6": "y",
9071
+ "7": "y",
9072
+ "8": "y",
9073
+ "9": "y",
9074
+ "10": "y",
9075
+ "11": "y",
9076
+ "12": "y",
9077
+ "13": "y",
9078
+ "14": "y",
9079
+ "15": "y",
9080
+ "16": "y",
9081
+ "17": "y",
9082
+ "18": "y",
9083
+ "19": "y",
9084
+ "20": "y",
9085
+ "21": "y",
9086
+ "22": "y",
9087
+ "23": "y",
9088
+ "24": "y",
9089
+ "25": "y",
9090
+ "26": "y",
9091
+ "27": "y",
9092
+ "28": "y",
9093
+ "29": "y",
9094
+ "30": "y",
9095
+ "31": "y",
9096
+ "32": "y"
9097
+ },
9098
+ "safari": {
9099
+ "3.1": "y",
9100
+ "3.2": "y",
9101
+ "4": "y",
9102
+ "5": "y",
9103
+ "5.1": "y",
9104
+ "6": "y",
9105
+ "6.1": "y",
9106
+ "7": "y"
9107
+ },
9108
+ "opera": {
9109
+ "9": "y",
9110
+ "9.5-9.6": "y",
9111
+ "10.0-10.1": "y",
9112
+ "10.5": "y",
9113
+ "10.6": "y",
9114
+ "11": "y",
9115
+ "11.1": "y",
9116
+ "11.5": "y",
9117
+ "11.6": "y",
9118
+ "12": "y",
9119
+ "12.1": "y",
9120
+ "15": "y",
9121
+ "16": "y",
9122
+ "17": "y",
9123
+ "18": "y"
9124
+ },
9125
+ "ios_saf": {
9126
+ "3.2": "y",
9127
+ "4.0-4.1": "y",
9128
+ "4.2-4.3": "y",
9129
+ "5.0-5.1": "y",
9130
+ "6.0-6.1": "y",
9131
+ "7.0": "y"
9132
+ },
9133
+ "op_mini": {
9134
+ "5.0-7.0": "y"
9135
+ },
9136
+ "android": {
9137
+ "2.1": "y",
9138
+ "2.2": "y",
9139
+ "2.3": "y",
9140
+ "3": "y",
9141
+ "4": "y",
9142
+ "4.1": "y",
9143
+ "4.2-4.3": "y",
9144
+ "4.4": "y"
9145
+ },
9146
+ "bb": {
9147
+ "7": "y",
9148
+ "10": "y"
9149
+ },
9150
+ "op_mob": {
9151
+ "10": "y",
9152
+ "11": "y",
9153
+ "11.1": "y",
9154
+ "11.5": "y",
9155
+ "12": "y",
9156
+ "12.1": "y",
9157
+ "0": "y"
9158
+ },
9159
+ "and_chr": {
9160
+ "0": "y"
9161
+ },
9162
+ "and_ff": {
9163
+ "0": "y"
9164
+ },
9165
+ "ie_mob": {
9166
+ "10": "y"
9167
+ }
9168
+ },
9169
+ "notes": "",
9170
+ "usage_perc_y": 93.86,
9171
+ "usage_perc_a": 0,
9172
+ "ucprefix": false,
9173
+ "parent": "",
9174
+ "keywords": "display:table, display: table,table-cell,table-row,table-layout"
9175
+ },
9176
+ "css-gencontent": {
9177
+ "title": "CSS Generated content",
9178
+ "description": "Method of displaying text or images before or after the given element's contents using the :before and :after pseudo-elements",
9179
+ "spec": "http://www.w3.org/TR/CSS21/generate.html",
9180
+ "status": "rec",
9181
+ "links": [{
9182
+ "url": "http://www.westciv.com/style_master/academy/css_tutorial/advanced/generated_content.html",
9183
+ "title": "Guide on usage"
9184
+ }, {
9185
+ "url": "http://docs.webplatform.org/wiki/css/generated_and_replaced_content",
9186
+ "title": "WebPlatform Docs"
9187
+ }, {
9188
+ "url": "http://dev.opera.com/articles/view/css-generated-content-techniques/",
9189
+ "title": "Dev.Opera article"
9190
+ }],
9191
+ "categories": ["CSS2", "CSS3"],
9192
+ "stats": {
9193
+ "ie": {
9194
+ "5.5": "n",
9195
+ "6": "n",
9196
+ "7": "n",
9197
+ "8": "a",
9198
+ "9": "y",
9199
+ "10": "y",
9200
+ "11": "y"
9201
+ },
9202
+ "firefox": {
9203
+ "2": "y",
9204
+ "3": "y",
9205
+ "3.5": "y",
9206
+ "3.6": "y",
9207
+ "4": "y",
9208
+ "5": "y",
9209
+ "6": "y",
9210
+ "7": "y",
9211
+ "8": "y",
9212
+ "9": "y",
9213
+ "10": "y",
9214
+ "11": "y",
9215
+ "12": "y",
9216
+ "13": "y",
9217
+ "14": "y",
9218
+ "15": "y",
9219
+ "16": "y",
9220
+ "17": "y",
9221
+ "18": "y",
9222
+ "19": "y",
9223
+ "20": "y",
9224
+ "21": "y",
9225
+ "22": "y",
9226
+ "23": "y",
9227
+ "24": "y",
9228
+ "25": "y",
9229
+ "26": "y",
9230
+ "27": "y"
9231
+ },
9232
+ "chrome": {
9233
+ "4": "y",
9234
+ "5": "y",
9235
+ "6": "y",
9236
+ "7": "y",
9237
+ "8": "y",
9238
+ "9": "y",
9239
+ "10": "y",
9240
+ "11": "y",
9241
+ "12": "y",
9242
+ "13": "y",
9243
+ "14": "y",
9244
+ "15": "y",
9245
+ "16": "y",
9246
+ "17": "y",
9247
+ "18": "y",
9248
+ "19": "y",
9249
+ "20": "y",
9250
+ "21": "y",
9251
+ "22": "y",
9252
+ "23": "y",
9253
+ "24": "y",
9254
+ "25": "y",
9255
+ "26": "y",
9256
+ "27": "y",
9257
+ "28": "y",
9258
+ "29": "y",
9259
+ "30": "y",
9260
+ "31": "y",
9261
+ "32": "y"
9262
+ },
9263
+ "safari": {
9264
+ "3.1": "y",
9265
+ "3.2": "y",
9266
+ "4": "y",
9267
+ "5": "y",
9268
+ "5.1": "y",
9269
+ "6": "y",
9270
+ "6.1": "y",
9271
+ "7": "y"
9272
+ },
9273
+ "opera": {
9274
+ "9": "y",
9275
+ "9.5-9.6": "y",
9276
+ "10.0-10.1": "y",
9277
+ "10.5": "y",
9278
+ "10.6": "y",
9279
+ "11": "y",
9280
+ "11.1": "y",
9281
+ "11.5": "y",
9282
+ "11.6": "y",
9283
+ "12": "y",
9284
+ "12.1": "y",
9285
+ "15": "y",
9286
+ "16": "y",
9287
+ "17": "y",
9288
+ "18": "y"
9289
+ },
9290
+ "ios_saf": {
9291
+ "3.2": "y",
9292
+ "4.0-4.1": "y",
9293
+ "4.2-4.3": "y",
9294
+ "5.0-5.1": "y",
9295
+ "6.0-6.1": "y",
9296
+ "7.0": "y"
9297
+ },
9298
+ "op_mini": {
9299
+ "5.0-7.0": "y"
9300
+ },
9301
+ "android": {
9302
+ "2.1": "y",
9303
+ "2.2": "y",
9304
+ "2.3": "y",
9305
+ "3": "y",
9306
+ "4": "y",
9307
+ "4.1": "y",
9308
+ "4.2-4.3": "y",
9309
+ "4.4": "y"
9310
+ },
9311
+ "bb": {
9312
+ "7": "y",
9313
+ "10": "y"
9314
+ },
9315
+ "op_mob": {
9316
+ "10": "y",
9317
+ "11": "y",
9318
+ "11.1": "y",
9319
+ "11.5": "y",
9320
+ "12": "y",
9321
+ "12.1": "y",
9322
+ "0": "y"
9323
+ },
9324
+ "and_chr": {
9325
+ "0": "y"
9326
+ },
9327
+ "and_ff": {
9328
+ "0": "y"
9329
+ },
9330
+ "ie_mob": {
9331
+ "10": "y"
9332
+ }
9333
+ },
9334
+ "notes": "IE8 only supports the single-colon CSS 2.1 syntax (i.e. pseudo-class). It does not support the double-colon CSS3 syntax (i.e. pseudo-element)",
9335
+ "usage_perc_y": 85.55,
9336
+ "usage_perc_a": 8.31,
9337
+ "ucprefix": false,
9338
+ "parent": "",
9339
+ "keywords": "before,after"
9340
+ },
9341
+ "css-fixed": {
9342
+ "title": "CSS position:fixed",
9343
+ "description": "Method of keeping an element in a fixed location regardless of scroll position",
9344
+ "spec": "http://www.w3.org/TR/CSS21/visuren.html#fixed-positioning",
9345
+ "status": "rec",
9346
+ "links": [{
9347
+ "url": "http://www.css-101.org/fixed-positioning/05.php",
9348
+ "title": "Workaround for IE6"
9349
+ }, {
9350
+ "url": "http://bradfrostweb.com/blog/mobile/fixed-position/",
9351
+ "title": "Article on mobile support"
9352
+ }, {
9353
+ "url": "http://docs.webplatform.org/wiki/css/properties/position",
9354
+ "title": "WebPlatform Docs"
9355
+ }],
9356
+ "categories": ["CSS"],
9357
+ "stats": {
9358
+ "ie": {
9359
+ "5.5": "n",
9360
+ "6": "p",
9361
+ "7": "y",
9362
+ "8": "y",
9363
+ "9": "y",
9364
+ "10": "y",
9365
+ "11": "y"
9366
+ },
9367
+ "firefox": {
9368
+ "2": "y",
9369
+ "3": "y",
9370
+ "3.5": "y",
9371
+ "3.6": "y",
9372
+ "4": "y",
9373
+ "5": "y",
9374
+ "6": "y",
9375
+ "7": "y",
9376
+ "8": "y",
9377
+ "9": "y",
9378
+ "10": "y",
9379
+ "11": "y",
9380
+ "12": "y",
9381
+ "13": "y",
9382
+ "14": "y",
9383
+ "15": "y",
9384
+ "16": "y",
9385
+ "17": "y",
9386
+ "18": "y",
9387
+ "19": "y",
9388
+ "20": "y",
9389
+ "21": "y",
9390
+ "22": "y",
9391
+ "23": "y",
9392
+ "24": "y",
9393
+ "25": "y",
9394
+ "26": "y",
9395
+ "27": "y"
9396
+ },
9397
+ "chrome": {
9398
+ "4": "y",
9399
+ "5": "y",
9400
+ "6": "y",
9401
+ "7": "y",
9402
+ "8": "y",
9403
+ "9": "y",
9404
+ "10": "y",
9405
+ "11": "y",
9406
+ "12": "y",
9407
+ "13": "y",
9408
+ "14": "y",
9409
+ "15": "y",
9410
+ "16": "y",
9411
+ "17": "y",
9412
+ "18": "y",
9413
+ "19": "y",
9414
+ "20": "y",
9415
+ "21": "y",
9416
+ "22": "y",
9417
+ "23": "y",
9418
+ "24": "y",
9419
+ "25": "y",
9420
+ "26": "y",
9421
+ "27": "y",
9422
+ "28": "y",
9423
+ "29": "y",
9424
+ "30": "y",
9425
+ "31": "y",
9426
+ "32": "y"
9427
+ },
9428
+ "safari": {
9429
+ "3.1": "y",
9430
+ "3.2": "y",
9431
+ "4": "y",
9432
+ "5": "y",
9433
+ "5.1": "y",
9434
+ "6": "y",
9435
+ "6.1": "y",
9436
+ "7": "y"
9437
+ },
9438
+ "opera": {
9439
+ "9": "y",
9440
+ "9.5-9.6": "y",
9441
+ "10.0-10.1": "y",
9442
+ "10.5": "y",
9443
+ "10.6": "y",
9444
+ "11": "y",
9445
+ "11.1": "y",
9446
+ "11.5": "y",
9447
+ "11.6": "y",
9448
+ "12": "y",
9449
+ "12.1": "y",
9450
+ "15": "y",
9451
+ "16": "y",
9452
+ "17": "y",
9453
+ "18": "y"
9454
+ },
9455
+ "ios_saf": {
9456
+ "3.2": "n",
9457
+ "4.0-4.1": "n",
9458
+ "4.2-4.3": "n",
9459
+ "5.0-5.1": "a",
9460
+ "6.0-6.1": "a",
9461
+ "7.0": "a"
9462
+ },
9463
+ "op_mini": {
9464
+ "5.0-7.0": "n"
9465
+ },
9466
+ "android": {
9467
+ "2.1": "a",
9468
+ "2.2": "a",
9469
+ "2.3": "a",
9470
+ "3": "y",
9471
+ "4": "y",
9472
+ "4.1": "y",
9473
+ "4.2-4.3": "y",
9474
+ "4.4": "y"
9475
+ },
9476
+ "bb": {
9477
+ "7": "y",
9478
+ "10": "y"
9479
+ },
9480
+ "op_mob": {
9481
+ "10": "y",
9482
+ "11": "y",
9483
+ "11.1": "y",
9484
+ "11.5": "y",
9485
+ "12": "y",
9486
+ "12.1": "y",
9487
+ "0": "y"
9488
+ },
9489
+ "and_chr": {
9490
+ "0": "y"
9491
+ },
9492
+ "and_ff": {
9493
+ "0": "y"
9494
+ },
9495
+ "ie_mob": {
9496
+ "10": "y"
9497
+ }
9498
+ },
9499
+ "notes": "Only works in Android 2.2+ by using the following meta tag: &lt;meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">. Partial support in iOS Safari refers to <a href=\"http://remysharp.com/2012/05/24/issues-with-position-fixed-scrolling-on-ios/\">buggy behavior</a>.",
9500
+ "usage_perc_y": 84.35,
9501
+ "usage_perc_a": 5.39,
9502
+ "ucprefix": false,
9503
+ "parent": "",
9504
+ "keywords": ""
9505
+ },
9506
+ "hashchange": {
9507
+ "title": "Hashchange event",
9508
+ "description": "Event triggered in JavaScript when the URL's hash has changed (for example: page.html#foo to page.html#bar) ",
9509
+ "spec": "http://www.w3.org/TR/html5/history.html#event-hashchange",
9510
+ "status": "cr",
9511
+ "links": [{
9512
+ "url": "http://www.quirksmode.org/dom/events/tests/hashchange.html",
9513
+ "title": "Simple demo"
9514
+ }, {
9515
+ "url": "http://docs.webplatform.org/wiki/dom/events/hashchange",
9516
+ "title": "WebPlatform Docs"
9517
+ }, {
9518
+ "url": "https://developer.mozilla.org/en/DOM/window.onhashchange",
9519
+ "title": "MDN article"
9520
+ }, {
9521
+ "url": "http://github.com/3nr1c/jUri.js",
9522
+ "title": "Polyfill"
9523
+ }, {
9524
+ "url": "http://msdn.microsoft.com/en-us/library/cc288209(VS.85).aspx",
9525
+ "title": "MSDN article"
9526
+ }],
9527
+ "categories": ["HTML5", "JS API"],
9528
+ "stats": {
9529
+ "ie": {
9530
+ "5.5": "p",
9531
+ "6": "p",
9532
+ "7": "p",
9533
+ "8": "y",
9534
+ "9": "y",
9535
+ "10": "y",
9536
+ "11": "y"
9537
+ },
9538
+ "firefox": {
9539
+ "2": "p",
9540
+ "3": "p",
9541
+ "3.5": "p",
9542
+ "3.6": "y",
9543
+ "4": "y",
9544
+ "5": "y",
9545
+ "6": "y",
9546
+ "7": "y",
9547
+ "8": "y",
9548
+ "9": "y",
9549
+ "10": "y",
9550
+ "11": "y",
9551
+ "12": "y",
9552
+ "13": "y",
9553
+ "14": "y",
9554
+ "15": "y",
9555
+ "16": "y",
9556
+ "17": "y",
9557
+ "18": "y",
9558
+ "19": "y",
9559
+ "20": "y",
9560
+ "21": "y",
9561
+ "22": "y",
9562
+ "23": "y",
9563
+ "24": "y",
9564
+ "25": "y",
9565
+ "26": "y",
9566
+ "27": "y"
9567
+ },
9568
+ "chrome": {
9569
+ "4": "p",
9570
+ "5": "y",
9571
+ "6": "y",
9572
+ "7": "y",
9573
+ "8": "y",
9574
+ "9": "y",
9575
+ "10": "y",
9576
+ "11": "y",
9577
+ "12": "y",
9578
+ "13": "y",
9579
+ "14": "y",
9580
+ "15": "y",
9581
+ "16": "y",
9582
+ "17": "y",
9583
+ "18": "y",
9584
+ "19": "y",
9585
+ "20": "y",
9586
+ "21": "y",
9587
+ "22": "y",
9588
+ "23": "y",
9589
+ "24": "y",
9590
+ "25": "y",
9591
+ "26": "y",
9592
+ "27": "y",
9593
+ "28": "y",
9594
+ "29": "y",
9595
+ "30": "y",
9596
+ "31": "y",
9597
+ "32": "y"
9598
+ },
9599
+ "safari": {
9600
+ "3.1": "p",
9601
+ "3.2": "p",
9602
+ "4": "p",
9603
+ "5": "y",
9604
+ "5.1": "y",
9605
+ "6": "y",
9606
+ "6.1": "y",
9607
+ "7": "y"
9608
+ },
9609
+ "opera": {
9610
+ "9": "p",
9611
+ "9.5-9.6": "p",
9612
+ "10.0-10.1": "p",
9613
+ "10.5": "p",
9614
+ "10.6": "y",
9615
+ "11": "y",
9616
+ "11.1": "y",
9617
+ "11.5": "y",
9618
+ "11.6": "y",
9619
+ "12": "y",
9620
+ "12.1": "y",
9621
+ "15": "y",
9622
+ "16": "y",
9623
+ "17": "y",
9624
+ "18": "y"
9625
+ },
9626
+ "ios_saf": {
9627
+ "3.2": "n",
9628
+ "4.0-4.1": "y",
9629
+ "4.2-4.3": "y",
9630
+ "5.0-5.1": "y",
9631
+ "6.0-6.1": "y",
9632
+ "7.0": "y"
9633
+ },
9634
+ "op_mini": {
9635
+ "5.0-7.0": "n"
9636
+ },
9637
+ "android": {
9638
+ "2.1": "n",
9639
+ "2.2": "y",
9640
+ "2.3": "y",
9641
+ "3": "y",
9642
+ "4": "y",
9643
+ "4.1": "y",
9644
+ "4.2-4.3": "y",
9645
+ "4.4": "y"
9646
+ },
9647
+ "bb": {
9648
+ "7": "y",
9649
+ "10": "y"
9650
+ },
9651
+ "op_mob": {
9652
+ "10": "p",
9653
+ "11": "y",
9654
+ "11.1": "y",
9655
+ "11.5": "y",
9656
+ "12": "y",
9657
+ "12.1": "y",
9658
+ "0": "y"
9659
+ },
9660
+ "and_chr": {
9661
+ "0": "y"
9662
+ },
9663
+ "and_ff": {
9664
+ "0": "y"
9665
+ },
9666
+ "ie_mob": {
9667
+ "10": "y"
9668
+ }
9669
+ },
9670
+ "notes": "",
9671
+ "usage_perc_y": 88.92,
9672
+ "usage_perc_a": 0,
9673
+ "ucprefix": false,
9674
+ "parent": "",
9675
+ "keywords": "onhashchange,HashChangeEvent"
9676
+ },
9677
+ "css-sel2": {
9678
+ "title": "CSS 2.1 selectors",
9679
+ "description": "Allows more accurate element selecting, using >, +, [attr], :first-child, etc.",
9680
+ "spec": "http://www.w3.org/TR/CSS21/selector.html",
9681
+ "status": "rec",
9682
+ "links": [{
9683
+ "url": "http://www.quirksmode.org/css/contents.html",
9684
+ "title": "Detailed support information"
9685
+ }, {
9686
+ "url": "http://docs.webplatform.org/wiki/css/selectors",
9687
+ "title": "WebPlatform Docs"
9688
+ }, {
9689
+ "url": "http://selectivizr.com",
9690
+ "title": "Selectivizr: Polyfill for IE6-8"
9691
+ }, {
9692
+ "url": "http://www.yourhtmlsource.com/stylesheets/advancedselectors.html",
9693
+ "title": "Examples of advanced selectors"
9694
+ }],
9695
+ "categories": ["CSS2"],
9696
+ "stats": {
9697
+ "ie": {
9698
+ "5.5": "n",
9699
+ "6": "p",
9700
+ "7": "y",
9701
+ "8": "y",
9702
+ "9": "y",
9703
+ "10": "y",
9704
+ "11": "y"
9705
+ },
9706
+ "firefox": {
9707
+ "2": "y",
9708
+ "3": "y",
9709
+ "3.5": "y",
9710
+ "3.6": "y",
9711
+ "4": "y",
9712
+ "5": "y",
9713
+ "6": "y",
9714
+ "7": "y",
9715
+ "8": "y",
9716
+ "9": "y",
9717
+ "10": "y",
9718
+ "11": "y",
9719
+ "12": "y",
9720
+ "13": "y",
9721
+ "14": "y",
9722
+ "15": "y",
9723
+ "16": "y",
9724
+ "17": "y",
9725
+ "18": "y",
9726
+ "19": "y",
9727
+ "20": "y",
9728
+ "21": "y",
9729
+ "22": "y",
9730
+ "23": "y",
9731
+ "24": "y",
9732
+ "25": "y",
9733
+ "26": "y",
9734
+ "27": "y"
9735
+ },
9736
+ "chrome": {
9737
+ "4": "y",
9738
+ "5": "y",
9739
+ "6": "y",
9740
+ "7": "y",
9741
+ "8": "y",
9742
+ "9": "y",
9743
+ "10": "y",
9744
+ "11": "y",
9745
+ "12": "y",
9746
+ "13": "y",
9747
+ "14": "y",
9748
+ "15": "y",
9749
+ "16": "y",
9750
+ "17": "y",
9751
+ "18": "y",
9752
+ "19": "y",
9753
+ "20": "y",
9754
+ "21": "y",
9755
+ "22": "y",
9756
+ "23": "y",
9757
+ "24": "y",
9758
+ "25": "y",
9759
+ "26": "y",
9760
+ "27": "y",
9761
+ "28": "y",
9762
+ "29": "y",
9763
+ "30": "y",
9764
+ "31": "y",
9765
+ "32": "y"
9766
+ },
9767
+ "safari": {
9768
+ "3.1": "y",
9769
+ "3.2": "y",
9770
+ "4": "y",
9771
+ "5": "y",
9772
+ "5.1": "y",
9773
+ "6": "y",
9774
+ "6.1": "y",
9775
+ "7": "y"
9776
+ },
9777
+ "opera": {
9778
+ "9": "y",
9779
+ "9.5-9.6": "y",
9780
+ "10.0-10.1": "y",
9781
+ "10.5": "y",
9782
+ "10.6": "y",
9783
+ "11": "y",
9784
+ "11.1": "y",
9785
+ "11.5": "y",
9786
+ "11.6": "y",
9787
+ "12": "y",
9788
+ "12.1": "y",
9789
+ "15": "y",
9790
+ "16": "y",
9791
+ "17": "y",
9792
+ "18": "y"
9793
+ },
9794
+ "ios_saf": {
9795
+ "3.2": "y",
9796
+ "4.0-4.1": "y",
9797
+ "4.2-4.3": "y",
9798
+ "5.0-5.1": "y",
9799
+ "6.0-6.1": "y",
9800
+ "7.0": "y"
9801
+ },
9802
+ "op_mini": {
9803
+ "5.0-7.0": "y"
9804
+ },
9805
+ "android": {
9806
+ "2.1": "y",
9807
+ "2.2": "y",
9808
+ "2.3": "y",
9809
+ "3": "y",
9810
+ "4": "y",
9811
+ "4.1": "y",
9812
+ "4.2-4.3": "y",
9813
+ "4.4": "y"
9814
+ },
9815
+ "bb": {
9816
+ "7": "y",
9817
+ "10": "y"
9818
+ },
9819
+ "op_mob": {
9820
+ "10": "y",
9821
+ "11": "y",
9822
+ "11.1": "y",
9823
+ "11.5": "y",
9824
+ "12": "y",
9825
+ "12.1": "y",
9826
+ "0": "y"
9827
+ },
9828
+ "and_chr": {
9829
+ "0": "y"
9830
+ },
9831
+ "and_ff": {
9832
+ "0": "y"
9833
+ },
9834
+ "ie_mob": {
9835
+ "10": "y"
9836
+ }
9837
+ },
9838
+ "notes": "",
9839
+ "usage_perc_y": 94.36,
9840
+ "usage_perc_a": 0,
9841
+ "ucprefix": false,
9842
+ "parent": "",
9843
+ "keywords": "child selector,:hover,adjacent,sibling,adjacent sibling"
9844
+ },
9845
+ "css-sel3": {
9846
+ "title": "CSS3 selectors",
9847
+ "description": "Advanced element selection using selectors like :nth-child(), :last-child, :first-of-type, etc.",
9848
+ "spec": "http://www.w3.org/TR/css3-selectors/",
9849
+ "status": "rec",
9850
+ "links": [{
9851
+ "url": "http://www.css3.info/selectors-test/",
9852
+ "title": "Automated CSS3 selector test"
9853
+ }, {
9854
+ "url": "http://docs.webplatform.org/wiki/css/selectors",
9855
+ "title": "WebPlatform Docs"
9856
+ }, {
9857
+ "url": "http://www.quirksmode.org/css/contents.html",
9858
+ "title": "Detailed support information"
9859
+ }, {
9860
+ "url": "http://selectivizr.com",
9861
+ "title": "Selectivizr: Polyfill for IE6-8"
9862
+ }],
9863
+ "categories": ["CSS3"],
9864
+ "stats": {
9865
+ "ie": {
9866
+ "5.5": "n",
9867
+ "6": "p",
9868
+ "7": "p",
9869
+ "8": "p",
9870
+ "9": "y",
9871
+ "10": "y",
9872
+ "11": "y"
9873
+ },
9874
+ "firefox": {
9875
+ "2": "n",
9876
+ "3": "n",
9877
+ "3.5": "y",
9878
+ "3.6": "y",
9879
+ "4": "y",
9880
+ "5": "y",
9881
+ "6": "y",
9882
+ "7": "y",
9883
+ "8": "y",
9884
+ "9": "y",
9885
+ "10": "y",
9886
+ "11": "y",
9887
+ "12": "y",
9888
+ "13": "y",
9889
+ "14": "y",
9890
+ "15": "y",
9891
+ "16": "y",
9892
+ "17": "y",
9893
+ "18": "y",
9894
+ "19": "y",
9895
+ "20": "y",
9896
+ "21": "y",
9897
+ "22": "y",
9898
+ "23": "y",
9899
+ "24": "y",
9900
+ "25": "y",
9901
+ "26": "y",
9902
+ "27": "y"
9903
+ },
9904
+ "chrome": {
9905
+ "4": "y",
9906
+ "5": "y",
9907
+ "6": "y",
9908
+ "7": "y",
9909
+ "8": "y",
9910
+ "9": "y",
9911
+ "10": "y",
9912
+ "11": "y",
9913
+ "12": "y",
9914
+ "13": "y",
9915
+ "14": "y",
9916
+ "15": "y",
9917
+ "16": "y",
9918
+ "17": "y",
9919
+ "18": "y",
9920
+ "19": "y",
9921
+ "20": "y",
9922
+ "21": "y",
9923
+ "22": "y",
9924
+ "23": "y",
9925
+ "24": "y",
9926
+ "25": "y",
9927
+ "26": "y",
9928
+ "27": "y",
9929
+ "28": "y",
9930
+ "29": "y",
9931
+ "30": "y",
9932
+ "31": "y",
9933
+ "32": "y"
9934
+ },
9935
+ "safari": {
9936
+ "3.1": "n",
9937
+ "3.2": "y",
9938
+ "4": "y",
9939
+ "5": "y",
9940
+ "5.1": "y",
9941
+ "6": "y",
9942
+ "6.1": "y",
9943
+ "7": "y"
9944
+ },
9945
+ "opera": {
9946
+ "9": "n",
9947
+ "9.5-9.6": "y",
9948
+ "10.0-10.1": "y",
9949
+ "10.5": "y",
9950
+ "10.6": "y",
9951
+ "11": "y",
9952
+ "11.1": "y",
9953
+ "11.5": "y",
9954
+ "11.6": "y",
9955
+ "12": "y",
9956
+ "12.1": "y",
9957
+ "15": "y",
9958
+ "16": "y",
9959
+ "17": "y",
9960
+ "18": "y"
9961
+ },
9962
+ "ios_saf": {
9963
+ "3.2": "y",
9964
+ "4.0-4.1": "y",
9965
+ "4.2-4.3": "y",
9966
+ "5.0-5.1": "y",
9967
+ "6.0-6.1": "y",
9968
+ "7.0": "y"
9969
+ },
9970
+ "op_mini": {
9971
+ "5.0-7.0": "y"
9972
+ },
9973
+ "android": {
9974
+ "2.1": "y",
9975
+ "2.2": "y",
9976
+ "2.3": "y",
9977
+ "3": "y",
9978
+ "4": "y",
9979
+ "4.1": "y",
9980
+ "4.2-4.3": "y",
9981
+ "4.4": "y"
9982
+ },
9983
+ "bb": {
9984
+ "7": "y",
9985
+ "10": "y"
9986
+ },
9987
+ "op_mob": {
9988
+ "10": "y",
9989
+ "11": "y",
9990
+ "11.1": "y",
9991
+ "11.5": "y",
9992
+ "12": "y",
9993
+ "12.1": "y",
9994
+ "0": "y"
9995
+ },
9996
+ "and_chr": {
9997
+ "0": "y"
9998
+ },
9999
+ "and_ff": {
10000
+ "0": "y"
10001
+ },
10002
+ "ie_mob": {
10003
+ "10": "y"
10004
+ }
10005
+ },
10006
+ "notes": "",
10007
+ "usage_perc_y": 85.43,
10008
+ "usage_perc_a": 0,
10009
+ "ucprefix": false,
10010
+ "parent": "",
10011
+ "keywords": ":target,:not"
10012
+ },
10013
+ "css-textshadow": {
10014
+ "title": "CSS3 Text-shadow",
10015
+ "description": "Method of applying one or more shadow or blur effects to text",
10016
+ "spec": "http://www.w3.org/TR/css-text-decor-3/#text-shadow-property",
10017
+ "status": "wd",
10018
+ "links": [{
10019
+ "url": "http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_text-shadow.htm",
10020
+ "title": "Live editor"
10021
+ }, {
10022
+ "url": "http://docs.webplatform.org/wiki/css/properties/text-shadow",
10023
+ "title": "WebPlatform Docs"
10024
+ }, {
10025
+ "url": "http://hacks.mozilla.org/2009/06/text-shadow/",
10026
+ "title": "Mozilla hacks article"
10027
+ }, {
10028
+ "url": "http://www.css3files.com/shadow/#textshadow",
10029
+ "title": "Information page"
10030
+ }],
10031
+ "categories": ["CSS3"],
10032
+ "stats": {
10033
+ "ie": {
10034
+ "5.5": "n",
10035
+ "6": "n",
10036
+ "7": "n",
10037
+ "8": "n",
10038
+ "9": "n",
10039
+ "10": "y",
10040
+ "11": "y"
10041
+ },
10042
+ "firefox": {
10043
+ "2": "n",
10044
+ "3": "n",
10045
+ "3.5": "y",
10046
+ "3.6": "y",
10047
+ "4": "y",
10048
+ "5": "y",
10049
+ "6": "y",
10050
+ "7": "y",
10051
+ "8": "y",
10052
+ "9": "y",
10053
+ "10": "y",
10054
+ "11": "y",
10055
+ "12": "y",
10056
+ "13": "y",
10057
+ "14": "y",
10058
+ "15": "y",
10059
+ "16": "y",
10060
+ "17": "y",
10061
+ "18": "y",
10062
+ "19": "y",
10063
+ "20": "y",
10064
+ "21": "y",
10065
+ "22": "y",
10066
+ "23": "y",
10067
+ "24": "y",
10068
+ "25": "y",
10069
+ "26": "y",
10070
+ "27": "y"
10071
+ },
10072
+ "chrome": {
10073
+ "4": "y",
10074
+ "5": "y",
10075
+ "6": "y",
10076
+ "7": "y",
10077
+ "8": "y",
10078
+ "9": "y",
10079
+ "10": "y",
10080
+ "11": "y",
10081
+ "12": "y",
10082
+ "13": "y",
10083
+ "14": "y",
10084
+ "15": "y",
10085
+ "16": "y",
10086
+ "17": "y",
10087
+ "18": "y",
10088
+ "19": "y",
10089
+ "20": "y",
10090
+ "21": "y",
10091
+ "22": "y",
10092
+ "23": "y",
10093
+ "24": "y",
10094
+ "25": "y",
10095
+ "26": "y",
10096
+ "27": "y",
10097
+ "28": "y",
10098
+ "29": "y",
10099
+ "30": "y",
10100
+ "31": "y",
10101
+ "32": "y"
10102
+ },
10103
+ "safari": {
10104
+ "3.1": "a",
10105
+ "3.2": "a",
10106
+ "4": "y",
10107
+ "5": "y",
10108
+ "5.1": "y",
10109
+ "6": "y",
10110
+ "6.1": "y",
10111
+ "7": "y"
10112
+ },
10113
+ "opera": {
10114
+ "9": "n",
10115
+ "9.5-9.6": "y",
10116
+ "10.0-10.1": "y",
10117
+ "10.5": "y",
10118
+ "10.6": "y",
10119
+ "11": "y",
10120
+ "11.1": "y",
10121
+ "11.5": "y",
10122
+ "11.6": "y",
10123
+ "12": "y",
10124
+ "12.1": "y",
10125
+ "15": "y",
10126
+ "16": "y",
10127
+ "17": "y",
10128
+ "18": "y"
10129
+ },
10130
+ "ios_saf": {
10131
+ "3.2": "y",
10132
+ "4.0-4.1": "y",
10133
+ "4.2-4.3": "y",
10134
+ "5.0-5.1": "y",
10135
+ "6.0-6.1": "y",
10136
+ "7.0": "y"
10137
+ },
10138
+ "op_mini": {
10139
+ "5.0-7.0": "a"
10140
+ },
10141
+ "android": {
10142
+ "2.1": "y",
10143
+ "2.2": "y",
10144
+ "2.3": "y",
10145
+ "3": "y",
10146
+ "4": "y",
10147
+ "4.1": "y",
10148
+ "4.2-4.3": "y",
10149
+ "4.4": "y"
10150
+ },
10151
+ "bb": {
10152
+ "7": "a",
10153
+ "10": "y"
10154
+ },
10155
+ "op_mob": {
10156
+ "10": "y",
10157
+ "11": "y",
10158
+ "11.1": "y",
10159
+ "11.5": "y",
10160
+ "12": "y",
10161
+ "12.1": "y",
10162
+ "0": "y"
10163
+ },
10164
+ "and_chr": {
10165
+ "0": "y"
10166
+ },
10167
+ "and_ff": {
10168
+ "0": "y"
10169
+ },
10170
+ "ie_mob": {
10171
+ "10": "y"
10172
+ }
10173
+ },
10174
+ "notes": "Opera Mini ignores the blur-radius set, so no blur effect is visible. Text-shadow behavior can be somewhat emulated in older IE versions using the non-standard \"dropshadow\" or \"glow\" filters. ",
10175
+ "usage_perc_y": 75.49,
10176
+ "usage_perc_a": 4.73,
10177
+ "ucprefix": false,
10178
+ "parent": "",
10179
+ "keywords": ""
10180
+ },
10181
+ "css-boxshadow": {
10182
+ "title": "CSS3 Box-shadow",
10183
+ "description": "Method of displaying an inner or outer shadow effect to elements",
10184
+ "spec": "http://www.w3.org/TR/css3-background/#box-shadow",
10185
+ "status": "cr",
10186
+ "links": [{
10187
+ "url": "http://www.css3files.com/shadow/",
10188
+ "title": "Information page"
10189
+ }, {
10190
+ "url": "https://developer.mozilla.org/En/CSS/-moz-box-shadow",
10191
+ "title": "MDN article"
10192
+ }, {
10193
+ "url": "http://westciv.com/tools/boxshadows/index.html",
10194
+ "title": "Live editor"
10195
+ }, {
10196
+ "url": "http://tests.themasta.com/blogstuff/boxshadowdemo.html",
10197
+ "title": "Demo of various effects"
10198
+ }, {
10199
+ "url": "http://docs.webplatform.org/wiki/css/properties/box-shadow",
10200
+ "title": "WebPlatform Docs"
10201
+ }],
10202
+ "categories": ["CSS3"],
10203
+ "stats": {
10204
+ "ie": {
10205
+ "5.5": "n",
10206
+ "6": "n",
10207
+ "7": "n",
10208
+ "8": "n",
10209
+ "9": "y",
10210
+ "10": "y",
10211
+ "11": "y"
10212
+ },
10213
+ "firefox": {
10214
+ "2": "n",
10215
+ "3": "n",
10216
+ "3.5": "y x",
10217
+ "3.6": "y x",
10218
+ "4": "y",
10219
+ "5": "y",
10220
+ "6": "y",
10221
+ "7": "y",
10222
+ "8": "y",
10223
+ "9": "y",
10224
+ "10": "y",
10225
+ "11": "y",
10226
+ "12": "y",
10227
+ "13": "y",
10228
+ "14": "y",
10229
+ "15": "y",
10230
+ "16": "y",
10231
+ "17": "y",
10232
+ "18": "y",
10233
+ "19": "y",
10234
+ "20": "y",
10235
+ "21": "y",
10236
+ "22": "y",
10237
+ "23": "y",
10238
+ "24": "y",
10239
+ "25": "y",
10240
+ "26": "y",
10241
+ "27": "y"
10242
+ },
10243
+ "chrome": {
10244
+ "4": "y x",
10245
+ "5": "y x",
10246
+ "6": "y x",
10247
+ "7": "y x",
10248
+ "8": "y x",
10249
+ "9": "y x",
10250
+ "10": "y",
10251
+ "11": "y",
10252
+ "12": "y",
10253
+ "13": "y",
10254
+ "14": "y",
10255
+ "15": "y",
10256
+ "16": "y",
10257
+ "17": "y",
10258
+ "18": "y",
10259
+ "19": "y",
10260
+ "20": "y",
10261
+ "21": "y",
10262
+ "22": "y",
10263
+ "23": "y",
10264
+ "24": "y",
10265
+ "25": "y",
10266
+ "26": "y",
10267
+ "27": "y",
10268
+ "28": "y",
10269
+ "29": "y",
10270
+ "30": "y",
10271
+ "31": "y",
10272
+ "32": "y"
10273
+ },
10274
+ "safari": {
10275
+ "3.1": "a x",
10276
+ "3.2": "a x",
10277
+ "4": "a x",
10278
+ "5": "y x",
10279
+ "5.1": "y",
10280
+ "6": "y",
10281
+ "6.1": "y",
10282
+ "7": "y"
10283
+ },
10284
+ "opera": {
10285
+ "9": "n",
10286
+ "9.5-9.6": "n",
10287
+ "10.0-10.1": "n",
10288
+ "10.5": "y",
10289
+ "10.6": "y",
10290
+ "11": "y",
10291
+ "11.1": "y",
10292
+ "11.5": "y",
10293
+ "11.6": "y",
10294
+ "12": "y",
10295
+ "12.1": "y",
10296
+ "15": "y",
10297
+ "16": "y",
10298
+ "17": "y",
10299
+ "18": "y"
10300
+ },
10301
+ "ios_saf": {
10302
+ "3.2": "a x",
10303
+ "4.0-4.1": "y x",
10304
+ "4.2-4.3": "y x",
10305
+ "5.0-5.1": "y",
10306
+ "6.0-6.1": "y",
10307
+ "7.0": "y"
10308
+ },
10309
+ "op_mini": {
10310
+ "5.0-7.0": "n"
10311
+ },
10312
+ "android": {
10313
+ "2.1": "a x",
10314
+ "2.2": "a x",
10315
+ "2.3": "a x",
10316
+ "3": "a x",
10317
+ "4": "y",
10318
+ "4.1": "y",
10319
+ "4.2-4.3": "y",
10320
+ "4.4": "y"
10321
+ },
10322
+ "bb": {
10323
+ "7": "y x",
10324
+ "10": "y"
10325
+ },
10326
+ "op_mob": {
10327
+ "10": "n",
10328
+ "11": "y",
10329
+ "11.1": "y",
10330
+ "11.5": "y",
10331
+ "12": "y",
10332
+ "12.1": "y",
10333
+ "0": "y"
10334
+ },
10335
+ "and_chr": {
10336
+ "0": "y"
10337
+ },
10338
+ "and_ff": {
10339
+ "0": "y"
10340
+ },
10341
+ "ie_mob": {
10342
+ "10": "y"
10343
+ }
10344
+ },
10345
+ "notes": "Can be partially emulated in older IE versions using the non-standard \"shadow\" filter. Partial support in Safari, iOS Safari and Android Browser refers to missing \"inset\" and blur radius value support.",
10346
+ "usage_perc_y": 79.27,
10347
+ "usage_perc_a": 1.55,
10348
+ "ucprefix": false,
10349
+ "parent": "",
10350
+ "keywords": "box-shadows,boxshadows,box shadow,shaow"
10351
+ },
10352
+ "css3-colors": {
10353
+ "title": "CSS3 Colors",
10354
+ "description": "Method of describing colors using Hue, Saturation and Lightness (hsl()) rather than just RGB, as well as allowing alpha-transparency with rgba() and hsla().",
10355
+ "spec": "http://www.w3.org/TR/css3-color/",
10356
+ "status": "rec",
10357
+ "links": [{
10358
+ "url": "http://www.zenelements.com/blog/css3-rgb-rgba-color-opacity/",
10359
+ "title": "Guide to RGB & RGBA"
10360
+ }, {
10361
+ "url": "http://www.css3files.com/color/",
10362
+ "title": "Information page"
10363
+ }, {
10364
+ "url": "http://www.zenelements.com/blog/css3-hsl-hsla-color-opacity/",
10365
+ "title": "Guide to HSL & HSLA"
10366
+ }, {
10367
+ "url": "http://docs.webplatform.org/wiki/css/color#RGBA_Notation",
10368
+ "title": "WebPlatform Docs"
10369
+ }, {
10370
+ "url": "http://dev.opera.com/articles/view/color-in-opera-10-hsl-rgb-and-alpha-transparency/",
10371
+ "title": "Dev.Opera article"
10372
+ }],
10373
+ "categories": ["CSS3"],
10374
+ "stats": {
10375
+ "ie": {
10376
+ "5.5": "n",
10377
+ "6": "n",
10378
+ "7": "n",
10379
+ "8": "n",
10380
+ "9": "y",
10381
+ "10": "y",
10382
+ "11": "y"
10383
+ },
10384
+ "firefox": {
10385
+ "2": "a",
10386
+ "3": "y",
10387
+ "3.5": "y",
10388
+ "3.6": "y",
10389
+ "4": "y",
10390
+ "5": "y",
10391
+ "6": "y",
10392
+ "7": "y",
10393
+ "8": "y",
10394
+ "9": "y",
10395
+ "10": "y",
10396
+ "11": "y",
10397
+ "12": "y",
10398
+ "13": "y",
10399
+ "14": "y",
10400
+ "15": "y",
10401
+ "16": "y",
10402
+ "17": "y",
10403
+ "18": "y",
10404
+ "19": "y",
10405
+ "20": "y",
10406
+ "21": "y",
10407
+ "22": "y",
10408
+ "23": "y",
10409
+ "24": "y",
10410
+ "25": "y",
10411
+ "26": "y",
10412
+ "27": "y"
10413
+ },
10414
+ "chrome": {
10415
+ "4": "y",
10416
+ "5": "y",
10417
+ "6": "y",
10418
+ "7": "y",
10419
+ "8": "y",
10420
+ "9": "y",
10421
+ "10": "y",
10422
+ "11": "y",
10423
+ "12": "y",
10424
+ "13": "y",
10425
+ "14": "y",
10426
+ "15": "y",
10427
+ "16": "y",
10428
+ "17": "y",
10429
+ "18": "y",
10430
+ "19": "y",
10431
+ "20": "y",
10432
+ "21": "y",
10433
+ "22": "y",
10434
+ "23": "y",
10435
+ "24": "y",
10436
+ "25": "y",
10437
+ "26": "y",
10438
+ "27": "y",
10439
+ "28": "y",
10440
+ "29": "y",
10441
+ "30": "y",
10442
+ "31": "y",
10443
+ "32": "y"
10444
+ },
10445
+ "safari": {
10446
+ "3.1": "y",
10447
+ "3.2": "y",
10448
+ "4": "y",
10449
+ "5": "y",
10450
+ "5.1": "y",
10451
+ "6": "y",
10452
+ "6.1": "y",
10453
+ "7": "y"
10454
+ },
10455
+ "opera": {
10456
+ "9": "n",
10457
+ "9.5-9.6": "a",
10458
+ "10.0-10.1": "y",
10459
+ "10.5": "y",
10460
+ "10.6": "y",
10461
+ "11": "y",
10462
+ "11.1": "y",
10463
+ "11.5": "y",
10464
+ "11.6": "y",
10465
+ "12": "y",
10466
+ "12.1": "y",
10467
+ "15": "y",
10468
+ "16": "y",
10469
+ "17": "y",
10470
+ "18": "y"
10471
+ },
10472
+ "ios_saf": {
10473
+ "3.2": "y",
10474
+ "4.0-4.1": "y",
10475
+ "4.2-4.3": "y",
10476
+ "5.0-5.1": "y",
10477
+ "6.0-6.1": "y",
10478
+ "7.0": "y"
10479
+ },
10480
+ "op_mini": {
10481
+ "5.0-7.0": "y"
10482
+ },
10483
+ "android": {
10484
+ "2.1": "y",
10485
+ "2.2": "y",
10486
+ "2.3": "y",
10487
+ "3": "y",
10488
+ "4": "y",
10489
+ "4.1": "y",
10490
+ "4.2-4.3": "y",
10491
+ "4.4": "y"
10492
+ },
10493
+ "bb": {
10494
+ "7": "y",
10495
+ "10": "y"
10496
+ },
10497
+ "op_mob": {
10498
+ "10": "y",
10499
+ "11": "y",
10500
+ "11.1": "y",
10501
+ "11.5": "y",
10502
+ "12": "y",
10503
+ "12.1": "y",
10504
+ "0": "y"
10505
+ },
10506
+ "and_chr": {
10507
+ "0": "y"
10508
+ },
10509
+ "and_ff": {
10510
+ "0": "y"
10511
+ },
10512
+ "ie_mob": {
10513
+ "10": "y"
10514
+ }
10515
+ },
10516
+ "notes": "",
10517
+ "usage_perc_y": 85.51,
10518
+ "usage_perc_a": 0.02,
10519
+ "ucprefix": false,
10520
+ "parent": "",
10521
+ "keywords": "rgb,hsl,rgba,hsla"
10522
+ },
10523
+ "css3-boxsizing": {
10524
+ "title": "CSS3 Box-sizing",
10525
+ "description": "Method of specifying whether or not an element's borders and padding should be included in size units",
10526
+ "spec": "http://www.w3.org/TR/css3-ui/#box-sizing",
10527
+ "status": "wd",
10528
+ "links": [{
10529
+ "url": "http://docs.webplatform.org/wiki/css/properties/box-sizing",
10530
+ "title": "WebPlatform Docs"
10531
+ }, {
10532
+ "url": "http://css-tricks.com/box-sizing/",
10533
+ "title": "CSS Tricks"
10534
+ }, {
10535
+ "url": "https://github.com/Schepp/box-sizing-polyfill",
10536
+ "title": "Polyfill for IE"
10537
+ }, {
10538
+ "url": "https://developer.mozilla.org/En/CSS/Box-sizing",
10539
+ "title": "MDN article"
10540
+ }, {
10541
+ "url": "http://www.456bereastreet.com/archive/201104/controlling_width_with_css3_box-sizing/",
10542
+ "title": "Blog post"
10543
+ }],
10544
+ "categories": ["CSS3"],
10545
+ "stats": {
10546
+ "ie": {
10547
+ "5.5": "p",
10548
+ "6": "p",
10549
+ "7": "p",
10550
+ "8": "a",
10551
+ "9": "a",
10552
+ "10": "a",
10553
+ "11": "a"
10554
+ },
10555
+ "firefox": {
10556
+ "2": "y x",
10557
+ "3": "y x",
10558
+ "3.5": "y x",
10559
+ "3.6": "y x",
10560
+ "4": "y x",
10561
+ "5": "y x",
10562
+ "6": "y x",
10563
+ "7": "y x",
10564
+ "8": "y x",
10565
+ "9": "y x",
10566
+ "10": "y x",
10567
+ "11": "y x",
10568
+ "12": "y x",
10569
+ "13": "y x",
10570
+ "14": "y x",
10571
+ "15": "y x",
10572
+ "16": "y x",
10573
+ "17": "y x",
10574
+ "18": "y x",
10575
+ "19": "y x",
10576
+ "20": "y x",
10577
+ "21": "y x",
10578
+ "22": "y x",
10579
+ "23": "y x",
10580
+ "24": "y x",
10581
+ "25": "y x",
10582
+ "26": "y x",
10583
+ "27": "y x"
10584
+ },
10585
+ "chrome": {
10586
+ "4": "a x",
10587
+ "5": "a x",
10588
+ "6": "a x",
10589
+ "7": "a x",
10590
+ "8": "a x",
10591
+ "9": "a x",
10592
+ "10": "a",
10593
+ "11": "a",
10594
+ "12": "a",
10595
+ "13": "a",
10596
+ "14": "a",
10597
+ "15": "a",
10598
+ "16": "a",
10599
+ "17": "a",
10600
+ "18": "a",
10601
+ "19": "a",
10602
+ "20": "a",
10603
+ "21": "a",
10604
+ "22": "a",
10605
+ "23": "a",
10606
+ "24": "a",
10607
+ "25": "a",
10608
+ "26": "a",
10609
+ "27": "a",
10610
+ "28": "a",
10611
+ "29": "a",
10612
+ "30": "a",
10613
+ "31": "a",
10614
+ "32": "a"
10615
+ },
10616
+ "safari": {
10617
+ "3.1": "a x",
10618
+ "3.2": "a x",
10619
+ "4": "a x",
10620
+ "5": "a x",
10621
+ "5.1": "a",
10622
+ "6": "a",
10623
+ "6.1": "a",
10624
+ "7": "a"
10625
+ },
10626
+ "opera": {
10627
+ "9": "n",
10628
+ "9.5-9.6": "a",
10629
+ "10.0-10.1": "a",
10630
+ "10.5": "a",
10631
+ "10.6": "a",
10632
+ "11": "a",
10633
+ "11.1": "a",
10634
+ "11.5": "a",
10635
+ "11.6": "a",
10636
+ "12": "a",
10637
+ "12.1": "a",
10638
+ "15": "a",
10639
+ "16": "a",
10640
+ "17": "a",
10641
+ "18": "a"
10642
+ },
10643
+ "ios_saf": {
10644
+ "3.2": "a x",
10645
+ "4.0-4.1": "a x",
10646
+ "4.2-4.3": "a x",
10647
+ "5.0-5.1": "a",
10648
+ "6.0-6.1": "a",
10649
+ "7.0": "a"
10650
+ },
10651
+ "op_mini": {
10652
+ "5.0-7.0": "a"
10653
+ },
10654
+ "android": {
10655
+ "2.1": "a x",
10656
+ "2.2": "a x",
10657
+ "2.3": "a x",
10658
+ "3": "a x",
10659
+ "4": "a",
10660
+ "4.1": "a",
10661
+ "4.2-4.3": "a",
10662
+ "4.4": "a"
10663
+ },
10664
+ "bb": {
10665
+ "7": "a x",
10666
+ "10": "a"
10667
+ },
10668
+ "op_mob": {
10669
+ "10": "a",
10670
+ "11": "a",
10671
+ "11.1": "a",
10672
+ "11.5": "a",
10673
+ "12": "a",
10674
+ "12.1": "a",
10675
+ "0": "a"
10676
+ },
10677
+ "and_chr": {
10678
+ "0": "a"
10679
+ },
10680
+ "and_ff": {
10681
+ "0": "y x"
10682
+ },
10683
+ "ie_mob": {
10684
+ "10": "a"
10685
+ }
10686
+ },
10687
+ "notes": "Partial support refers to supporting only the \"border-box\" value, not \"padding-box\" (which was added to the spec later).",
10688
+ "usage_perc_y": 15.43,
10689
+ "usage_perc_a": 78.42,
10690
+ "ucprefix": false,
10691
+ "parent": "",
10692
+ "keywords": "border-box,content-box,padding-box"
10693
+ },
10694
+ "css-mediaqueries": {
10695
+ "title": "CSS3 Media Queries",
10696
+ "description": "Method of applying styles based on media information. Includes things like page and device dimensions",
10697
+ "spec": "http://www.w3.org/TR/css3-mediaqueries/",
10698
+ "status": "rec",
10699
+ "links": [{
10700
+ "url": "http://docs.webplatform.org/wiki/css/atrules/@media",
10701
+ "title": "WebPlatform Docs"
10702
+ }, {
10703
+ "url": "http://ie.microsoft.com/testdrive/HTML5/85CSS3_MediaQueries/",
10704
+ "title": "IE demo page with information"
10705
+ }, {
10706
+ "url": "https://github.com/scottjehl/Respond",
10707
+ "title": "Polyfill for IE"
10708
+ }, {
10709
+ "url": "http://webdesignerwall.com/tutorials/responsive-design-with-css3-media-queries",
10710
+ "title": "Media Queries tutorial"
10711
+ }],
10712
+ "categories": ["CSS3"],
10713
+ "stats": {
10714
+ "ie": {
10715
+ "5.5": "p",
10716
+ "6": "p",
10717
+ "7": "p",
10718
+ "8": "p",
10719
+ "9": "y",
10720
+ "10": "y",
10721
+ "11": "y"
10722
+ },
10723
+ "firefox": {
10724
+ "2": "n",
10725
+ "3": "n",
10726
+ "3.5": "y",
10727
+ "3.6": "y",
10728
+ "4": "y",
10729
+ "5": "y",
10730
+ "6": "y",
10731
+ "7": "y",
10732
+ "8": "y",
10733
+ "9": "y",
10734
+ "10": "y",
10735
+ "11": "y",
10736
+ "12": "y",
10737
+ "13": "y",
10738
+ "14": "y",
10739
+ "15": "y",
10740
+ "16": "y",
10741
+ "17": "y",
10742
+ "18": "y",
10743
+ "19": "y",
10744
+ "20": "y",
10745
+ "21": "y",
10746
+ "22": "y",
10747
+ "23": "y",
10748
+ "24": "y",
10749
+ "25": "y",
10750
+ "26": "y",
10751
+ "27": "y"
10752
+ },
10753
+ "chrome": {
10754
+ "4": "y",
10755
+ "5": "y",
10756
+ "6": "y",
10757
+ "7": "y",
10758
+ "8": "y",
10759
+ "9": "y",
10760
+ "10": "y",
10761
+ "11": "y",
10762
+ "12": "y",
10763
+ "13": "y",
10764
+ "14": "y",
10765
+ "15": "y",
10766
+ "16": "y",
10767
+ "17": "y",
10768
+ "18": "y",
10769
+ "19": "y",
10770
+ "20": "y",
10771
+ "21": "y",
10772
+ "22": "y",
10773
+ "23": "y",
10774
+ "24": "y",
10775
+ "25": "y",
10776
+ "26": "y",
10777
+ "27": "y",
10778
+ "28": "y",
10779
+ "29": "y",
10780
+ "30": "y",
10781
+ "31": "y",
10782
+ "32": "y"
10783
+ },
10784
+ "safari": {
10785
+ "3.1": "a",
10786
+ "3.2": "a",
10787
+ "4": "y",
10788
+ "5": "y",
10789
+ "5.1": "y",
10790
+ "6": "y",
10791
+ "6.1": "y",
10792
+ "7": "y"
10793
+ },
10794
+ "opera": {
10795
+ "9": "n",
10796
+ "9.5-9.6": "y",
10797
+ "10.0-10.1": "y",
10798
+ "10.5": "y",
10799
+ "10.6": "y",
10800
+ "11": "y",
10801
+ "11.1": "y",
10802
+ "11.5": "y",
10803
+ "11.6": "y",
10804
+ "12": "y",
10805
+ "12.1": "y",
10806
+ "15": "y",
10807
+ "16": "y",
10808
+ "17": "y",
10809
+ "18": "y"
10810
+ },
10811
+ "ios_saf": {
10812
+ "3.2": "y",
10813
+ "4.0-4.1": "y",
10814
+ "4.2-4.3": "y",
10815
+ "5.0-5.1": "y",
10816
+ "6.0-6.1": "y",
10817
+ "7.0": "y"
10818
+ },
10819
+ "op_mini": {
10820
+ "5.0-7.0": "y"
10821
+ },
10822
+ "android": {
10823
+ "2.1": "y",
10824
+ "2.2": "y",
10825
+ "2.3": "y",
10826
+ "3": "y",
10827
+ "4": "y",
10828
+ "4.1": "y",
10829
+ "4.2-4.3": "y",
10830
+ "4.4": "y"
10831
+ },
10832
+ "bb": {
10833
+ "7": "y",
10834
+ "10": "y"
10835
+ },
10836
+ "op_mob": {
10837
+ "10": "y",
10838
+ "11": "y",
10839
+ "11.1": "y",
10840
+ "11.5": "y",
10841
+ "12": "y",
10842
+ "12.1": "y",
10843
+ "0": "y"
10844
+ },
10845
+ "and_chr": {
10846
+ "0": "y"
10847
+ },
10848
+ "and_ff": {
10849
+ "0": "y"
10850
+ },
10851
+ "ie_mob": {
10852
+ "10": "y"
10853
+ }
10854
+ },
10855
+ "notes": "Incomplete support by older webkit browsers refers to only acknowledging different media rules on page reload",
10856
+ "usage_perc_y": 85.42,
10857
+ "usage_perc_a": 0.01,
10858
+ "ucprefix": false,
10859
+ "parent": "",
10860
+ "keywords": "@media"
10861
+ },
10862
+ "multicolumn": {
10863
+ "title": "CSS3 Multiple column layout",
10864
+ "description": "Method of flowing information in multiple columns",
10865
+ "spec": "http://www.w3.org/TR/css3-multicol/",
10866
+ "status": "cr",
10867
+ "links": [{
10868
+ "url": "http://dev.opera.com/articles/view/css3-multi-column-layout/",
10869
+ "title": "Dev.Opera article"
10870
+ }, {
10871
+ "url": "http://docs.webplatform.org/wiki/css/properties/column-width",
10872
+ "title": "WebPlatform Docs"
10873
+ }, {
10874
+ "url": "http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/an-introduction-to-the-css3-multiple-column-layout-module/",
10875
+ "title": "Introduction page"
10876
+ }],
10877
+ "categories": ["CSS3"],
10878
+ "stats": {
10879
+ "ie": {
10880
+ "5.5": "n",
10881
+ "6": "n",
10882
+ "7": "n",
10883
+ "8": "n",
10884
+ "9": "n",
10885
+ "10": "y",
10886
+ "11": "y"
10887
+ },
10888
+ "firefox": {
10889
+ "2": "a x",
10890
+ "3": "a x",
10891
+ "3.5": "a x",
10892
+ "3.6": "a x",
10893
+ "4": "a x",
10894
+ "5": "a x",
10895
+ "6": "a x",
10896
+ "7": "a x",
10897
+ "8": "a x",
10898
+ "9": "a x",
10899
+ "10": "a x",
10900
+ "11": "a x",
10901
+ "12": "a x",
10902
+ "13": "a x",
10903
+ "14": "a x",
10904
+ "15": "a x",
10905
+ "16": "a x",
10906
+ "17": "a x",
10907
+ "18": "a x",
10908
+ "19": "a x",
10909
+ "20": "a x",
10910
+ "21": "a x",
10911
+ "22": "a x",
10912
+ "23": "a x",
10913
+ "24": "a x",
10914
+ "25": "a x",
10915
+ "26": "a x",
10916
+ "27": "a x"
10917
+ },
10918
+ "chrome": {
10919
+ "4": "a x",
10920
+ "5": "a x",
10921
+ "6": "a x",
10922
+ "7": "a x",
10923
+ "8": "a x",
10924
+ "9": "a x",
10925
+ "10": "a x",
10926
+ "11": "a x",
10927
+ "12": "a x",
10928
+ "13": "a x",
10929
+ "14": "a x",
10930
+ "15": "a x",
10931
+ "16": "a x",
10932
+ "17": "a x",
10933
+ "18": "a x",
10934
+ "19": "a x",
10935
+ "20": "a x",
10936
+ "21": "a x",
10937
+ "22": "a x",
10938
+ "23": "a x",
10939
+ "24": "a x",
10940
+ "25": "a x",
10941
+ "26": "a x",
10942
+ "27": "a x",
10943
+ "28": "a x",
10944
+ "29": "a x",
10945
+ "30": "a x",
10946
+ "31": "a x",
10947
+ "32": "a x"
10948
+ },
10949
+ "safari": {
10950
+ "3.1": "a x",
10951
+ "3.2": "a x",
10952
+ "4": "a x",
10953
+ "5": "a x",
10954
+ "5.1": "a x",
10955
+ "6": "a x",
10956
+ "6.1": "a x",
10957
+ "7": "a x"
10958
+ },
10959
+ "opera": {
10960
+ "9": "n",
10961
+ "9.5-9.6": "n",
10962
+ "10.0-10.1": "n",
10963
+ "10.5": "n",
10964
+ "10.6": "n",
10965
+ "11": "n",
10966
+ "11.1": "y",
10967
+ "11.5": "y",
10968
+ "11.6": "y",
10969
+ "12": "y",
10970
+ "12.1": "y",
10971
+ "15": "a x",
10972
+ "16": "a x",
10973
+ "17": "a x",
10974
+ "18": "a x"
10975
+ },
10976
+ "ios_saf": {
10977
+ "3.2": "a x",
10978
+ "4.0-4.1": "a x",
10979
+ "4.2-4.3": "a x",
10980
+ "5.0-5.1": "a x",
10981
+ "6.0-6.1": "a x",
10982
+ "7.0": "a x"
10983
+ },
10984
+ "op_mini": {
10985
+ "5.0-7.0": "y"
10986
+ },
10987
+ "android": {
10988
+ "2.1": "a x",
10989
+ "2.2": "a x",
10990
+ "2.3": "a x",
10991
+ "3": "a x",
10992
+ "4": "a x",
10993
+ "4.1": "a x",
10994
+ "4.2-4.3": "a x",
10995
+ "4.4": "a x"
10996
+ },
10997
+ "bb": {
10998
+ "7": "a x",
10999
+ "10": "a x"
11000
+ },
11001
+ "op_mob": {
11002
+ "10": "n",
11003
+ "11": "n",
11004
+ "11.1": "y",
11005
+ "11.5": "y",
11006
+ "12": "y",
11007
+ "12.1": "y",
11008
+ "0": "a x"
11009
+ },
11010
+ "and_chr": {
11011
+ "0": "a x"
11012
+ },
11013
+ "and_ff": {
11014
+ "0": "a x"
11015
+ },
11016
+ "ie_mob": {
11017
+ "10": "y"
11018
+ }
11019
+ },
11020
+ "notes": "Partial support refers to not supporting the break-before, break-after, break-inside properties. Webkit browsers do have equivalent support for the non-standard -webkit-column-break-* properties.",
11021
+ "usage_perc_y": 16.41,
11022
+ "usage_perc_a": 63.85,
11023
+ "ucprefix": false,
11024
+ "parent": "",
11025
+ "keywords": "column-count"
11026
+ },
11027
+ "border-radius": {
11028
+ "title": "CSS3 Border-radius (rounded corners)",
11029
+ "description": "Method of making the border corners round",
11030
+ "spec": "http://www.w3.org/TR/css3-background/#the-border-radius",
11031
+ "status": "cr",
11032
+ "links": [{
11033
+ "url": "http://docs.webplatform.org/wiki/css/properties/border-radius",
11034
+ "title": "WebPlatform Docs"
11035
+ }, {
11036
+ "url": "http://muddledramblings.com/table-of-css3-border-radius-compliance",
11037
+ "title": "Detailed compliance table"
11038
+ }, {
11039
+ "url": "http://www.css3files.com/border/#borderradius",
11040
+ "title": "Information page"
11041
+ }, {
11042
+ "url": "http://css3pie.com/",
11043
+ "title": "Polyfill which includes border-radius"
11044
+ }, {
11045
+ "url": "http://border-radius.com",
11046
+ "title": "Border-radius CSS Generator"
11047
+ }],
11048
+ "categories": ["CSS3"],
11049
+ "stats": {
11050
+ "ie": {
11051
+ "5.5": "n",
11052
+ "6": "n",
11053
+ "7": "n",
11054
+ "8": "n",
11055
+ "9": "y",
11056
+ "10": "y",
11057
+ "11": "y"
11058
+ },
11059
+ "firefox": {
11060
+ "2": "a x",
11061
+ "3": "y x",
11062
+ "3.5": "y x",
11063
+ "3.6": "y x",
11064
+ "4": "y",
11065
+ "5": "y",
11066
+ "6": "y",
11067
+ "7": "y",
11068
+ "8": "y",
11069
+ "9": "y",
11070
+ "10": "y",
11071
+ "11": "y",
11072
+ "12": "y",
11073
+ "13": "y",
11074
+ "14": "y",
11075
+ "15": "y",
11076
+ "16": "y",
11077
+ "17": "y",
11078
+ "18": "y",
11079
+ "19": "y",
11080
+ "20": "y",
11081
+ "21": "y",
11082
+ "22": "y",
11083
+ "23": "y",
11084
+ "24": "y",
11085
+ "25": "y",
11086
+ "26": "y",
11087
+ "27": "y"
11088
+ },
11089
+ "chrome": {
11090
+ "4": "y x",
11091
+ "5": "y",
11092
+ "6": "y",
11093
+ "7": "y",
11094
+ "8": "y",
11095
+ "9": "y",
11096
+ "10": "y",
11097
+ "11": "y",
11098
+ "12": "y",
11099
+ "13": "y",
11100
+ "14": "y",
11101
+ "15": "y",
11102
+ "16": "y",
11103
+ "17": "y",
11104
+ "18": "y",
11105
+ "19": "y",
11106
+ "20": "y",
11107
+ "21": "y",
11108
+ "22": "y",
11109
+ "23": "y",
11110
+ "24": "y",
11111
+ "25": "y",
11112
+ "26": "y",
11113
+ "27": "y",
11114
+ "28": "y",
11115
+ "29": "y",
11116
+ "30": "y",
11117
+ "31": "y",
11118
+ "32": "y"
11119
+ },
11120
+ "safari": {
11121
+ "3.1": "y x",
11122
+ "3.2": "y x",
11123
+ "4": "y x",
11124
+ "5": "y",
11125
+ "5.1": "y",
11126
+ "6": "y",
11127
+ "6.1": "y",
11128
+ "7": "y"
11129
+ },
11130
+ "opera": {
11131
+ "9": "n",
11132
+ "9.5-9.6": "n",
11133
+ "10.0-10.1": "n",
11134
+ "10.5": "y",
11135
+ "10.6": "y",
11136
+ "11": "y",
11137
+ "11.1": "y",
11138
+ "11.5": "y",
11139
+ "11.6": "y",
11140
+ "12": "y",
11141
+ "12.1": "y",
11142
+ "15": "y",
11143
+ "16": "y",
11144
+ "17": "y",
11145
+ "18": "y"
11146
+ },
11147
+ "ios_saf": {
11148
+ "3.2": "y x",
11149
+ "4.0-4.1": "y",
11150
+ "4.2-4.3": "y",
11151
+ "5.0-5.1": "y",
11152
+ "6.0-6.1": "y",
11153
+ "7.0": "y"
11154
+ },
11155
+ "op_mini": {
11156
+ "5.0-7.0": "n"
11157
+ },
11158
+ "android": {
11159
+ "2.1": "y x",
11160
+ "2.2": "y",
11161
+ "2.3": "y",
11162
+ "3": "y",
11163
+ "4": "y",
11164
+ "4.1": "y",
11165
+ "4.2-4.3": "y",
11166
+ "4.4": "y"
11167
+ },
11168
+ "bb": {
11169
+ "7": "y",
11170
+ "10": "y"
11171
+ },
11172
+ "op_mob": {
11173
+ "10": "n",
11174
+ "11": "y",
11175
+ "11.1": "y",
11176
+ "11.5": "y",
11177
+ "12": "y",
11178
+ "12.1": "y",
11179
+ "0": "y"
11180
+ },
11181
+ "and_chr": {
11182
+ "0": "y"
11183
+ },
11184
+ "and_ff": {
11185
+ "0": "y"
11186
+ },
11187
+ "ie_mob": {
11188
+ "10": "y"
11189
+ }
11190
+ },
11191
+ "notes": "",
11192
+ "usage_perc_y": 80.91,
11193
+ "usage_perc_a": 0.02,
11194
+ "ucprefix": false,
11195
+ "parent": "",
11196
+ "keywords": "roundedcorners, border radius,-moz-border-radius"
11197
+ },
11198
+ "transforms2d": {
11199
+ "title": "CSS3 Transforms",
11200
+ "description": "Method of transforming an element including rotating, scaling, etc.",
11201
+ "spec": "http://www.w3.org/TR/css3-2d-transforms/",
11202
+ "status": "wd",
11203
+ "links": [{
11204
+ "url": "http://www.westciv.com/tools/transforms/",
11205
+ "title": "Live editor"
11206
+ }, {
11207
+ "url": "http://www.useragentman.com/IETransformsTranslator/",
11208
+ "title": "Converter for IE"
11209
+ }, {
11210
+ "url": "http://docs.webplatform.org/wiki/css/transforms/transform",
11211
+ "title": "WebPlatform Docs"
11212
+ }, {
11213
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/css.js#css-transform",
11214
+ "title": "has.js test"
11215
+ }, {
11216
+ "url": "https://developer.mozilla.org/en/CSS/-moz-transform",
11217
+ "title": "MDN article"
11218
+ }, {
11219
+ "url": "http://www.webresourcesdepot.com/cross-browser-css-transforms-csssandpaper/",
11220
+ "title": "Workaround script for IE"
11221
+ }, {
11222
+ "url": "http://www.css3files.com/transform/",
11223
+ "title": "Information page"
11224
+ }],
11225
+ "categories": ["CSS3"],
11226
+ "stats": {
11227
+ "ie": {
11228
+ "5.5": "n",
11229
+ "6": "p",
11230
+ "7": "p",
11231
+ "8": "p",
11232
+ "9": "y x",
11233
+ "10": "y",
11234
+ "11": "y"
11235
+ },
11236
+ "firefox": {
11237
+ "2": "n",
11238
+ "3": "n",
11239
+ "3.5": "y x",
11240
+ "3.6": "y x",
11241
+ "4": "y x",
11242
+ "5": "y x",
11243
+ "6": "y x",
11244
+ "7": "y x",
11245
+ "8": "y x",
11246
+ "9": "y x",
11247
+ "10": "y x",
11248
+ "11": "y x",
11249
+ "12": "y x",
11250
+ "13": "y x",
11251
+ "14": "y x",
11252
+ "15": "y x",
11253
+ "16": "y",
11254
+ "17": "y",
11255
+ "18": "y",
11256
+ "19": "y",
11257
+ "20": "y",
11258
+ "21": "y",
11259
+ "22": "y",
11260
+ "23": "y",
11261
+ "24": "y",
11262
+ "25": "y",
11263
+ "26": "y",
11264
+ "27": "y"
11265
+ },
11266
+ "chrome": {
11267
+ "4": "y x",
11268
+ "5": "y x",
11269
+ "6": "y x",
11270
+ "7": "y x",
11271
+ "8": "y x",
11272
+ "9": "y x",
11273
+ "10": "y x",
11274
+ "11": "y x",
11275
+ "12": "y x",
11276
+ "13": "y x",
11277
+ "14": "y x",
11278
+ "15": "y x",
11279
+ "16": "y x",
11280
+ "17": "y x",
11281
+ "18": "y x",
11282
+ "19": "y x",
11283
+ "20": "y x",
11284
+ "21": "y x",
11285
+ "22": "y x",
11286
+ "23": "y x",
11287
+ "24": "y x",
11288
+ "25": "y x",
11289
+ "26": "y x",
11290
+ "27": "y x",
11291
+ "28": "y x",
11292
+ "29": "y x",
11293
+ "30": "y x",
11294
+ "31": "y x",
11295
+ "32": "y x"
11296
+ },
11297
+ "safari": {
11298
+ "3.1": "y x",
11299
+ "3.2": "y x",
11300
+ "4": "y x",
11301
+ "5": "y x",
11302
+ "5.1": "y x",
11303
+ "6": "y x",
11304
+ "6.1": "y x",
11305
+ "7": "y x"
11306
+ },
11307
+ "opera": {
11308
+ "9": "n",
11309
+ "9.5-9.6": "n",
11310
+ "10.0-10.1": "n",
11311
+ "10.5": "y x",
11312
+ "10.6": "y x",
11313
+ "11": "y x",
11314
+ "11.1": "y x",
11315
+ "11.5": "y x",
11316
+ "11.6": "y x",
11317
+ "12": "y x",
11318
+ "12.1": "y",
11319
+ "15": "y x",
11320
+ "16": "y x",
11321
+ "17": "y x",
11322
+ "18": "y x"
11323
+ },
11324
+ "ios_saf": {
11325
+ "3.2": "y x",
11326
+ "4.0-4.1": "y x",
11327
+ "4.2-4.3": "y x",
11328
+ "5.0-5.1": "y x",
11329
+ "6.0-6.1": "y x",
11330
+ "7.0": "y x"
11331
+ },
11332
+ "op_mini": {
11333
+ "5.0-7.0": "n"
11334
+ },
11335
+ "android": {
11336
+ "2.1": "y x",
11337
+ "2.2": "y x",
11338
+ "2.3": "y x",
11339
+ "3": "y x",
11340
+ "4": "y x",
11341
+ "4.1": "y x",
11342
+ "4.2-4.3": "y x",
11343
+ "4.4": "y x"
11344
+ },
11345
+ "bb": {
11346
+ "7": "y x",
11347
+ "10": "y x"
11348
+ },
11349
+ "op_mob": {
11350
+ "10": "n",
11351
+ "11": "y",
11352
+ "11.1": "y",
11353
+ "11.5": "y",
11354
+ "12": "y",
11355
+ "12.1": "y",
11356
+ "0": "y x"
11357
+ },
11358
+ "and_chr": {
11359
+ "0": "y x"
11360
+ },
11361
+ "and_ff": {
11362
+ "0": "y"
11363
+ },
11364
+ "ie_mob": {
11365
+ "10": "y"
11366
+ }
11367
+ },
11368
+ "notes": "The scale transform can be emulated in IE < 9 using Microsoft's \"zoom\" extension, others are (not easily) possible using the MS Matrix filter",
11369
+ "usage_perc_y": 80.82,
11370
+ "usage_perc_a": 0,
11371
+ "ucprefix": false,
11372
+ "parent": "",
11373
+ "keywords": "transformation,translate,rotation,rotate,scale,css-transforms"
11374
+ },
11375
+ "use-strict": {
11376
+ "title": "ECMAScript 5 Strict Mode",
11377
+ "description": "Method of placing code in a \"strict\" operating context.",
11378
+ "spec": "http://ecma-international.org/ecma-262/5.1/#sec-14.1",
11379
+ "status": "other",
11380
+ "links": [{
11381
+ "url": "http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/",
11382
+ "title": "Article with test suite"
11383
+ }, {
11384
+ "url": "http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/",
11385
+ "title": "Information page"
11386
+ }],
11387
+ "categories": ["Other"],
11388
+ "stats": {
11389
+ "ie": {
11390
+ "5.5": "n",
11391
+ "6": "n",
11392
+ "7": "n",
11393
+ "8": "n",
11394
+ "9": "n",
11395
+ "10": "y",
11396
+ "11": "y"
11397
+ },
11398
+ "firefox": {
11399
+ "2": "n",
11400
+ "3": "n",
11401
+ "3.5": "n",
11402
+ "3.6": "n",
11403
+ "4": "y",
11404
+ "5": "y",
11405
+ "6": "y",
11406
+ "7": "y",
11407
+ "8": "y",
11408
+ "9": "y",
11409
+ "10": "y",
11410
+ "11": "y",
11411
+ "12": "y",
11412
+ "13": "y",
11413
+ "14": "y",
11414
+ "15": "y",
11415
+ "16": "y",
11416
+ "17": "y",
11417
+ "18": "y",
11418
+ "19": "y",
11419
+ "20": "y",
11420
+ "21": "y",
11421
+ "22": "y",
11422
+ "23": "y",
11423
+ "24": "y",
11424
+ "25": "y",
11425
+ "26": "y",
11426
+ "27": "y"
11427
+ },
11428
+ "chrome": {
11429
+ "4": "n",
11430
+ "5": "n",
11431
+ "6": "n",
11432
+ "7": "n",
11433
+ "8": "n",
11434
+ "9": "n",
11435
+ "10": "n",
11436
+ "11": "n",
11437
+ "12": "n",
11438
+ "13": "y",
11439
+ "14": "y",
11440
+ "15": "y",
11441
+ "16": "y",
11442
+ "17": "y",
11443
+ "18": "y",
11444
+ "19": "y",
11445
+ "20": "y",
11446
+ "21": "y",
11447
+ "22": "y",
11448
+ "23": "y",
11449
+ "24": "y",
11450
+ "25": "y",
11451
+ "26": "y",
11452
+ "27": "y",
11453
+ "28": "y",
11454
+ "29": "y",
11455
+ "30": "y",
11456
+ "31": "y",
11457
+ "32": "y"
11458
+ },
11459
+ "safari": {
11460
+ "3.1": "n",
11461
+ "3.2": "n",
11462
+ "4": "n",
11463
+ "5": "a",
11464
+ "5.1": "a",
11465
+ "6": "y",
11466
+ "6.1": "y",
11467
+ "7": "y"
11468
+ },
11469
+ "opera": {
11470
+ "9": "n",
11471
+ "9.5-9.6": "n",
11472
+ "10.0-10.1": "n",
11473
+ "10.5": "n",
11474
+ "10.6": "n",
11475
+ "11": "n",
11476
+ "11.1": "n",
11477
+ "11.5": "n",
11478
+ "11.6": "y",
11479
+ "12": "y",
11480
+ "12.1": "y",
11481
+ "15": "y",
11482
+ "16": "y",
11483
+ "17": "y",
11484
+ "18": "y"
11485
+ },
11486
+ "ios_saf": {
11487
+ "3.2": "n",
11488
+ "4.0-4.1": "n",
11489
+ "4.2-4.3": "n",
11490
+ "5.0-5.1": "y",
11491
+ "6.0-6.1": "y",
11492
+ "7.0": "y"
11493
+ },
11494
+ "op_mini": {
11495
+ "5.0-7.0": "n"
11496
+ },
11497
+ "android": {
11498
+ "2.1": "n",
11499
+ "2.2": "n",
11500
+ "2.3": "n",
11501
+ "3": "y",
11502
+ "4": "y",
11503
+ "4.1": "y",
11504
+ "4.2-4.3": "y",
11505
+ "4.4": "y"
11506
+ },
11507
+ "bb": {
11508
+ "7": "y",
11509
+ "10": "y"
11510
+ },
11511
+ "op_mob": {
11512
+ "10": "n",
11513
+ "11": "n",
11514
+ "11.1": "n",
11515
+ "11.5": "y",
11516
+ "12": "y",
11517
+ "12.1": "y",
11518
+ "0": "y"
11519
+ },
11520
+ "and_chr": {
11521
+ "0": "y"
11522
+ },
11523
+ "and_ff": {
11524
+ "0": "y"
11525
+ },
11526
+ "ie_mob": {
11527
+ "10": "y"
11528
+ }
11529
+ },
11530
+ "notes": "Partial support in older Safari refers to strict mode still accepting a lot of JS that should be considered invalid.",
11531
+ "usage_perc_y": 71.65,
11532
+ "usage_perc_a": 1.59,
11533
+ "ucprefix": false,
11534
+ "parent": "",
11535
+ "keywords": ""
11536
+ },
11537
+ "transforms3d": {
11538
+ "title": "CSS3 3D Transforms",
11539
+ "description": "Method of transforming an element in the third dimension",
11540
+ "spec": "http://www.w3.org/TR/css3-3d-transforms/",
11541
+ "status": "wd",
11542
+ "links": [{
11543
+ "url": "http://docs.webplatform.org/wiki/css/transforms/transform",
11544
+ "title": "WebPlatform Docs"
11545
+ }, {
11546
+ "url": "http://css3.bradshawenterprises.com/flip/",
11547
+ "title": "Multi-browser demo"
11548
+ }, {
11549
+ "url": "http://thewebrocks.com/demos/3D-css-tester/",
11550
+ "title": "3D CSS Tester"
11551
+ }, {
11552
+ "url": "http://hacks.mozilla.org/2011/10/css-3d-transformations-in-firefox-nightly/",
11553
+ "title": "Mozilla hacks article"
11554
+ }, {
11555
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/css.js#css-transform",
11556
+ "title": "has.js test"
11557
+ }],
11558
+ "categories": ["CSS3"],
11559
+ "stats": {
11560
+ "ie": {
11561
+ "5.5": "n",
11562
+ "6": "n",
11563
+ "7": "n",
11564
+ "8": "n",
11565
+ "9": "n",
11566
+ "10": "a",
11567
+ "11": "a"
11568
+ },
11569
+ "firefox": {
11570
+ "2": "n",
11571
+ "3": "n",
11572
+ "3.5": "n",
11573
+ "3.6": "n",
11574
+ "4": "n",
11575
+ "5": "n",
11576
+ "6": "n",
11577
+ "7": "n",
11578
+ "8": "n",
11579
+ "9": "n",
11580
+ "10": "y x",
11581
+ "11": "y x",
11582
+ "12": "y x",
11583
+ "13": "y x",
11584
+ "14": "y x",
11585
+ "15": "y x",
11586
+ "16": "y",
11587
+ "17": "y",
11588
+ "18": "y",
11589
+ "19": "y",
11590
+ "20": "y",
11591
+ "21": "y",
11592
+ "22": "y",
11593
+ "23": "y",
11594
+ "24": "y",
11595
+ "25": "y",
11596
+ "26": "y",
11597
+ "27": "y"
11598
+ },
11599
+ "chrome": {
11600
+ "4": "n",
11601
+ "5": "n",
11602
+ "6": "n",
11603
+ "7": "n",
11604
+ "8": "n",
11605
+ "9": "n",
11606
+ "10": "n",
11607
+ "11": "n",
11608
+ "12": "y x",
11609
+ "13": "y x",
11610
+ "14": "y x",
11611
+ "15": "y x",
11612
+ "16": "y x",
11613
+ "17": "y x",
11614
+ "18": "y x",
11615
+ "19": "y x",
11616
+ "20": "y x",
11617
+ "21": "y x",
11618
+ "22": "y x",
11619
+ "23": "y x",
11620
+ "24": "y x",
11621
+ "25": "y x",
11622
+ "26": "y x",
11623
+ "27": "y x",
11624
+ "28": "y x",
11625
+ "29": "y x",
11626
+ "30": "y x",
11627
+ "31": "y x",
11628
+ "32": "y x"
11629
+ },
11630
+ "safari": {
11631
+ "3.1": "n",
11632
+ "3.2": "n",
11633
+ "4": "y x",
11634
+ "5": "y x",
11635
+ "5.1": "y x",
11636
+ "6": "y x",
11637
+ "6.1": "y x",
11638
+ "7": "y x"
11639
+ },
11640
+ "opera": {
11641
+ "9": "n",
11642
+ "9.5-9.6": "n",
11643
+ "10.0-10.1": "n",
11644
+ "10.5": "n",
11645
+ "10.6": "n",
11646
+ "11": "n",
11647
+ "11.1": "n",
11648
+ "11.5": "n",
11649
+ "11.6": "n",
11650
+ "12": "n",
11651
+ "12.1": "n",
11652
+ "15": "y x",
11653
+ "16": "y x",
11654
+ "17": "y x",
11655
+ "18": "y x"
11656
+ },
11657
+ "ios_saf": {
11658
+ "3.2": "y x",
11659
+ "4.0-4.1": "y x",
11660
+ "4.2-4.3": "y x",
11661
+ "5.0-5.1": "y x",
11662
+ "6.0-6.1": "y x",
11663
+ "7.0": "y x"
11664
+ },
11665
+ "op_mini": {
11666
+ "5.0-7.0": "n"
11667
+ },
11668
+ "android": {
11669
+ "2.1": "n",
11670
+ "2.2": "n",
11671
+ "2.3": "n",
11672
+ "3": "y x",
11673
+ "4": "y x",
11674
+ "4.1": "y x",
11675
+ "4.2-4.3": "y x",
11676
+ "4.4": "y x"
11677
+ },
11678
+ "bb": {
11679
+ "7": "y x",
11680
+ "10": "y x"
11681
+ },
11682
+ "op_mob": {
11683
+ "10": "n",
11684
+ "11": "n",
11685
+ "11.1": "n",
11686
+ "11.5": "n",
11687
+ "12": "n",
11688
+ "12.1": "n",
11689
+ "0": "y x"
11690
+ },
11691
+ "and_chr": {
11692
+ "0": "y x"
11693
+ },
11694
+ "and_ff": {
11695
+ "0": "y"
11696
+ },
11697
+ "ie_mob": {
11698
+ "10": "a"
11699
+ }
11700
+ },
11701
+ "notes": "Partial support in IE10 refers to not supporting <a href=\"http://msdn.microsoft.com/en-us/library/ie/hh673529%28v=vs.85%29.aspx#the_ms_transform_style_property\">the transform-style: preserve-3d property</a>. This prevents nesting 3D transformed elements.",
11702
+ "usage_perc_y": 61.31,
11703
+ "usage_perc_a": 11.11,
11704
+ "ucprefix": false,
11705
+ "parent": "",
11706
+ "keywords": "css 3d,3dtransforms,translate3d,transform3d"
11707
+ },
11708
+ "sharedworkers": {
11709
+ "title": "Shared Web Workers",
11710
+ "description": "Method of allowing multiple scripts to communicate with a single web worker.",
11711
+ "spec": "http://www.w3.org/TR/workers/#shared-workers-introduction",
11712
+ "status": "cr",
11713
+ "links": [{
11714
+ "url": "http://www.sitepoint.com/javascript-shared-web-workers-html5/",
11715
+ "title": "Sitepoint article"
11716
+ }, {
11717
+ "url": "http://greenido.wordpress.com/2011/11/03/web-workers-part-3-out-of-3-shared-wrokers/",
11718
+ "title": "Blog post"
11719
+ }],
11720
+ "categories": ["JS API"],
11721
+ "stats": {
11722
+ "ie": {
11723
+ "5.5": "n",
11724
+ "6": "n",
11725
+ "7": "n",
11726
+ "8": "n",
11727
+ "9": "n",
11728
+ "10": "n",
11729
+ "11": "n"
11730
+ },
11731
+ "firefox": {
11732
+ "2": "n",
11733
+ "3": "n",
11734
+ "3.5": "n",
11735
+ "3.6": "n",
11736
+ "4": "n",
11737
+ "5": "n",
11738
+ "6": "n",
11739
+ "7": "n",
11740
+ "8": "n",
11741
+ "9": "n",
11742
+ "10": "n",
11743
+ "11": "n",
11744
+ "12": "n",
11745
+ "13": "n",
11746
+ "14": "n",
11747
+ "15": "n",
11748
+ "16": "n",
11749
+ "17": "n",
11750
+ "18": "n",
11751
+ "19": "n",
11752
+ "20": "n",
11753
+ "21": "n",
11754
+ "22": "n",
11755
+ "23": "n",
11756
+ "24": "n",
11757
+ "25": "n",
11758
+ "26": "u",
11759
+ "27": "u"
11760
+ },
11761
+ "chrome": {
11762
+ "4": "y",
11763
+ "5": "y",
11764
+ "6": "y",
11765
+ "7": "y",
11766
+ "8": "y",
11767
+ "9": "y",
11768
+ "10": "y",
11769
+ "11": "y",
11770
+ "12": "y",
11771
+ "13": "y",
11772
+ "14": "y",
11773
+ "15": "y",
11774
+ "16": "y",
11775
+ "17": "y",
11776
+ "18": "y",
11777
+ "19": "y",
11778
+ "20": "y",
11779
+ "21": "y",
11780
+ "22": "y",
11781
+ "23": "y",
11782
+ "24": "y",
11783
+ "25": "y",
11784
+ "26": "y",
11785
+ "27": "y",
11786
+ "28": "y",
11787
+ "29": "y",
11788
+ "30": "y",
11789
+ "31": "y",
11790
+ "32": "y"
11791
+ },
11792
+ "safari": {
11793
+ "3.1": "n",
11794
+ "3.2": "n",
11795
+ "4": "n",
11796
+ "5": "y",
11797
+ "5.1": "y",
11798
+ "6": "y",
11799
+ "6.1": "y",
11800
+ "7": "y"
11801
+ },
11802
+ "opera": {
11803
+ "9": "n",
11804
+ "9.5-9.6": "n",
11805
+ "10.0-10.1": "n",
11806
+ "10.5": "n",
11807
+ "10.6": "y",
11808
+ "11": "y",
11809
+ "11.1": "y",
11810
+ "11.5": "y",
11811
+ "11.6": "y",
11812
+ "12": "y",
11813
+ "12.1": "y",
11814
+ "15": "y",
11815
+ "16": "y",
11816
+ "17": "y",
11817
+ "18": "y"
11818
+ },
11819
+ "ios_saf": {
11820
+ "3.2": "n",
11821
+ "4.0-4.1": "n",
11822
+ "4.2-4.3": "n",
11823
+ "5.0-5.1": "y",
11824
+ "6.0-6.1": "y",
11825
+ "7.0": "n"
11826
+ },
11827
+ "op_mini": {
11828
+ "5.0-7.0": "n"
11829
+ },
11830
+ "android": {
11831
+ "2.1": "n",
11832
+ "2.2": "n",
11833
+ "2.3": "n",
11834
+ "3": "n",
11835
+ "4": "n",
11836
+ "4.1": "n",
11837
+ "4.2-4.3": "n",
11838
+ "4.4": "n"
11839
+ },
11840
+ "bb": {
11841
+ "7": "y",
11842
+ "10": "y"
11843
+ },
11844
+ "op_mob": {
11845
+ "10": "u",
11846
+ "11": "y",
11847
+ "11.1": "y",
11848
+ "11.5": "y",
11849
+ "12": "y",
11850
+ "12.1": "y",
11851
+ "0": "n"
11852
+ },
11853
+ "and_chr": {
11854
+ "0": "n"
11855
+ },
11856
+ "and_ff": {
11857
+ "0": "n"
11858
+ },
11859
+ "ie_mob": {
11860
+ "10": "n"
11861
+ }
11862
+ },
11863
+ "notes": "Expected to be supported in Firefox 27.",
11864
+ "usage_perc_y": 40.07,
11865
+ "usage_perc_a": 0,
11866
+ "ucprefix": false,
11867
+ "parent": "webworkers",
11868
+ "keywords": "shared worker"
11869
+ },
11870
+ "css-hyphens": {
11871
+ "title": "CSS Hyphenation",
11872
+ "description": "Method of controlling when words at the end of lines should be hyphenated using the \"hyphens\" property.",
11873
+ "spec": "http://www.w3.org/TR/css3-text/#hyphenation",
11874
+ "status": "wd",
11875
+ "links": [{
11876
+ "url": "https://developer.mozilla.org/en/CSS/hyphens",
11877
+ "title": "MDN article"
11878
+ }, {
11879
+ "url": "http://docs.webplatform.org/wiki/css/properties/hyphens",
11880
+ "title": "WebPlatform Docs"
11881
+ }, {
11882
+ "url": "http://blog.fontdeck.com/post/9037028497/hyphens",
11883
+ "title": "Blog post"
11884
+ }],
11885
+ "categories": ["CSS3"],
11886
+ "stats": {
11887
+ "ie": {
11888
+ "5.5": "n",
11889
+ "6": "n",
11890
+ "7": "n",
11891
+ "8": "n",
11892
+ "9": "n",
11893
+ "10": "y x",
11894
+ "11": "y x"
11895
+ },
11896
+ "firefox": {
11897
+ "2": "n",
11898
+ "3": "n",
11899
+ "3.5": "n",
11900
+ "3.6": "n",
11901
+ "4": "n",
11902
+ "5": "n",
11903
+ "6": "y x",
11904
+ "7": "y x",
11905
+ "8": "y x",
11906
+ "9": "y x",
11907
+ "10": "y x",
11908
+ "11": "y x",
11909
+ "12": "y x",
11910
+ "13": "y x",
11911
+ "14": "y x",
11912
+ "15": "y x",
11913
+ "16": "y x",
11914
+ "17": "y x",
11915
+ "18": "y x",
11916
+ "19": "y x",
11917
+ "20": "y x",
11918
+ "21": "y x",
11919
+ "22": "y x",
11920
+ "23": "y x",
11921
+ "24": "y x",
11922
+ "25": "y x",
11923
+ "26": "y x",
11924
+ "27": "y x"
11925
+ },
11926
+ "chrome": {
11927
+ "4": "n",
11928
+ "5": "n",
11929
+ "6": "n",
11930
+ "7": "n",
11931
+ "8": "n",
11932
+ "9": "n",
11933
+ "10": "n",
11934
+ "11": "n",
11935
+ "12": "n",
11936
+ "13": "n",
11937
+ "14": "n",
11938
+ "15": "n",
11939
+ "16": "n",
11940
+ "17": "n",
11941
+ "18": "n",
11942
+ "19": "n",
11943
+ "20": "n",
11944
+ "21": "n",
11945
+ "22": "n",
11946
+ "23": "n",
11947
+ "24": "n",
11948
+ "25": "n",
11949
+ "26": "n",
11950
+ "27": "n",
11951
+ "28": "n",
11952
+ "29": "n",
11953
+ "30": "n",
11954
+ "31": "n",
11955
+ "32": "n"
11956
+ },
11957
+ "safari": {
11958
+ "3.1": "n",
11959
+ "3.2": "n",
11960
+ "4": "n",
11961
+ "5": "n",
11962
+ "5.1": "y x",
11963
+ "6": "y x",
11964
+ "6.1": "y x",
11965
+ "7": "y x"
11966
+ },
11967
+ "opera": {
11968
+ "9": "n",
11969
+ "9.5-9.6": "n",
11970
+ "10.0-10.1": "n",
11971
+ "10.5": "n",
11972
+ "10.6": "n",
11973
+ "11": "n",
11974
+ "11.1": "n",
11975
+ "11.5": "n",
11976
+ "11.6": "n",
11977
+ "12": "n",
11978
+ "12.1": "n",
11979
+ "15": "n",
11980
+ "16": "n",
11981
+ "17": "n",
11982
+ "18": "n"
11983
+ },
11984
+ "ios_saf": {
11985
+ "3.2": "n",
11986
+ "4.0-4.1": "n",
11987
+ "4.2-4.3": "y x",
11988
+ "5.0-5.1": "y x",
11989
+ "6.0-6.1": "y x",
11990
+ "7.0": "y x"
11991
+ },
11992
+ "op_mini": {
11993
+ "5.0-7.0": "n"
11994
+ },
11995
+ "android": {
11996
+ "2.1": "n",
11997
+ "2.2": "n",
11998
+ "2.3": "n",
11999
+ "3": "n",
12000
+ "4": "n",
12001
+ "4.1": "n",
12002
+ "4.2-4.3": "n",
12003
+ "4.4": "n"
12004
+ },
12005
+ "bb": {
12006
+ "7": "n",
12007
+ "10": "n"
12008
+ },
12009
+ "op_mob": {
12010
+ "10": "n",
12011
+ "11": "n",
12012
+ "11.1": "n",
12013
+ "11.5": "n",
12014
+ "12": "n",
12015
+ "12.1": "n",
12016
+ "0": "n"
12017
+ },
12018
+ "and_chr": {
12019
+ "0": "n"
12020
+ },
12021
+ "and_ff": {
12022
+ "0": "y x"
12023
+ },
12024
+ "ie_mob": {
12025
+ "10": "n"
12026
+ }
12027
+ },
12028
+ "notes": "Chrome 29- and Android 4.0 Browser support \"-webkit-hyphens: none\", but not the \"auto\" property. Chrome 30+ doesn't support it either.",
12029
+ "usage_perc_y": 33.31,
12030
+ "usage_perc_a": 0,
12031
+ "ucprefix": false,
12032
+ "parent": "",
12033
+ "keywords": "hyphen,shy"
12034
+ },
12035
+ "css-transitions": {
12036
+ "title": "CSS3 Transitions",
12037
+ "description": "Simple method of animating certain properties of an element",
12038
+ "spec": "http://www.w3.org/TR/css3-transitions/",
12039
+ "status": "wd",
12040
+ "links": [{
12041
+ "url": "http://docs.webplatform.org/wiki/css/properties/transition",
12042
+ "title": "WebPlatform Docs"
12043
+ }, {
12044
+ "url": "http://www.webdesignerdepot.com/2010/01/css-transitions-101/",
12045
+ "title": "Article on usage"
12046
+ }, {
12047
+ "url": "http://www.opera.com/docs/specs/presto2.12/css/transitions/#anima",
12048
+ "title": "Animation of property types support in Opera"
12049
+ }, {
12050
+ "url": "http://www.css3files.com/transition/",
12051
+ "title": "Information page"
12052
+ }, {
12053
+ "url": "http://www.the-art-of-web.com/css/timing-function/",
12054
+ "title": "Examples on timing functions"
12055
+ }],
12056
+ "categories": ["CSS3"],
12057
+ "stats": {
12058
+ "ie": {
12059
+ "5.5": "n",
12060
+ "6": "n",
12061
+ "7": "n",
12062
+ "8": "n",
12063
+ "9": "n",
12064
+ "10": "y",
12065
+ "11": "y"
12066
+ },
12067
+ "firefox": {
12068
+ "2": "n",
12069
+ "3": "n",
12070
+ "3.5": "n",
12071
+ "3.6": "n",
12072
+ "4": "y x",
12073
+ "5": "y x",
12074
+ "6": "y x",
12075
+ "7": "y x",
12076
+ "8": "y x",
12077
+ "9": "y x",
12078
+ "10": "y x",
12079
+ "11": "y x",
12080
+ "12": "y x",
12081
+ "13": "y x",
12082
+ "14": "y x",
12083
+ "15": "y x",
12084
+ "16": "y",
12085
+ "17": "y",
12086
+ "18": "y",
12087
+ "19": "y",
12088
+ "20": "y",
12089
+ "21": "y",
12090
+ "22": "y",
12091
+ "23": "y",
12092
+ "24": "y",
12093
+ "25": "y",
12094
+ "26": "y",
12095
+ "27": "y"
12096
+ },
12097
+ "chrome": {
12098
+ "4": "y x",
12099
+ "5": "y x",
12100
+ "6": "y x",
12101
+ "7": "y x",
12102
+ "8": "y x",
12103
+ "9": "y x",
12104
+ "10": "y x",
12105
+ "11": "y x",
12106
+ "12": "y x",
12107
+ "13": "y x",
12108
+ "14": "y x",
12109
+ "15": "y x",
12110
+ "16": "y x",
12111
+ "17": "y x",
12112
+ "18": "y x",
12113
+ "19": "y x",
12114
+ "20": "y x",
12115
+ "21": "y x",
12116
+ "22": "y x",
12117
+ "23": "y x",
12118
+ "24": "y x",
12119
+ "25": "y x",
12120
+ "26": "y",
12121
+ "27": "y",
12122
+ "28": "y",
12123
+ "29": "y",
12124
+ "30": "y",
12125
+ "31": "y",
12126
+ "32": "y"
12127
+ },
12128
+ "safari": {
12129
+ "3.1": "y x",
12130
+ "3.2": "y x",
12131
+ "4": "y x",
12132
+ "5": "y x",
12133
+ "5.1": "y x",
12134
+ "6": "y x",
12135
+ "6.1": "y",
12136
+ "7": "y"
12137
+ },
12138
+ "opera": {
12139
+ "9": "n",
12140
+ "9.5-9.6": "n",
12141
+ "10.0-10.1": "n",
12142
+ "10.5": "y x",
12143
+ "10.6": "y x",
12144
+ "11": "y x",
12145
+ "11.1": "y x",
12146
+ "11.5": "y x",
12147
+ "11.6": "y x",
12148
+ "12": "y x",
12149
+ "12.1": "y",
12150
+ "15": "y",
12151
+ "16": "y",
12152
+ "17": "y",
12153
+ "18": "y"
12154
+ },
12155
+ "ios_saf": {
12156
+ "3.2": "y x",
12157
+ "4.0-4.1": "y x",
12158
+ "4.2-4.3": "y x",
12159
+ "5.0-5.1": "y x",
12160
+ "6.0-6.1": "y x",
12161
+ "7.0": "y"
12162
+ },
12163
+ "op_mini": {
12164
+ "5.0-7.0": "n"
12165
+ },
12166
+ "android": {
12167
+ "2.1": "y x",
12168
+ "2.2": "y x",
12169
+ "2.3": "y x",
12170
+ "3": "y x",
12171
+ "4": "y x",
12172
+ "4.1": "y x",
12173
+ "4.2-4.3": "y x",
12174
+ "4.4": "y"
12175
+ },
12176
+ "bb": {
12177
+ "7": "y x",
12178
+ "10": "y x"
12179
+ },
12180
+ "op_mob": {
12181
+ "10": "y x",
12182
+ "11": "y x",
12183
+ "11.1": "y x",
12184
+ "11.5": "y x",
12185
+ "12": "y x",
12186
+ "12.1": "y",
12187
+ "0": "y"
12188
+ },
12189
+ "and_chr": {
12190
+ "0": "y"
12191
+ },
12192
+ "and_ff": {
12193
+ "0": "y"
12194
+ },
12195
+ "ie_mob": {
12196
+ "10": "y"
12197
+ }
12198
+ },
12199
+ "notes": "",
12200
+ "usage_perc_y": 75.27,
12201
+ "usage_perc_a": 0,
12202
+ "ucprefix": false,
12203
+ "parent": "",
12204
+ "keywords": "css transition"
12205
+ },
12206
+ "font-feature": {
12207
+ "title": "Font feature settings",
12208
+ "description": "Method of applying advanced typographic and language-specific font features to supported OpenType fonts.",
12209
+ "spec": "http://w3.org/TR/css3-fonts/#font-rend-props",
12210
+ "status": "wd",
12211
+ "links": [{
12212
+ "url": "http://docs.webplatform.org/wiki/css/properties/font-feature-settings",
12213
+ "title": "WebPlatform Docs"
12214
+ }, {
12215
+ "url": "http://hacks.mozilla.org/2010/11/firefox-4-font-feature-support/",
12216
+ "title": "Mozilla hacks article"
12217
+ }, {
12218
+ "url": "http://html5accessibility.com/",
12219
+ "title": "Detailed tables on accessability support"
12220
+ }, {
12221
+ "url": "http://ie.microsoft.com/testdrive/Graphics/opentype/",
12222
+ "title": "Demo pages (IE/Firefox only)"
12223
+ }],
12224
+ "categories": ["CSS3"],
12225
+ "stats": {
12226
+ "ie": {
12227
+ "5.5": "n",
12228
+ "6": "n",
12229
+ "7": "n",
12230
+ "8": "n",
12231
+ "9": "n",
12232
+ "10": "y",
12233
+ "11": "y"
12234
+ },
12235
+ "firefox": {
12236
+ "2": "n",
12237
+ "3": "n",
12238
+ "3.5": "n",
12239
+ "3.6": "n",
12240
+ "4": "a x",
12241
+ "5": "a x",
12242
+ "6": "a x",
12243
+ "7": "a x",
12244
+ "8": "a x",
12245
+ "9": "a x",
12246
+ "10": "a x",
12247
+ "11": "a x",
12248
+ "12": "a x",
12249
+ "13": "a x",
12250
+ "14": "a x",
12251
+ "15": "y x",
12252
+ "16": "y x",
12253
+ "17": "y x",
12254
+ "18": "y x",
12255
+ "19": "y x",
12256
+ "20": "y x",
12257
+ "21": "y x",
12258
+ "22": "y x",
12259
+ "23": "y x",
12260
+ "24": "y x",
12261
+ "25": "y x",
12262
+ "26": "y x",
12263
+ "27": "y x"
12264
+ },
12265
+ "chrome": {
12266
+ "4": "n",
12267
+ "5": "n",
12268
+ "6": "n",
12269
+ "7": "n",
12270
+ "8": "n",
12271
+ "9": "n",
12272
+ "10": "n",
12273
+ "11": "n",
12274
+ "12": "n",
12275
+ "13": "n",
12276
+ "14": "n",
12277
+ "15": "n",
12278
+ "16": "a x",
12279
+ "17": "a x",
12280
+ "18": "a x",
12281
+ "19": "a x",
12282
+ "20": "a x",
12283
+ "21": "y x",
12284
+ "22": "y x",
12285
+ "23": "y x",
12286
+ "24": "y x",
12287
+ "25": "y x",
12288
+ "26": "y x",
12289
+ "27": "y x",
12290
+ "28": "y x",
12291
+ "29": "y x",
12292
+ "30": "y x",
12293
+ "31": "y x",
12294
+ "32": "y x"
12295
+ },
12296
+ "safari": {
12297
+ "3.1": "n",
12298
+ "3.2": "n",
12299
+ "4": "a",
12300
+ "5": "a",
12301
+ "5.1": "a",
12302
+ "6": "a",
12303
+ "6.1": "y x",
12304
+ "7": "y x"
12305
+ },
12306
+ "opera": {
12307
+ "9": "n",
12308
+ "9.5-9.6": "n",
12309
+ "10.0-10.1": "n",
12310
+ "10.5": "n",
12311
+ "10.6": "n",
12312
+ "11": "n",
12313
+ "11.1": "n",
12314
+ "11.5": "n",
12315
+ "11.6": "n",
12316
+ "12": "n",
12317
+ "12.1": "n",
12318
+ "15": "y x",
12319
+ "16": "y x",
12320
+ "17": "y x",
12321
+ "18": "y x"
12322
+ },
12323
+ "ios_saf": {
12324
+ "3.2": "a",
12325
+ "4.0-4.1": "a",
12326
+ "4.2-4.3": "a",
12327
+ "5.0-5.1": "a",
12328
+ "6.0-6.1": "a",
12329
+ "7.0": "y x"
12330
+ },
12331
+ "op_mini": {
12332
+ "5.0-7.0": "n"
12333
+ },
12334
+ "android": {
12335
+ "2.1": "n",
12336
+ "2.2": "n",
12337
+ "2.3": "n",
12338
+ "3": "n",
12339
+ "4": "n",
12340
+ "4.1": "n",
12341
+ "4.2-4.3": "n",
12342
+ "4.4": "y x"
12343
+ },
12344
+ "bb": {
12345
+ "7": "n",
12346
+ "10": "y x"
12347
+ },
12348
+ "op_mob": {
12349
+ "10": "n",
12350
+ "11": "n",
12351
+ "11.1": "n",
12352
+ "11.5": "n",
12353
+ "12": "n",
12354
+ "12.1": "n",
12355
+ "0": "y x"
12356
+ },
12357
+ "and_chr": {
12358
+ "0": "y x"
12359
+ },
12360
+ "and_ff": {
12361
+ "0": "y x"
12362
+ },
12363
+ "ie_mob": {
12364
+ "10": "n"
12365
+ }
12366
+ },
12367
+ "notes": "Partial support in older Firefox versions refers to using an older syntax. Partial support in older Chrome versions refers to lacking support in Mac OS X. ",
12368
+ "usage_perc_y": 62.13,
12369
+ "usage_perc_a": 6.41,
12370
+ "ucprefix": false,
12371
+ "parent": "",
12372
+ "keywords": "font-feature,font-feature-settings,kern,kerning,font-variant-alternates,ligatures,font-variant-ligatures"
12373
+ },
12374
+ "css-animation": {
12375
+ "title": "CSS3 Animation",
12376
+ "description": "Complex method of animating certain properties of an element",
12377
+ "spec": "http://www.w3.org/TR/css3-animations/",
12378
+ "status": "wd",
12379
+ "links": [{
12380
+ "url": "http://docs.webplatform.org/wiki/css/properties/animations",
12381
+ "title": "WebPlatform Docs"
12382
+ }, {
12383
+ "url": "http://www.css3files.com/animation/",
12384
+ "title": "Information page"
12385
+ }, {
12386
+ "url": "http://robertnyman.com/2010/05/06/css3-animations/",
12387
+ "title": "Blog post on usage"
12388
+ }],
12389
+ "categories": ["CSS3"],
12390
+ "stats": {
12391
+ "ie": {
12392
+ "5.5": "n",
12393
+ "6": "n",
12394
+ "7": "n",
12395
+ "8": "n",
12396
+ "9": "n",
12397
+ "10": "y",
12398
+ "11": "y"
12399
+ },
12400
+ "firefox": {
12401
+ "2": "n",
12402
+ "3": "n",
12403
+ "3.5": "n",
12404
+ "3.6": "n",
12405
+ "4": "n",
12406
+ "5": "y x",
12407
+ "6": "y x",
12408
+ "7": "y x",
12409
+ "8": "y x",
12410
+ "9": "y x",
12411
+ "10": "y x",
12412
+ "11": "y x",
12413
+ "12": "y x",
12414
+ "13": "y x",
12415
+ "14": "y x",
12416
+ "15": "y x",
12417
+ "16": "y",
12418
+ "17": "y",
12419
+ "18": "y",
12420
+ "19": "y",
12421
+ "20": "y",
12422
+ "21": "y",
12423
+ "22": "y",
12424
+ "23": "y",
12425
+ "24": "y",
12426
+ "25": "y",
12427
+ "26": "y",
12428
+ "27": "y"
12429
+ },
12430
+ "chrome": {
12431
+ "4": "y x",
12432
+ "5": "y x",
12433
+ "6": "y x",
12434
+ "7": "y x",
12435
+ "8": "y x",
12436
+ "9": "y x",
12437
+ "10": "y x",
12438
+ "11": "y x",
12439
+ "12": "y x",
12440
+ "13": "y x",
12441
+ "14": "y x",
12442
+ "15": "y x",
12443
+ "16": "y x",
12444
+ "17": "y x",
12445
+ "18": "y x",
12446
+ "19": "y x",
12447
+ "20": "y x",
12448
+ "21": "y x",
12449
+ "22": "y x",
12450
+ "23": "y x",
12451
+ "24": "y x",
12452
+ "25": "y x",
12453
+ "26": "y x",
12454
+ "27": "y x",
12455
+ "28": "y x",
12456
+ "29": "y x",
12457
+ "30": "y x",
12458
+ "31": "y x",
12459
+ "32": "y x"
12460
+ },
12461
+ "safari": {
12462
+ "3.1": "n",
12463
+ "3.2": "n",
12464
+ "4": "y x",
12465
+ "5": "y x",
12466
+ "5.1": "y x",
12467
+ "6": "y x",
12468
+ "6.1": "y x",
12469
+ "7": "y x"
12470
+ },
12471
+ "opera": {
12472
+ "9": "n",
12473
+ "9.5-9.6": "n",
12474
+ "10.0-10.1": "n",
12475
+ "10.5": "n",
12476
+ "10.6": "n",
12477
+ "11": "n",
12478
+ "11.1": "n",
12479
+ "11.5": "n",
12480
+ "11.6": "n",
12481
+ "12": "y x",
12482
+ "12.1": "y",
12483
+ "15": "y x",
12484
+ "16": "y x",
12485
+ "17": "y x",
12486
+ "18": "y x"
12487
+ },
12488
+ "ios_saf": {
12489
+ "3.2": "y x",
12490
+ "4.0-4.1": "y x",
12491
+ "4.2-4.3": "y x",
12492
+ "5.0-5.1": "y x",
12493
+ "6.0-6.1": "y x",
12494
+ "7.0": "y x"
12495
+ },
12496
+ "op_mini": {
12497
+ "5.0-7.0": "n"
12498
+ },
12499
+ "android": {
12500
+ "2.1": "a x",
12501
+ "2.2": "a x",
12502
+ "2.3": "a x",
12503
+ "3": "a x",
12504
+ "4": "y x",
12505
+ "4.1": "y x",
12506
+ "4.2-4.3": "y x",
12507
+ "4.4": "y x"
12508
+ },
12509
+ "bb": {
12510
+ "7": "y x",
12511
+ "10": "y x"
12512
+ },
12513
+ "op_mob": {
12514
+ "10": "n",
12515
+ "11": "n",
12516
+ "11.1": "n",
12517
+ "11.5": "n",
12518
+ "12": "n",
12519
+ "12.1": "y",
12520
+ "0": "y x"
12521
+ },
12522
+ "and_chr": {
12523
+ "0": "y x"
12524
+ },
12525
+ "and_ff": {
12526
+ "0": "y"
12527
+ },
12528
+ "ie_mob": {
12529
+ "10": "y"
12530
+ }
12531
+ },
12532
+ "notes": "Partial support in Android browser refers to buggy behavior in different scenarios.",
12533
+ "usage_perc_y": 73.62,
12534
+ "usage_perc_a": 1.44,
12535
+ "ucprefix": false,
12536
+ "parent": "",
12537
+ "keywords": "animations,css-animations,keyframe,keyframes"
12538
+ },
12539
+ "css-gradients": {
12540
+ "title": "CSS Gradients",
12541
+ "description": "Method of defining a linear or radial color gradient as a CSS image.",
12542
+ "spec": "http://www.w3.org/TR/css3-images/",
12543
+ "status": "cr",
12544
+ "links": [{
12545
+ "url": "http://www.colorzilla.com/gradient-editor/",
12546
+ "title": "Cross-browser editor"
12547
+ }, {
12548
+ "url": "http://docs.webplatform.org/wiki/css/functions/linear-gradient",
12549
+ "title": "WebPlatform Docs"
12550
+ }, {
12551
+ "url": "http://www.css3files.com/gradient/",
12552
+ "title": "Information page"
12553
+ }, {
12554
+ "url": "http://css3pie.com/",
12555
+ "title": "Tool to emulate support in IE"
12556
+ }],
12557
+ "categories": ["CSS3"],
12558
+ "stats": {
12559
+ "ie": {
12560
+ "5.5": "n",
12561
+ "6": "n",
12562
+ "7": "n",
12563
+ "8": "n",
12564
+ "9": "n",
12565
+ "10": "y",
12566
+ "11": "y"
12567
+ },
12568
+ "firefox": {
12569
+ "2": "n",
12570
+ "3": "n",
12571
+ "3.5": "n",
12572
+ "3.6": "y x",
12573
+ "4": "y x",
12574
+ "5": "y x",
12575
+ "6": "y x",
12576
+ "7": "y x",
12577
+ "8": "y x",
12578
+ "9": "y x",
12579
+ "10": "y x",
12580
+ "11": "y x",
12581
+ "12": "y x",
12582
+ "13": "y x",
12583
+ "14": "y x",
12584
+ "15": "y x",
12585
+ "16": "y",
12586
+ "17": "y",
12587
+ "18": "y",
12588
+ "19": "y",
12589
+ "20": "y",
12590
+ "21": "y",
12591
+ "22": "y",
12592
+ "23": "y",
12593
+ "24": "y",
12594
+ "25": "y",
12595
+ "26": "y",
12596
+ "27": "y"
12597
+ },
12598
+ "chrome": {
12599
+ "4": "a x",
12600
+ "5": "a x",
12601
+ "6": "a x",
12602
+ "7": "a x",
12603
+ "8": "a x",
12604
+ "9": "a x",
12605
+ "10": "y x",
12606
+ "11": "y x",
12607
+ "12": "y x",
12608
+ "13": "y x",
12609
+ "14": "y x",
12610
+ "15": "y x",
12611
+ "16": "y x",
12612
+ "17": "y x",
12613
+ "18": "y x",
12614
+ "19": "y x",
12615
+ "20": "y x",
12616
+ "21": "y x",
12617
+ "22": "y x",
12618
+ "23": "y x",
12619
+ "24": "y x",
12620
+ "25": "y x",
12621
+ "26": "y",
12622
+ "27": "y",
12623
+ "28": "y",
12624
+ "29": "y",
12625
+ "30": "y",
12626
+ "31": "y",
12627
+ "32": "y"
12628
+ },
12629
+ "safari": {
12630
+ "3.1": "n",
12631
+ "3.2": "n",
12632
+ "4": "a x",
12633
+ "5": "a x",
12634
+ "5.1": "y x",
12635
+ "6": "y x",
12636
+ "6.1": "y",
12637
+ "7": "y"
12638
+ },
12639
+ "opera": {
12640
+ "9": "n",
12641
+ "9.5-9.6": "n",
12642
+ "10.0-10.1": "n",
12643
+ "10.5": "n",
12644
+ "10.6": "n",
12645
+ "11": "n",
12646
+ "11.1": "a x",
12647
+ "11.5": "a x",
12648
+ "11.6": "y x",
12649
+ "12": "y x",
12650
+ "12.1": "y",
12651
+ "15": "y",
12652
+ "16": "y",
12653
+ "17": "y",
12654
+ "18": "y"
12655
+ },
12656
+ "ios_saf": {
12657
+ "3.2": "a x",
12658
+ "4.0-4.1": "a x",
12659
+ "4.2-4.3": "a x",
12660
+ "5.0-5.1": "y x",
12661
+ "6.0-6.1": "y x",
12662
+ "7.0": "y"
12663
+ },
12664
+ "op_mini": {
12665
+ "5.0-7.0": "n"
12666
+ },
12667
+ "android": {
12668
+ "2.1": "a x",
12669
+ "2.2": "a x",
12670
+ "2.3": "a x",
12671
+ "3": "a x",
12672
+ "4": "y x",
12673
+ "4.1": "y x",
12674
+ "4.2-4.3": "y x",
12675
+ "4.4": "y"
12676
+ },
12677
+ "bb": {
12678
+ "7": "a x",
12679
+ "10": "y x"
12680
+ },
12681
+ "op_mob": {
12682
+ "10": "n",
12683
+ "11": "n",
12684
+ "11.1": "a x",
12685
+ "11.5": "a x",
12686
+ "12": "y x",
12687
+ "12.1": "y",
12688
+ "0": "y"
12689
+ },
12690
+ "and_chr": {
12691
+ "0": "y"
12692
+ },
12693
+ "and_ff": {
12694
+ "0": "y"
12695
+ },
12696
+ "ie_mob": {
12697
+ "10": "y"
12698
+ }
12699
+ },
12700
+ "notes": "Partial support in Opera 11.10 and 11.50 also refers to only having support for linear gradients. Support can be somewhat emulated in older IE versions using the non-standard \"gradient\" filter. Firefox 10+, Opera 11.6+, Chrome 26+ and IE10 also support the new \"to (side)\" syntax.",
12701
+ "usage_perc_y": 73.31,
12702
+ "usage_perc_a": 2.22,
12703
+ "ucprefix": false,
12704
+ "parent": "",
12705
+ "keywords": "linear,linear-gradient,gradiant"
12706
+ },
12707
+ "css-canvas": {
12708
+ "title": "CSS Canvas Drawings",
12709
+ "description": "Method of using HTML5 Canvas as a background image",
12710
+ "spec": "http://webkit.org/blog/176/css-canvas-drawing/",
12711
+ "status": "unoff",
12712
+ "links": [{
12713
+ "url": "http://webkit.org/blog/176/css-canvas-drawing/",
12714
+ "title": "Webkit blog post"
12715
+ }],
12716
+ "categories": ["CSS"],
12717
+ "stats": {
12718
+ "ie": {
12719
+ "5.5": "n",
12720
+ "6": "n",
12721
+ "7": "n",
12722
+ "8": "n",
12723
+ "9": "n",
12724
+ "10": "n",
12725
+ "11": "n"
12726
+ },
12727
+ "firefox": {
12728
+ "2": "n",
12729
+ "3": "n",
12730
+ "3.5": "n",
12731
+ "3.6": "n",
12732
+ "4": "n",
12733
+ "5": "n",
12734
+ "6": "n",
12735
+ "7": "n",
12736
+ "8": "n",
12737
+ "9": "n",
12738
+ "10": "n",
12739
+ "11": "n",
12740
+ "12": "n",
12741
+ "13": "n",
12742
+ "14": "n",
12743
+ "15": "n",
12744
+ "16": "n",
12745
+ "17": "n",
12746
+ "18": "n",
12747
+ "19": "n",
12748
+ "20": "n",
12749
+ "21": "n",
12750
+ "22": "n",
12751
+ "23": "n",
12752
+ "24": "n",
12753
+ "25": "n",
12754
+ "26": "u",
12755
+ "27": "u"
12756
+ },
12757
+ "chrome": {
12758
+ "4": "y x",
12759
+ "5": "y x",
12760
+ "6": "y x",
12761
+ "7": "y x",
12762
+ "8": "y x",
12763
+ "9": "y x",
12764
+ "10": "y x",
12765
+ "11": "y x",
12766
+ "12": "y x",
12767
+ "13": "y x",
12768
+ "14": "y x",
12769
+ "15": "y x",
12770
+ "16": "y x",
12771
+ "17": "y x",
12772
+ "18": "y x",
12773
+ "19": "y x",
12774
+ "20": "y x",
12775
+ "21": "y x",
12776
+ "22": "y x",
12777
+ "23": "y x",
12778
+ "24": "y x",
12779
+ "25": "y x",
12780
+ "26": "y x",
12781
+ "27": "y x",
12782
+ "28": "y x",
12783
+ "29": "y x",
12784
+ "30": "y x",
12785
+ "31": "y x",
12786
+ "32": "y x"
12787
+ },
12788
+ "safari": {
12789
+ "3.1": "n",
12790
+ "3.2": "n",
12791
+ "4": "y x",
12792
+ "5": "y x",
12793
+ "5.1": "y x",
12794
+ "6": "y x",
12795
+ "6.1": "y x",
12796
+ "7": "y x"
12797
+ },
12798
+ "opera": {
12799
+ "9": "n",
12800
+ "9.5-9.6": "n",
12801
+ "10.0-10.1": "n",
12802
+ "10.5": "n",
12803
+ "10.6": "n",
12804
+ "11": "n",
12805
+ "11.1": "n",
12806
+ "11.5": "n",
12807
+ "11.6": "n",
12808
+ "12": "n",
12809
+ "12.1": "n",
12810
+ "15": "y x",
12811
+ "16": "y x",
12812
+ "17": "y x",
12813
+ "18": "y x"
12814
+ },
12815
+ "ios_saf": {
12816
+ "3.2": "y x",
12817
+ "4.0-4.1": "y x",
12818
+ "4.2-4.3": "y x",
12819
+ "5.0-5.1": "y x",
12820
+ "6.0-6.1": "y x",
12821
+ "7.0": "y x"
12822
+ },
12823
+ "op_mini": {
12824
+ "5.0-7.0": "n"
12825
+ },
12826
+ "android": {
12827
+ "2.1": "y x",
12828
+ "2.2": "y x",
12829
+ "2.3": "y x",
12830
+ "3": "y x",
12831
+ "4": "y x",
12832
+ "4.1": "y x",
12833
+ "4.2-4.3": "y x",
12834
+ "4.4": "y x"
12835
+ },
12836
+ "bb": {
12837
+ "7": "y x",
12838
+ "10": "y x"
12839
+ },
12840
+ "op_mob": {
12841
+ "10": "n",
12842
+ "11": "n",
12843
+ "11.1": "n",
12844
+ "11.5": "n",
12845
+ "12": "n",
12846
+ "12.1": "n",
12847
+ "0": "y x"
12848
+ },
12849
+ "and_chr": {
12850
+ "0": "y x"
12851
+ },
12852
+ "and_ff": {
12853
+ "0": "n"
12854
+ },
12855
+ "ie_mob": {
12856
+ "10": "n"
12857
+ }
12858
+ },
12859
+ "notes": "Proposal by Webkit, being considered for W3C standardization. A similar effect can be achieved in Firefox 4+ using the -moz-element() background property",
12860
+ "usage_perc_y": 48.41,
12861
+ "usage_perc_a": 0,
12862
+ "ucprefix": false,
12863
+ "parent": "",
12864
+ "keywords": ""
12865
+ },
12866
+ "css-reflections": {
12867
+ "title": "CSS Reflections",
12868
+ "description": "Method of displaying a reflection of an element",
12869
+ "spec": "http://webkit.org/blog/182/css-reflections/",
12870
+ "status": "unoff",
12871
+ "links": [{
12872
+ "url": "http://webkit.org/blog/182/css-reflections/",
12873
+ "title": "Webkit blog post"
12874
+ }],
12875
+ "categories": ["CSS"],
12876
+ "stats": {
12877
+ "ie": {
12878
+ "5.5": "n",
12879
+ "6": "n",
12880
+ "7": "n",
12881
+ "8": "n",
12882
+ "9": "n",
12883
+ "10": "n",
12884
+ "11": "n"
12885
+ },
12886
+ "firefox": {
12887
+ "2": "n",
12888
+ "3": "n",
12889
+ "3.5": "n",
12890
+ "3.6": "n",
12891
+ "4": "n",
12892
+ "5": "n",
12893
+ "6": "n",
12894
+ "7": "n",
12895
+ "8": "n",
12896
+ "9": "n",
12897
+ "10": "n",
12898
+ "11": "n",
12899
+ "12": "n",
12900
+ "13": "n",
12901
+ "14": "n",
12902
+ "15": "n",
12903
+ "16": "n",
12904
+ "17": "n",
12905
+ "18": "n",
12906
+ "19": "n",
12907
+ "20": "n",
12908
+ "21": "n",
12909
+ "22": "n",
12910
+ "23": "n",
12911
+ "24": "n",
12912
+ "25": "n",
12913
+ "26": "n",
12914
+ "27": "n"
12915
+ },
12916
+ "chrome": {
12917
+ "4": "y x",
12918
+ "5": "y x",
12919
+ "6": "y x",
12920
+ "7": "y x",
12921
+ "8": "y x",
12922
+ "9": "y x",
12923
+ "10": "y x",
12924
+ "11": "y x",
12925
+ "12": "y x",
12926
+ "13": "y x",
12927
+ "14": "y x",
12928
+ "15": "y x",
12929
+ "16": "y x",
12930
+ "17": "y x",
12931
+ "18": "y x",
12932
+ "19": "y x",
12933
+ "20": "y x",
12934
+ "21": "y x",
12935
+ "22": "y x",
12936
+ "23": "y x",
12937
+ "24": "y x",
12938
+ "25": "y x",
12939
+ "26": "y x",
12940
+ "27": "y x",
12941
+ "28": "y x",
12942
+ "29": "y x",
12943
+ "30": "y x",
12944
+ "31": "y x",
12945
+ "32": "y x"
12946
+ },
12947
+ "safari": {
12948
+ "3.1": "n",
12949
+ "3.2": "n",
12950
+ "4": "y x",
12951
+ "5": "y x",
12952
+ "5.1": "y x",
12953
+ "6": "y x",
12954
+ "6.1": "y x",
12955
+ "7": "y x"
12956
+ },
12957
+ "opera": {
12958
+ "9": "n",
12959
+ "9.5-9.6": "n",
12960
+ "10.0-10.1": "n",
12961
+ "10.5": "n",
12962
+ "10.6": "n",
12963
+ "11": "n",
12964
+ "11.1": "n",
12965
+ "11.5": "n",
12966
+ "11.6": "n",
12967
+ "12": "n",
12968
+ "12.1": "n",
12969
+ "15": "y x",
12970
+ "16": "y x",
12971
+ "17": "y x",
12972
+ "18": "y x"
12973
+ },
12974
+ "ios_saf": {
12975
+ "3.2": "y x",
12976
+ "4.0-4.1": "y x",
12977
+ "4.2-4.3": "y x",
12978
+ "5.0-5.1": "y x",
12979
+ "6.0-6.1": "y x",
12980
+ "7.0": "y x"
12981
+ },
12982
+ "op_mini": {
12983
+ "5.0-7.0": "n"
12984
+ },
12985
+ "android": {
12986
+ "2.1": "y x",
12987
+ "2.2": "y x",
12988
+ "2.3": "y x",
12989
+ "3": "y x",
12990
+ "4": "y x",
12991
+ "4.1": "y x",
12992
+ "4.2-4.3": "y x",
12993
+ "4.4": "y x"
12994
+ },
12995
+ "bb": {
12996
+ "7": "y x",
12997
+ "10": "y x"
12998
+ },
12999
+ "op_mob": {
13000
+ "10": "n",
13001
+ "11": "n",
13002
+ "11.1": "n",
13003
+ "11.5": "n",
13004
+ "12": "n",
13005
+ "12.1": "n",
13006
+ "0": "y x"
13007
+ },
13008
+ "and_chr": {
13009
+ "0": "y x"
13010
+ },
13011
+ "and_ff": {
13012
+ "0": "n"
13013
+ },
13014
+ "ie_mob": {
13015
+ "10": "n"
13016
+ }
13017
+ },
13018
+ "notes": "Similar effect can be achieved in Firefox 4+ using the -moz-element() background property",
13019
+ "usage_perc_y": 48.41,
13020
+ "usage_perc_a": 0,
13021
+ "ucprefix": false,
13022
+ "parent": "",
13023
+ "keywords": "box-reflect"
13024
+ },
13025
+ "css-masks": {
13026
+ "title": "CSS Masks",
13027
+ "description": "Method of displaying part of an element, using a selected image as a mask",
13028
+ "spec": "http://www.w3.org/TR/css-masking/",
13029
+ "status": "wd",
13030
+ "links": [{
13031
+ "url": "http://docs.webplatform.org/wiki/css/properties/mask",
13032
+ "title": "WebPlatform Docs"
13033
+ }, {
13034
+ "url": "http://www.html5rocks.com/en/tutorials/masking/adobe/",
13035
+ "title": "HTML5 Rocks article"
13036
+ }, {
13037
+ "url": "http://thenittygritty.co/css-masking",
13038
+ "title": "Detailed blog post"
13039
+ }],
13040
+ "categories": ["CSS"],
13041
+ "stats": {
13042
+ "ie": {
13043
+ "5.5": "n",
13044
+ "6": "n",
13045
+ "7": "n",
13046
+ "8": "n",
13047
+ "9": "n",
13048
+ "10": "n",
13049
+ "11": "n"
13050
+ },
13051
+ "firefox": {
13052
+ "2": "n",
13053
+ "3": "n",
13054
+ "3.5": "n",
13055
+ "3.6": "n",
13056
+ "4": "n",
13057
+ "5": "n",
13058
+ "6": "n",
13059
+ "7": "n",
13060
+ "8": "n",
13061
+ "9": "n",
13062
+ "10": "n",
13063
+ "11": "n",
13064
+ "12": "n",
13065
+ "13": "n",
13066
+ "14": "n",
13067
+ "15": "n",
13068
+ "16": "n",
13069
+ "17": "n",
13070
+ "18": "n",
13071
+ "19": "n",
13072
+ "20": "n",
13073
+ "21": "n",
13074
+ "22": "n",
13075
+ "23": "n",
13076
+ "24": "n",
13077
+ "25": "n",
13078
+ "26": "u",
13079
+ "27": "u"
13080
+ },
13081
+ "chrome": {
13082
+ "4": "a x",
13083
+ "5": "a x",
13084
+ "6": "a x",
13085
+ "7": "a x",
13086
+ "8": "a x",
13087
+ "9": "a x",
13088
+ "10": "a x",
13089
+ "11": "a x",
13090
+ "12": "a x",
13091
+ "13": "a x",
13092
+ "14": "a x",
13093
+ "15": "a x",
13094
+ "16": "a x",
13095
+ "17": "a x",
13096
+ "18": "a x",
13097
+ "19": "a x",
13098
+ "20": "a x",
13099
+ "21": "a x",
13100
+ "22": "a x",
13101
+ "23": "a x",
13102
+ "24": "a x",
13103
+ "25": "a x",
13104
+ "26": "a x",
13105
+ "27": "a x",
13106
+ "28": "a x",
13107
+ "29": "a x",
13108
+ "30": "a x",
13109
+ "31": "a x",
13110
+ "32": "a x"
13111
+ },
13112
+ "safari": {
13113
+ "3.1": "n",
13114
+ "3.2": "n",
13115
+ "4": "a x",
13116
+ "5": "a x",
13117
+ "5.1": "a x",
13118
+ "6": "a x",
13119
+ "6.1": "a x",
13120
+ "7": "a x"
13121
+ },
13122
+ "opera": {
13123
+ "9": "n",
13124
+ "9.5-9.6": "n",
13125
+ "10.0-10.1": "n",
13126
+ "10.5": "n",
13127
+ "10.6": "n",
13128
+ "11": "n",
13129
+ "11.1": "n",
13130
+ "11.5": "n",
13131
+ "11.6": "n",
13132
+ "12": "n",
13133
+ "12.1": "n",
13134
+ "15": "a x",
13135
+ "16": "a x",
13136
+ "17": "a x",
13137
+ "18": "a x"
13138
+ },
13139
+ "ios_saf": {
13140
+ "3.2": "a x",
13141
+ "4.0-4.1": "a x",
13142
+ "4.2-4.3": "a x",
13143
+ "5.0-5.1": "a x",
13144
+ "6.0-6.1": "a x",
13145
+ "7.0": "a x"
13146
+ },
13147
+ "op_mini": {
13148
+ "5.0-7.0": "n"
13149
+ },
13150
+ "android": {
13151
+ "2.1": "a x",
13152
+ "2.2": "a x",
13153
+ "2.3": "a x",
13154
+ "3": "a x",
13155
+ "4": "a x",
13156
+ "4.1": "a x",
13157
+ "4.2-4.3": "a x",
13158
+ "4.4": "a x"
13159
+ },
13160
+ "bb": {
13161
+ "7": "a x",
13162
+ "10": "a x"
13163
+ },
13164
+ "op_mob": {
13165
+ "10": "n",
13166
+ "11": "n",
13167
+ "11.1": "n",
13168
+ "11.5": "n",
13169
+ "12": "n",
13170
+ "12.1": "n",
13171
+ "0": "a x"
13172
+ },
13173
+ "and_chr": {
13174
+ "0": "a x"
13175
+ },
13176
+ "and_ff": {
13177
+ "0": "n"
13178
+ },
13179
+ "ie_mob": {
13180
+ "10": "n"
13181
+ }
13182
+ },
13183
+ "notes": "Previously a WebKit-only property, now a W3C specification. Partial support refers to not yet fully supporting the new spec (details currently unknown).",
13184
+ "usage_perc_y": 0,
13185
+ "usage_perc_a": 48.41,
13186
+ "ucprefix": false,
13187
+ "parent": "",
13188
+ "keywords": ""
13189
+ },
13190
+ "svg": {
13191
+ "title": "SVG (basic support)",
13192
+ "description": "Method of displaying basic Vector Graphics features using the embed or object elements",
13193
+ "spec": "http://www.w3.org/Graphics/SVG/",
13194
+ "status": "rec",
13195
+ "links": [{
13196
+ "url": "http://en.wikipedia.org/wiki/Scalable_Vector_Graphics",
13197
+ "title": "Wikipedia"
13198
+ }, {
13199
+ "url": "http://code.google.com/p/svgweb/",
13200
+ "title": "SVG Web: Flash-based polyfill"
13201
+ }, {
13202
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/graphics.js#svg",
13203
+ "title": "has.js test"
13204
+ }, {
13205
+ "url": "http://svg-edit.googlecode.com",
13206
+ "title": "Web-based SVG editor"
13207
+ }, {
13208
+ "url": "http://www.alistapart.com/articles/using-svg-for-flexible-scalable-and-fun-backgrounds-part-i",
13209
+ "title": "A List Apart article"
13210
+ }, {
13211
+ "url": "http://svg-wow.org/",
13212
+ "title": "SVG showcase site"
13213
+ }],
13214
+ "categories": ["SVG"],
13215
+ "stats": {
13216
+ "ie": {
13217
+ "5.5": "n",
13218
+ "6": "p",
13219
+ "7": "p",
13220
+ "8": "p",
13221
+ "9": "y",
13222
+ "10": "y",
13223
+ "11": "y"
13224
+ },
13225
+ "firefox": {
13226
+ "2": "a",
13227
+ "3": "y",
13228
+ "3.5": "y",
13229
+ "3.6": "y",
13230
+ "4": "y",
13231
+ "5": "y",
13232
+ "6": "y",
13233
+ "7": "y",
13234
+ "8": "y",
13235
+ "9": "y",
13236
+ "10": "y",
13237
+ "11": "y",
13238
+ "12": "y",
13239
+ "13": "y",
13240
+ "14": "y",
13241
+ "15": "y",
13242
+ "16": "y",
13243
+ "17": "y",
13244
+ "18": "y",
13245
+ "19": "y",
13246
+ "20": "y",
13247
+ "21": "y",
13248
+ "22": "y",
13249
+ "23": "y",
13250
+ "24": "y",
13251
+ "25": "y",
13252
+ "26": "y",
13253
+ "27": "y"
13254
+ },
13255
+ "chrome": {
13256
+ "4": "y",
13257
+ "5": "y",
13258
+ "6": "y",
13259
+ "7": "y",
13260
+ "8": "y",
13261
+ "9": "y",
13262
+ "10": "y",
13263
+ "11": "y",
13264
+ "12": "y",
13265
+ "13": "y",
13266
+ "14": "y",
13267
+ "15": "y",
13268
+ "16": "y",
13269
+ "17": "y",
13270
+ "18": "y",
13271
+ "19": "y",
13272
+ "20": "y",
13273
+ "21": "y",
13274
+ "22": "y",
13275
+ "23": "y",
13276
+ "24": "y",
13277
+ "25": "y",
13278
+ "26": "y",
13279
+ "27": "y",
13280
+ "28": "y",
13281
+ "29": "y",
13282
+ "30": "y",
13283
+ "31": "y",
13284
+ "32": "y"
13285
+ },
13286
+ "safari": {
13287
+ "3.1": "a",
13288
+ "3.2": "y",
13289
+ "4": "y",
13290
+ "5": "y",
13291
+ "5.1": "y",
13292
+ "6": "y",
13293
+ "6.1": "y",
13294
+ "7": "y"
13295
+ },
13296
+ "opera": {
13297
+ "9": "y",
13298
+ "9.5-9.6": "y",
13299
+ "10.0-10.1": "y",
13300
+ "10.5": "y",
13301
+ "10.6": "y",
13302
+ "11": "y",
13303
+ "11.1": "y",
13304
+ "11.5": "y",
13305
+ "11.6": "y",
13306
+ "12": "y",
13307
+ "12.1": "y",
13308
+ "15": "y",
13309
+ "16": "y",
13310
+ "17": "y",
13311
+ "18": "y"
13312
+ },
13313
+ "ios_saf": {
13314
+ "3.2": "y",
13315
+ "4.0-4.1": "y",
13316
+ "4.2-4.3": "y",
13317
+ "5.0-5.1": "y",
13318
+ "6.0-6.1": "y",
13319
+ "7.0": "y"
13320
+ },
13321
+ "op_mini": {
13322
+ "5.0-7.0": "y"
13323
+ },
13324
+ "android": {
13325
+ "2.1": "n",
13326
+ "2.2": "n",
13327
+ "2.3": "n",
13328
+ "3": "y",
13329
+ "4": "y",
13330
+ "4.1": "y",
13331
+ "4.2-4.3": "y",
13332
+ "4.4": "y"
13333
+ },
13334
+ "bb": {
13335
+ "7": "y",
13336
+ "10": "y"
13337
+ },
13338
+ "op_mob": {
13339
+ "10": "y",
13340
+ "11": "y",
13341
+ "11.1": "y",
13342
+ "11.5": "y",
13343
+ "12": "y",
13344
+ "12.1": "y",
13345
+ "0": "y"
13346
+ },
13347
+ "and_chr": {
13348
+ "0": "y"
13349
+ },
13350
+ "and_ff": {
13351
+ "0": "y"
13352
+ },
13353
+ "ie_mob": {
13354
+ "10": "y"
13355
+ }
13356
+ },
13357
+ "notes": "",
13358
+ "usage_perc_y": 84.1,
13359
+ "usage_perc_a": 0.02,
13360
+ "ucprefix": false,
13361
+ "parent": "",
13362
+ "keywords": ""
13363
+ },
13364
+ "svg-css": {
13365
+ "title": "SVG in CSS backgrounds",
13366
+ "description": "Method of using SVG images as CSS backgrounds",
13367
+ "spec": "http://www.w3.org/TR/css3-background/#background-image",
13368
+ "status": "cr",
13369
+ "links": [{
13370
+ "url": "http://designfestival.com/a-farewell-to-css3-gradients/",
13371
+ "title": "Tutorial for advanced effects"
13372
+ }],
13373
+ "categories": ["SVG", "CSS3"],
13374
+ "stats": {
13375
+ "ie": {
13376
+ "5.5": "n",
13377
+ "6": "n",
13378
+ "7": "n",
13379
+ "8": "n",
13380
+ "9": "y",
13381
+ "10": "y",
13382
+ "11": "y"
13383
+ },
13384
+ "firefox": {
13385
+ "2": "n",
13386
+ "3": "n",
13387
+ "3.5": "n",
13388
+ "3.6": "n",
13389
+ "4": "a",
13390
+ "5": "a",
13391
+ "6": "a",
13392
+ "7": "a",
13393
+ "8": "a",
13394
+ "9": "a",
13395
+ "10": "a",
13396
+ "11": "a",
13397
+ "12": "a",
13398
+ "13": "a",
13399
+ "14": "a",
13400
+ "15": "a",
13401
+ "16": "a",
13402
+ "17": "a",
13403
+ "18": "a",
13404
+ "19": "a",
13405
+ "20": "a",
13406
+ "21": "a",
13407
+ "22": "a",
13408
+ "23": "a",
13409
+ "24": "y",
13410
+ "25": "y",
13411
+ "26": "y",
13412
+ "27": "y"
13413
+ },
13414
+ "chrome": {
13415
+ "4": "a",
13416
+ "5": "y",
13417
+ "6": "y",
13418
+ "7": "y",
13419
+ "8": "y",
13420
+ "9": "y",
13421
+ "10": "y",
13422
+ "11": "y",
13423
+ "12": "y",
13424
+ "13": "y",
13425
+ "14": "y",
13426
+ "15": "y",
13427
+ "16": "y",
13428
+ "17": "y",
13429
+ "18": "y",
13430
+ "19": "y",
13431
+ "20": "y",
13432
+ "21": "y",
13433
+ "22": "y",
13434
+ "23": "y",
13435
+ "24": "y",
13436
+ "25": "y",
13437
+ "26": "y",
13438
+ "27": "y",
13439
+ "28": "y",
13440
+ "29": "y",
13441
+ "30": "y",
13442
+ "31": "y",
13443
+ "32": "y"
13444
+ },
13445
+ "safari": {
13446
+ "3.1": "n",
13447
+ "3.2": "a",
13448
+ "4": "a",
13449
+ "5": "y",
13450
+ "5.1": "y",
13451
+ "6": "y",
13452
+ "6.1": "y",
13453
+ "7": "y"
13454
+ },
13455
+ "opera": {
13456
+ "9": "n",
13457
+ "9.5-9.6": "y",
13458
+ "10.0-10.1": "y",
13459
+ "10.5": "y",
13460
+ "10.6": "y",
13461
+ "11": "y",
13462
+ "11.1": "y",
13463
+ "11.5": "y",
13464
+ "11.6": "y",
13465
+ "12": "y",
13466
+ "12.1": "y",
13467
+ "15": "y",
13468
+ "16": "y",
13469
+ "17": "y",
13470
+ "18": "y"
13471
+ },
13472
+ "ios_saf": {
13473
+ "3.2": "a",
13474
+ "4.0-4.1": "a",
13475
+ "4.2-4.3": "y",
13476
+ "5.0-5.1": "y",
13477
+ "6.0-6.1": "y",
13478
+ "7.0": "y"
13479
+ },
13480
+ "op_mini": {
13481
+ "5.0-7.0": "a"
13482
+ },
13483
+ "android": {
13484
+ "2.1": "n",
13485
+ "2.2": "n",
13486
+ "2.3": "n",
13487
+ "3": "y",
13488
+ "4": "y",
13489
+ "4.1": "y",
13490
+ "4.2-4.3": "y",
13491
+ "4.4": "y"
13492
+ },
13493
+ "bb": {
13494
+ "7": "y",
13495
+ "10": "y"
13496
+ },
13497
+ "op_mob": {
13498
+ "10": "a",
13499
+ "11": "a",
13500
+ "11.1": "a",
13501
+ "11.5": "a",
13502
+ "12": "a",
13503
+ "12.1": "a",
13504
+ "0": "y"
13505
+ },
13506
+ "and_chr": {
13507
+ "0": "y"
13508
+ },
13509
+ "and_ff": {
13510
+ "0": "y"
13511
+ },
13512
+ "ie_mob": {
13513
+ "10": "y"
13514
+ }
13515
+ },
13516
+ "notes": "Partial support in older Firefox and Opera Mini/Mobile refers to SVG images being blurry when scaled. Partial support in iOS Safari and older Safari versions refers to failing to support tiling or the background-position property.",
13517
+ "usage_perc_y": 75.45,
13518
+ "usage_perc_a": 8.2,
13519
+ "ucprefix": false,
13520
+ "parent": "",
13521
+ "keywords": "svg-in-css,svgincss,css-svg"
13522
+ },
13523
+ "svg-smil": {
13524
+ "title": "SVG SMIL animation",
13525
+ "description": "Method of using animation elements to animate SVG images",
13526
+ "spec": "http://www.w3.org/TR/SVG/animate.html",
13527
+ "status": "rec",
13528
+ "links": [{
13529
+ "url": "https://github.com/madsgraphics/SVGEventListener",
13530
+ "title": "Polyfill for SMIL animate events on SVG"
13531
+ }, {
13532
+ "url": "https://developer.mozilla.org/en/SVG/SVG_animation_with_SMIL",
13533
+ "title": "MDN article"
13534
+ }, {
13535
+ "url": "http://svg-wow.org/blog/category/animation/",
13536
+ "title": "Examples on SVG WOW"
13537
+ }, {
13538
+ "url": "http://leunen.me/fakesmile/",
13539
+ "title": "JS library to support SMIL in SVG"
13540
+ }, {
13541
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/graphics.js#svg-smil",
13542
+ "title": "has.js test"
13543
+ }],
13544
+ "categories": ["SVG"],
13545
+ "stats": {
13546
+ "ie": {
13547
+ "5.5": "n",
13548
+ "6": "p",
13549
+ "7": "p",
13550
+ "8": "p",
13551
+ "9": "p",
13552
+ "10": "p",
13553
+ "11": "p"
13554
+ },
13555
+ "firefox": {
13556
+ "2": "p",
13557
+ "3": "p",
13558
+ "3.5": "p",
13559
+ "3.6": "p",
13560
+ "4": "y",
13561
+ "5": "y",
13562
+ "6": "y",
13563
+ "7": "y",
13564
+ "8": "y",
13565
+ "9": "y",
13566
+ "10": "y",
13567
+ "11": "y",
13568
+ "12": "y",
13569
+ "13": "y",
13570
+ "14": "y",
13571
+ "15": "y",
13572
+ "16": "y",
13573
+ "17": "y",
13574
+ "18": "y",
13575
+ "19": "y",
13576
+ "20": "y",
13577
+ "21": "y",
13578
+ "22": "y",
13579
+ "23": "y",
13580
+ "24": "y",
13581
+ "25": "y",
13582
+ "26": "y",
13583
+ "27": "y"
13584
+ },
13585
+ "chrome": {
13586
+ "4": "a",
13587
+ "5": "y",
13588
+ "6": "y",
13589
+ "7": "y",
13590
+ "8": "y",
13591
+ "9": "y",
13592
+ "10": "y",
13593
+ "11": "y",
13594
+ "12": "y",
13595
+ "13": "y",
13596
+ "14": "y",
13597
+ "15": "y",
13598
+ "16": "y",
13599
+ "17": "y",
13600
+ "18": "y",
13601
+ "19": "y",
13602
+ "20": "y",
13603
+ "21": "y",
13604
+ "22": "y",
13605
+ "23": "y",
13606
+ "24": "y",
13607
+ "25": "y",
13608
+ "26": "y",
13609
+ "27": "y",
13610
+ "28": "y",
13611
+ "29": "y",
13612
+ "30": "y",
13613
+ "31": "y",
13614
+ "32": "y"
13615
+ },
13616
+ "safari": {
13617
+ "3.1": "p",
13618
+ "3.2": "p",
13619
+ "4": "a",
13620
+ "5": "a",
13621
+ "5.1": "a",
13622
+ "6": "a",
13623
+ "6.1": "a",
13624
+ "7": "a"
13625
+ },
13626
+ "opera": {
13627
+ "9": "y",
13628
+ "9.5-9.6": "y",
13629
+ "10.0-10.1": "y",
13630
+ "10.5": "y",
13631
+ "10.6": "y",
13632
+ "11": "y",
13633
+ "11.1": "y",
13634
+ "11.5": "y",
13635
+ "11.6": "y",
13636
+ "12": "y",
13637
+ "12.1": "y",
13638
+ "15": "y",
13639
+ "16": "y",
13640
+ "17": "y",
13641
+ "18": "y"
13642
+ },
13643
+ "ios_saf": {
13644
+ "3.2": "a",
13645
+ "4.0-4.1": "a",
13646
+ "4.2-4.3": "a",
13647
+ "5.0-5.1": "a",
13648
+ "6.0-6.1": "a",
13649
+ "7.0": "a"
13650
+ },
13651
+ "op_mini": {
13652
+ "5.0-7.0": "n"
13653
+ },
13654
+ "android": {
13655
+ "2.1": "n",
13656
+ "2.2": "n",
13657
+ "2.3": "n",
13658
+ "3": "y",
13659
+ "4": "y",
13660
+ "4.1": "y",
13661
+ "4.2-4.3": "y",
13662
+ "4.4": "y"
13663
+ },
13664
+ "bb": {
13665
+ "7": "y",
13666
+ "10": "y"
13667
+ },
13668
+ "op_mob": {
13669
+ "10": "y",
13670
+ "11": "y",
13671
+ "11.1": "y",
13672
+ "11.5": "y",
13673
+ "12": "y",
13674
+ "12.1": "y",
13675
+ "0": "y"
13676
+ },
13677
+ "and_chr": {
13678
+ "0": "y"
13679
+ },
13680
+ "and_ff": {
13681
+ "0": "y"
13682
+ },
13683
+ "ie_mob": {
13684
+ "10": "p"
13685
+ }
13686
+ },
13687
+ "notes": "Partial support in Safari refers to not working in HTML files.",
13688
+ "usage_perc_y": 54.76,
13689
+ "usage_perc_a": 7.99,
13690
+ "ucprefix": false,
13691
+ "parent": "",
13692
+ "keywords": ""
13693
+ },
13694
+ "svg-fonts": {
13695
+ "title": "SVG fonts",
13696
+ "description": "Method of using fonts defined as SVG shapes",
13697
+ "spec": "http://www.w3.org/TR/SVG/fonts.html",
13698
+ "status": "rec",
13699
+ "links": [{
13700
+ "url": "http://opentype.info/blog/2010/04/13/the-ipad-and-svg-fonts-in-mobile-safari/",
13701
+ "title": "Blog post on usage for iPad"
13702
+ }, {
13703
+ "url": "http://jeremie.patonnier.net/post/2011/02/07/Why-are-SVG-Fonts-so-different",
13704
+ "title": "Blog post"
13705
+ }],
13706
+ "categories": ["SVG"],
13707
+ "stats": {
13708
+ "ie": {
13709
+ "5.5": "n",
13710
+ "6": "p",
13711
+ "7": "p",
13712
+ "8": "p",
13713
+ "9": "n",
13714
+ "10": "n",
13715
+ "11": "n"
13716
+ },
13717
+ "firefox": {
13718
+ "2": "n",
13719
+ "3": "n",
13720
+ "3.5": "n",
13721
+ "3.6": "n",
13722
+ "4": "n",
13723
+ "5": "n",
13724
+ "6": "n",
13725
+ "7": "n",
13726
+ "8": "n",
13727
+ "9": "n",
13728
+ "10": "n",
13729
+ "11": "n",
13730
+ "12": "n",
13731
+ "13": "n",
13732
+ "14": "n",
13733
+ "15": "n",
13734
+ "16": "n",
13735
+ "17": "n",
13736
+ "18": "n",
13737
+ "19": "n",
13738
+ "20": "n",
13739
+ "21": "n",
13740
+ "22": "n",
13741
+ "23": "n",
13742
+ "24": "n",
13743
+ "25": "n",
13744
+ "26": "n",
13745
+ "27": "n"
13746
+ },
13747
+ "chrome": {
13748
+ "4": "y",
13749
+ "5": "y",
13750
+ "6": "y",
13751
+ "7": "y",
13752
+ "8": "y",
13753
+ "9": "y",
13754
+ "10": "y",
13755
+ "11": "y",
13756
+ "12": "y",
13757
+ "13": "y",
13758
+ "14": "y",
13759
+ "15": "y",
13760
+ "16": "y",
13761
+ "17": "y",
13762
+ "18": "y",
13763
+ "19": "y",
13764
+ "20": "y",
13765
+ "21": "y",
13766
+ "22": "y",
13767
+ "23": "y",
13768
+ "24": "y",
13769
+ "25": "y",
13770
+ "26": "y",
13771
+ "27": "y",
13772
+ "28": "y",
13773
+ "29": "y",
13774
+ "30": "y",
13775
+ "31": "y",
13776
+ "32": "y"
13777
+ },
13778
+ "safari": {
13779
+ "3.1": "n",
13780
+ "3.2": "y",
13781
+ "4": "y",
13782
+ "5": "y",
13783
+ "5.1": "y",
13784
+ "6": "y",
13785
+ "6.1": "y",
13786
+ "7": "y"
13787
+ },
13788
+ "opera": {
13789
+ "9": "y",
13790
+ "9.5-9.6": "y",
13791
+ "10.0-10.1": "y",
13792
+ "10.5": "y",
13793
+ "10.6": "y",
13794
+ "11": "y",
13795
+ "11.1": "y",
13796
+ "11.5": "y",
13797
+ "11.6": "y",
13798
+ "12": "y",
13799
+ "12.1": "y",
13800
+ "15": "y",
13801
+ "16": "y",
13802
+ "17": "y",
13803
+ "18": "y"
13804
+ },
13805
+ "ios_saf": {
13806
+ "3.2": "y",
13807
+ "4.0-4.1": "y",
13808
+ "4.2-4.3": "y",
13809
+ "5.0-5.1": "y",
13810
+ "6.0-6.1": "y",
13811
+ "7.0": "y"
13812
+ },
13813
+ "op_mini": {
13814
+ "5.0-7.0": "n"
13815
+ },
13816
+ "android": {
13817
+ "2.1": "n",
13818
+ "2.2": "n",
13819
+ "2.3": "n",
13820
+ "3": "y",
13821
+ "4": "y",
13822
+ "4.1": "y",
13823
+ "4.2-4.3": "y",
13824
+ "4.4": "y"
13825
+ },
13826
+ "bb": {
13827
+ "7": "y",
13828
+ "10": "y"
13829
+ },
13830
+ "op_mob": {
13831
+ "10": "y",
13832
+ "11": "y",
13833
+ "11.1": "y",
13834
+ "11.5": "y",
13835
+ "12": "y",
13836
+ "12.1": "y",
13837
+ "0": "y"
13838
+ },
13839
+ "and_chr": {
13840
+ "0": "y"
13841
+ },
13842
+ "and_ff": {
13843
+ "0": "n"
13844
+ },
13845
+ "ie_mob": {
13846
+ "10": "n"
13847
+ }
13848
+ },
13849
+ "notes": "Supported in Opera Mini in SVG images only, not in HTML.",
13850
+ "usage_perc_y": 47.78,
13851
+ "usage_perc_a": 0,
13852
+ "ucprefix": false,
13853
+ "parent": "fontface",
13854
+ "keywords": ""
13855
+ },
13856
+ "svg-filters": {
13857
+ "title": "SVG filters",
13858
+ "description": "Method of using photoshop-like effects on SVG objects including blurring and color manipulation.",
13859
+ "spec": "http://www.w3.org/TR/SVG/filters.html",
13860
+ "status": "rec",
13861
+ "links": [{
13862
+ "url": "http://electricbeach.org/?p=950",
13863
+ "title": "Experiments with filter effects"
13864
+ }, {
13865
+ "url": "http://svg-wow.org/blog/category/filters/",
13866
+ "title": "SVG filter demos"
13867
+ }, {
13868
+ "url": "http://docs.webplatform.org/wiki/svg/elements/filter",
13869
+ "title": "WebPlatform Docs"
13870
+ }],
13871
+ "categories": ["SVG"],
13872
+ "stats": {
13873
+ "ie": {
13874
+ "5.5": "n",
13875
+ "6": "n",
13876
+ "7": "n",
13877
+ "8": "n",
13878
+ "9": "n",
13879
+ "10": "y",
13880
+ "11": "y"
13881
+ },
13882
+ "firefox": {
13883
+ "2": "n",
13884
+ "3": "y",
13885
+ "3.5": "y",
13886
+ "3.6": "y",
13887
+ "4": "y",
13888
+ "5": "y",
13889
+ "6": "y",
13890
+ "7": "y",
13891
+ "8": "y",
13892
+ "9": "y",
13893
+ "10": "y",
13894
+ "11": "y",
13895
+ "12": "y",
13896
+ "13": "y",
13897
+ "14": "y",
13898
+ "15": "y",
13899
+ "16": "y",
13900
+ "17": "y",
13901
+ "18": "y",
13902
+ "19": "y",
13903
+ "20": "y",
13904
+ "21": "y",
13905
+ "22": "y",
13906
+ "23": "y",
13907
+ "24": "y",
13908
+ "25": "y",
13909
+ "26": "y",
13910
+ "27": "y"
13911
+ },
13912
+ "chrome": {
13913
+ "4": "n",
13914
+ "5": "a",
13915
+ "6": "a",
13916
+ "7": "a",
13917
+ "8": "y",
13918
+ "9": "y",
13919
+ "10": "y",
13920
+ "11": "y",
13921
+ "12": "y",
13922
+ "13": "y",
13923
+ "14": "y",
13924
+ "15": "y",
13925
+ "16": "y",
13926
+ "17": "y",
13927
+ "18": "y",
13928
+ "19": "y",
13929
+ "20": "y",
13930
+ "21": "y",
13931
+ "22": "y",
13932
+ "23": "y",
13933
+ "24": "y",
13934
+ "25": "y",
13935
+ "26": "y",
13936
+ "27": "y",
13937
+ "28": "y",
13938
+ "29": "y",
13939
+ "30": "y",
13940
+ "31": "y",
13941
+ "32": "y"
13942
+ },
13943
+ "safari": {
13944
+ "3.1": "n",
13945
+ "3.2": "n",
13946
+ "4": "n",
13947
+ "5": "n",
13948
+ "5.1": "n",
13949
+ "6": "y",
13950
+ "6.1": "y",
13951
+ "7": "y"
13952
+ },
13953
+ "opera": {
13954
+ "9": "y",
13955
+ "9.5-9.6": "y",
13956
+ "10.0-10.1": "y",
13957
+ "10.5": "y",
13958
+ "10.6": "y",
13959
+ "11": "y",
13960
+ "11.1": "y",
13961
+ "11.5": "y",
13962
+ "11.6": "y",
13963
+ "12": "y",
13964
+ "12.1": "y",
13965
+ "15": "y",
13966
+ "16": "y",
13967
+ "17": "y",
13968
+ "18": "y"
13969
+ },
13970
+ "ios_saf": {
13971
+ "3.2": "n",
13972
+ "4.0-4.1": "n",
13973
+ "4.2-4.3": "n",
13974
+ "5.0-5.1": "n",
13975
+ "6.0-6.1": "y",
13976
+ "7.0": "y"
13977
+ },
13978
+ "op_mini": {
13979
+ "5.0-7.0": "y"
13980
+ },
13981
+ "android": {
13982
+ "2.1": "n",
13983
+ "2.2": "n",
13984
+ "2.3": "n",
13985
+ "3": "n",
13986
+ "4": "n",
13987
+ "4.1": "n",
13988
+ "4.2-4.3": "n",
13989
+ "4.4": "y"
13990
+ },
13991
+ "bb": {
13992
+ "7": "n",
13993
+ "10": "y"
13994
+ },
13995
+ "op_mob": {
13996
+ "10": "y",
13997
+ "11": "y",
13998
+ "11.1": "y",
13999
+ "11.5": "y",
14000
+ "12": "y",
14001
+ "12.1": "y",
14002
+ "0": "y"
14003
+ },
14004
+ "and_chr": {
14005
+ "0": "y"
14006
+ },
14007
+ "and_ff": {
14008
+ "0": "y"
14009
+ },
14010
+ "ie_mob": {
14011
+ "10": "y"
14012
+ }
14013
+ },
14014
+ "notes": "",
14015
+ "usage_perc_y": 72.99,
14016
+ "usage_perc_a": 0.08,
14017
+ "ucprefix": false,
14018
+ "parent": "",
14019
+ "keywords": ""
14020
+ },
14021
+ "svg-html": {
14022
+ "title": "SVG effects for HTML",
14023
+ "description": "Method of using SVG transforms, filters, etc on HTML elements using either CSS or the foreignObject element",
14024
+ "spec": "http://www.w3.org/TR/SVG11/extend.html#ForeignObjectElement",
14025
+ "status": "wd",
14026
+ "links": [{
14027
+ "url": "https://developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content",
14028
+ "title": "MDN Reference page"
14029
+ }, {
14030
+ "url": "https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html",
14031
+ "title": "Filter Effects draft"
14032
+ }, {
14033
+ "url": "https://developer.mozilla.org/en/SVG/Tutorial/Other_content_in_SVG",
14034
+ "title": "MDN Tutorial"
14035
+ }],
14036
+ "categories": ["SVG"],
14037
+ "stats": {
14038
+ "ie": {
14039
+ "5.5": "n",
14040
+ "6": "n",
14041
+ "7": "n",
14042
+ "8": "n",
14043
+ "9": "a",
14044
+ "10": "a",
14045
+ "11": "a"
14046
+ },
14047
+ "firefox": {
14048
+ "2": "n",
14049
+ "3": "a",
14050
+ "3.5": "y",
14051
+ "3.6": "y",
14052
+ "4": "y",
14053
+ "5": "y",
14054
+ "6": "y",
14055
+ "7": "y",
14056
+ "8": "y",
14057
+ "9": "y",
14058
+ "10": "y",
14059
+ "11": "y",
14060
+ "12": "y",
14061
+ "13": "y",
14062
+ "14": "y",
14063
+ "15": "y",
14064
+ "16": "y",
14065
+ "17": "y",
14066
+ "18": "y",
14067
+ "19": "y",
14068
+ "20": "y",
14069
+ "21": "y",
14070
+ "22": "y",
14071
+ "23": "y",
14072
+ "24": "y",
14073
+ "25": "y",
14074
+ "26": "y",
14075
+ "27": "y"
14076
+ },
14077
+ "chrome": {
14078
+ "4": "a",
14079
+ "5": "a",
14080
+ "6": "a",
14081
+ "7": "a",
14082
+ "8": "a",
14083
+ "9": "a",
14084
+ "10": "a",
14085
+ "11": "a",
14086
+ "12": "a",
14087
+ "13": "a",
14088
+ "14": "a",
14089
+ "15": "a",
14090
+ "16": "a",
14091
+ "17": "a",
14092
+ "18": "a",
14093
+ "19": "a",
14094
+ "20": "a",
14095
+ "21": "a",
14096
+ "22": "a",
14097
+ "23": "a",
14098
+ "24": "a",
14099
+ "25": "a",
14100
+ "26": "a",
14101
+ "27": "a",
14102
+ "28": "a",
14103
+ "29": "a",
14104
+ "30": "a",
14105
+ "31": "a",
14106
+ "32": "a"
14107
+ },
14108
+ "safari": {
14109
+ "3.1": "n",
14110
+ "3.2": "n",
14111
+ "4": "a",
14112
+ "5": "a",
14113
+ "5.1": "a",
14114
+ "6": "a",
14115
+ "6.1": "a",
14116
+ "7": "a"
14117
+ },
14118
+ "opera": {
14119
+ "9": "a",
14120
+ "9.5-9.6": "a",
14121
+ "10.0-10.1": "a",
14122
+ "10.5": "a",
14123
+ "10.6": "a",
14124
+ "11": "a",
14125
+ "11.1": "a",
14126
+ "11.5": "a",
14127
+ "11.6": "a",
14128
+ "12": "a",
14129
+ "12.1": "a",
14130
+ "15": "a",
14131
+ "16": "a",
14132
+ "17": "a",
14133
+ "18": "a"
14134
+ },
14135
+ "ios_saf": {
14136
+ "3.2": "a",
14137
+ "4.0-4.1": "a",
14138
+ "4.2-4.3": "a",
14139
+ "5.0-5.1": "a",
14140
+ "6.0-6.1": "a",
14141
+ "7.0": "a"
14142
+ },
14143
+ "op_mini": {
14144
+ "5.0-7.0": "n"
14145
+ },
14146
+ "android": {
14147
+ "2.1": "n",
14148
+ "2.2": "n",
14149
+ "2.3": "n",
14150
+ "3": "n",
14151
+ "4": "n",
14152
+ "4.1": "n",
14153
+ "4.2-4.3": "n",
14154
+ "4.4": "a"
14155
+ },
14156
+ "bb": {
14157
+ "7": "n",
14158
+ "10": "y"
14159
+ },
14160
+ "op_mob": {
14161
+ "10": "a",
14162
+ "11": "a",
14163
+ "11.1": "a",
14164
+ "11.5": "a",
14165
+ "12": "a",
14166
+ "12.1": "a",
14167
+ "0": "a"
14168
+ },
14169
+ "and_chr": {
14170
+ "0": "a"
14171
+ },
14172
+ "and_ff": {
14173
+ "0": "y"
14174
+ },
14175
+ "ie_mob": {
14176
+ "10": "n"
14177
+ }
14178
+ },
14179
+ "notes": "Partial support refers to lack of filter support or buggy result from effects. A <a href=\"https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html\">CSS Filter Effects</a> specification is in the works that would replace this method.",
14180
+ "usage_perc_y": 15.33,
14181
+ "usage_perc_a": 60.21,
14182
+ "ucprefix": false,
14183
+ "parent": "",
14184
+ "keywords": ""
14185
+ },
14186
+ "svg-html5": {
14187
+ "title": "Inline SVG in HTML5",
14188
+ "description": "Method of using SVG tags directly in HTML documents. Requires HTML5 parser.",
14189
+ "spec": "http://www.w3.org/TR/html5/embedded-content-0.html#svg-0",
14190
+ "status": "cr",
14191
+ "links": [{
14192
+ "url": "http://hacks.mozilla.org/2010/05/firefox-4-the-html5-parser-inline-svg-speed-and-more/",
14193
+ "title": "Mozilla Hacks blog post"
14194
+ }, {
14195
+ "url": "http://samples.msdn.microsoft.com/ietestcenter/html5/svghtml_harness.htm?url=SVG_HTML_Elements_001",
14196
+ "title": "Test suite"
14197
+ }],
14198
+ "categories": ["SVG", "HTML5"],
14199
+ "stats": {
14200
+ "ie": {
14201
+ "5.5": "n",
14202
+ "6": "p",
14203
+ "7": "p",
14204
+ "8": "p",
14205
+ "9": "y",
14206
+ "10": "y",
14207
+ "11": "y"
14208
+ },
14209
+ "firefox": {
14210
+ "2": "p",
14211
+ "3": "p",
14212
+ "3.5": "p",
14213
+ "3.6": "p",
14214
+ "4": "y",
14215
+ "5": "y",
14216
+ "6": "y",
14217
+ "7": "y",
14218
+ "8": "y",
14219
+ "9": "y",
14220
+ "10": "y",
14221
+ "11": "y",
14222
+ "12": "y",
14223
+ "13": "y",
14224
+ "14": "y",
14225
+ "15": "y",
14226
+ "16": "y",
14227
+ "17": "y",
14228
+ "18": "y",
14229
+ "19": "y",
14230
+ "20": "y",
14231
+ "21": "y",
14232
+ "22": "y",
14233
+ "23": "y",
14234
+ "24": "y",
14235
+ "25": "y",
14236
+ "26": "y",
14237
+ "27": "y"
14238
+ },
14239
+ "chrome": {
14240
+ "4": "p",
14241
+ "5": "p",
14242
+ "6": "p",
14243
+ "7": "y",
14244
+ "8": "y",
14245
+ "9": "y",
14246
+ "10": "y",
14247
+ "11": "y",
14248
+ "12": "y",
14249
+ "13": "y",
14250
+ "14": "y",
14251
+ "15": "y",
14252
+ "16": "y",
14253
+ "17": "y",
14254
+ "18": "y",
14255
+ "19": "y",
14256
+ "20": "y",
14257
+ "21": "y",
14258
+ "22": "y",
14259
+ "23": "y",
14260
+ "24": "y",
14261
+ "25": "y",
14262
+ "26": "y",
14263
+ "27": "y",
14264
+ "28": "y",
14265
+ "29": "y",
14266
+ "30": "y",
14267
+ "31": "y",
14268
+ "32": "y"
14269
+ },
14270
+ "safari": {
14271
+ "3.1": "p",
14272
+ "3.2": "p",
14273
+ "4": "p",
14274
+ "5": "p",
14275
+ "5.1": "y",
14276
+ "6": "y",
14277
+ "6.1": "y",
14278
+ "7": "y"
14279
+ },
14280
+ "opera": {
14281
+ "9": "p",
14282
+ "9.5-9.6": "p",
14283
+ "10.0-10.1": "p",
14284
+ "10.5": "p",
14285
+ "10.6": "n",
14286
+ "11": "n",
14287
+ "11.1": "n",
14288
+ "11.5": "n",
14289
+ "11.6": "y",
14290
+ "12": "y",
14291
+ "12.1": "y",
14292
+ "15": "y",
14293
+ "16": "y",
14294
+ "17": "y",
14295
+ "18": "y"
14296
+ },
14297
+ "ios_saf": {
14298
+ "3.2": "p",
14299
+ "4.0-4.1": "p",
14300
+ "4.2-4.3": "p",
14301
+ "5.0-5.1": "y",
14302
+ "6.0-6.1": "y",
14303
+ "7.0": "y"
14304
+ },
14305
+ "op_mini": {
14306
+ "5.0-7.0": "n"
14307
+ },
14308
+ "android": {
14309
+ "2.1": "n",
14310
+ "2.2": "n",
14311
+ "2.3": "n",
14312
+ "3": "y",
14313
+ "4": "y",
14314
+ "4.1": "y",
14315
+ "4.2-4.3": "y",
14316
+ "4.4": "y"
14317
+ },
14318
+ "bb": {
14319
+ "7": "y",
14320
+ "10": "y"
14321
+ },
14322
+ "op_mob": {
14323
+ "10": "p",
14324
+ "11": "p",
14325
+ "11.1": "p",
14326
+ "11.5": "p",
14327
+ "12": "y",
14328
+ "12.1": "y",
14329
+ "0": "y"
14330
+ },
14331
+ "and_chr": {
14332
+ "0": "y"
14333
+ },
14334
+ "and_ff": {
14335
+ "0": "y"
14336
+ },
14337
+ "ie_mob": {
14338
+ "10": "y"
14339
+ }
14340
+ },
14341
+ "notes": "",
14342
+ "usage_perc_y": 78.45,
14343
+ "usage_perc_a": 0,
14344
+ "ucprefix": false,
14345
+ "parent": "",
14346
+ "keywords": ""
14347
+ },
14348
+ "canvas": {
14349
+ "title": "Canvas (basic support)",
14350
+ "description": "Method of generating fast, dynamic graphics using JavaScript",
14351
+ "spec": "http://www.w3.org/TR/html5/embedded-content-0.html#the-canvas-element",
14352
+ "status": "cr",
14353
+ "links": [{
14354
+ "url": "https://developer.mozilla.org/en/Canvas_tutorial",
14355
+ "title": "Tutorial by Mozilla"
14356
+ }, {
14357
+ "url": "http://explorercanvas.googlecode.com/",
14358
+ "title": "Implementation for Internet Explorer"
14359
+ }, {
14360
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/graphics.js#canvas",
14361
+ "title": "has.js test"
14362
+ }, {
14363
+ "url": "http://www.diveinto.org/html5/canvas.html",
14364
+ "title": "Another tutorial"
14365
+ }, {
14366
+ "url": "http://glimr.rubyforge.org/cake/canvas.html",
14367
+ "title": "Animation kit "
14368
+ }, {
14369
+ "url": "http://www.canvasdemos.com/",
14370
+ "title": "Showcase site"
14371
+ }],
14372
+ "categories": ["Canvas", "HTML5"],
14373
+ "stats": {
14374
+ "ie": {
14375
+ "5.5": "n",
14376
+ "6": "p",
14377
+ "7": "p",
14378
+ "8": "p",
14379
+ "9": "y",
14380
+ "10": "y",
14381
+ "11": "y"
14382
+ },
14383
+ "firefox": {
14384
+ "2": "y",
14385
+ "3": "y",
14386
+ "3.5": "y",
14387
+ "3.6": "y",
14388
+ "4": "y",
14389
+ "5": "y",
14390
+ "6": "y",
14391
+ "7": "y",
14392
+ "8": "y",
14393
+ "9": "y",
14394
+ "10": "y",
14395
+ "11": "y",
14396
+ "12": "y",
14397
+ "13": "y",
14398
+ "14": "y",
14399
+ "15": "y",
14400
+ "16": "y",
14401
+ "17": "y",
14402
+ "18": "y",
14403
+ "19": "y",
14404
+ "20": "y",
14405
+ "21": "y",
14406
+ "22": "y",
14407
+ "23": "y",
14408
+ "24": "y",
14409
+ "25": "y",
14410
+ "26": "y",
14411
+ "27": "y"
14412
+ },
14413
+ "chrome": {
14414
+ "4": "y",
14415
+ "5": "y",
14416
+ "6": "y",
14417
+ "7": "y",
14418
+ "8": "y",
14419
+ "9": "y",
14420
+ "10": "y",
14421
+ "11": "y",
14422
+ "12": "y",
14423
+ "13": "y",
14424
+ "14": "y",
14425
+ "15": "y",
14426
+ "16": "y",
14427
+ "17": "y",
14428
+ "18": "y",
14429
+ "19": "y",
14430
+ "20": "y",
14431
+ "21": "y",
14432
+ "22": "y",
14433
+ "23": "y",
14434
+ "24": "y",
14435
+ "25": "y",
14436
+ "26": "y",
14437
+ "27": "y",
14438
+ "28": "y",
14439
+ "29": "y",
14440
+ "30": "y",
14441
+ "31": "y",
14442
+ "32": "y"
14443
+ },
14444
+ "safari": {
14445
+ "3.1": "y",
14446
+ "3.2": "y",
14447
+ "4": "y",
14448
+ "5": "y",
14449
+ "5.1": "y",
14450
+ "6": "y",
14451
+ "6.1": "y",
14452
+ "7": "y"
14453
+ },
14454
+ "opera": {
14455
+ "9": "y",
14456
+ "9.5-9.6": "y",
14457
+ "10.0-10.1": "y",
14458
+ "10.5": "y",
14459
+ "10.6": "y",
14460
+ "11": "y",
14461
+ "11.1": "y",
14462
+ "11.5": "y",
14463
+ "11.6": "y",
14464
+ "12": "y",
14465
+ "12.1": "y",
14466
+ "15": "y",
14467
+ "16": "y",
14468
+ "17": "y",
14469
+ "18": "y"
14470
+ },
14471
+ "ios_saf": {
14472
+ "3.2": "y",
14473
+ "4.0-4.1": "y",
14474
+ "4.2-4.3": "y",
14475
+ "5.0-5.1": "y",
14476
+ "6.0-6.1": "y",
14477
+ "7.0": "y"
14478
+ },
14479
+ "op_mini": {
14480
+ "5.0-7.0": "a"
14481
+ },
14482
+ "android": {
14483
+ "2.1": "a",
14484
+ "2.2": "a",
14485
+ "2.3": "a",
14486
+ "3": "y",
14487
+ "4": "y",
14488
+ "4.1": "y",
14489
+ "4.2-4.3": "y",
14490
+ "4.4": "y"
14491
+ },
14492
+ "bb": {
14493
+ "7": "y",
14494
+ "10": "y"
14495
+ },
14496
+ "op_mob": {
14497
+ "10": "y",
14498
+ "11": "y",
14499
+ "11.1": "y",
14500
+ "11.5": "y",
14501
+ "12": "y",
14502
+ "12.1": "y",
14503
+ "0": "y"
14504
+ },
14505
+ "and_chr": {
14506
+ "0": "y"
14507
+ },
14508
+ "and_ff": {
14509
+ "0": "y"
14510
+ },
14511
+ "ie_mob": {
14512
+ "10": "y"
14513
+ }
14514
+ },
14515
+ "notes": "Opera Mini supports the canvas element, but is unable to play animations or run other more complex applications. Android 2.x supports canvas except the toDataURL() function. See http://code.google.com/p/android/issues/detail?id=7901 Some (slow) workarounds are described here: http://stackoverflow.com/q/10488033/841830",
14516
+ "usage_perc_y": 79.53,
14517
+ "usage_perc_a": 6.02,
14518
+ "ucprefix": false,
14519
+ "parent": "",
14520
+ "keywords": ""
14521
+ },
14522
+ "canvas-text": {
14523
+ "title": "Text API for Canvas",
14524
+ "description": "Method of displaying text on Canvas elements",
14525
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-0",
14526
+ "status": "wd",
14527
+ "links": [{
14528
+ "url": "http://code.google.com/p/canvas-text/",
14529
+ "title": "Support library"
14530
+ }, {
14531
+ "url": "http://docs.webplatform.org/wiki/apis/canvas/CanvasRenderingContext2D/fillText",
14532
+ "title": "WebPlatform Docs"
14533
+ }, {
14534
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/graphics.js#canvas-text",
14535
+ "title": "has.js test"
14536
+ }, {
14537
+ "url": "https://developer.mozilla.org/en/Drawing_text_using_a_canvas#Additional_examples",
14538
+ "title": "Examples by Mozilla"
14539
+ }],
14540
+ "categories": ["Canvas", "HTML5"],
14541
+ "stats": {
14542
+ "ie": {
14543
+ "5.5": "n",
14544
+ "6": "p",
14545
+ "7": "p",
14546
+ "8": "p",
14547
+ "9": "y",
14548
+ "10": "y",
14549
+ "11": "y"
14550
+ },
14551
+ "firefox": {
14552
+ "2": "p",
14553
+ "3": "p",
14554
+ "3.5": "y",
14555
+ "3.6": "y",
14556
+ "4": "y",
14557
+ "5": "y",
14558
+ "6": "y",
14559
+ "7": "y",
14560
+ "8": "y",
14561
+ "9": "y",
14562
+ "10": "y",
14563
+ "11": "y",
14564
+ "12": "y",
14565
+ "13": "y",
14566
+ "14": "y",
14567
+ "15": "y",
14568
+ "16": "y",
14569
+ "17": "y",
14570
+ "18": "y",
14571
+ "19": "y",
14572
+ "20": "y",
14573
+ "21": "y",
14574
+ "22": "y",
14575
+ "23": "y",
14576
+ "24": "y",
14577
+ "25": "y",
14578
+ "26": "y",
14579
+ "27": "y"
14580
+ },
14581
+ "chrome": {
14582
+ "4": "y",
14583
+ "5": "y",
14584
+ "6": "y",
14585
+ "7": "y",
14586
+ "8": "y",
14587
+ "9": "y",
14588
+ "10": "y",
14589
+ "11": "y",
14590
+ "12": "y",
14591
+ "13": "y",
14592
+ "14": "y",
14593
+ "15": "y",
14594
+ "16": "y",
14595
+ "17": "y",
14596
+ "18": "y",
14597
+ "19": "y",
14598
+ "20": "y",
14599
+ "21": "y",
14600
+ "22": "y",
14601
+ "23": "y",
14602
+ "24": "y",
14603
+ "25": "y",
14604
+ "26": "y",
14605
+ "27": "y",
14606
+ "28": "y",
14607
+ "29": "y",
14608
+ "30": "y",
14609
+ "31": "y",
14610
+ "32": "y"
14611
+ },
14612
+ "safari": {
14613
+ "3.1": "p",
14614
+ "3.2": "p",
14615
+ "4": "y",
14616
+ "5": "y",
14617
+ "5.1": "y",
14618
+ "6": "y",
14619
+ "6.1": "y",
14620
+ "7": "y"
14621
+ },
14622
+ "opera": {
14623
+ "9": "p",
14624
+ "9.5-9.6": "p",
14625
+ "10.0-10.1": "p",
14626
+ "10.5": "y",
14627
+ "10.6": "y",
14628
+ "11": "y",
14629
+ "11.1": "y",
14630
+ "11.5": "y",
14631
+ "11.6": "y",
14632
+ "12": "y",
14633
+ "12.1": "y",
14634
+ "15": "y",
14635
+ "16": "y",
14636
+ "17": "y",
14637
+ "18": "y"
14638
+ },
14639
+ "ios_saf": {
14640
+ "3.2": "y",
14641
+ "4.0-4.1": "y",
14642
+ "4.2-4.3": "y",
14643
+ "5.0-5.1": "y",
14644
+ "6.0-6.1": "y",
14645
+ "7.0": "y"
14646
+ },
14647
+ "op_mini": {
14648
+ "5.0-7.0": "n"
14649
+ },
14650
+ "android": {
14651
+ "2.1": "y",
14652
+ "2.2": "y",
14653
+ "2.3": "y",
14654
+ "3": "y",
14655
+ "4": "y",
14656
+ "4.1": "y",
14657
+ "4.2-4.3": "y",
14658
+ "4.4": "y"
14659
+ },
14660
+ "bb": {
14661
+ "7": "y",
14662
+ "10": "y"
14663
+ },
14664
+ "op_mob": {
14665
+ "10": "p",
14666
+ "11": "y",
14667
+ "11.1": "y",
14668
+ "11.5": "y",
14669
+ "12": "y",
14670
+ "12.1": "y",
14671
+ "0": "y"
14672
+ },
14673
+ "and_chr": {
14674
+ "0": "y"
14675
+ },
14676
+ "and_ff": {
14677
+ "0": "y"
14678
+ },
14679
+ "ie_mob": {
14680
+ "10": "y"
14681
+ }
14682
+ },
14683
+ "notes": "",
14684
+ "usage_perc_y": 80.82,
14685
+ "usage_perc_a": 0,
14686
+ "ucprefix": false,
14687
+ "parent": "canvas",
14688
+ "keywords": ""
14689
+ },
14690
+ "namevalue-storage": {
14691
+ "title": "Web Storage - name/value pairs",
14692
+ "description": "Method of storing data locally like cookies, but for larger amounts of data (sessionStorage and localStorage, used to fall under HTML5).",
14693
+ "spec": "http://www.w3.org/TR/webstorage/#storage",
14694
+ "status": "rec",
14695
+ "links": [{
14696
+ "url": "http://html5demos.com/storage",
14697
+ "title": "Simple demo"
14698
+ }, {
14699
+ "url": "http://docs.webplatform.org/wiki/apis/web-storage/Storage/localStorage",
14700
+ "title": "WebPlatform Docs"
14701
+ }, {
14702
+ "url": "https://developer.mozilla.org/En/DOM/Storage",
14703
+ "title": "Gecko reference"
14704
+ }, {
14705
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-localstorage;native-sessionstorage",
14706
+ "title": "has.js test"
14707
+ }, {
14708
+ "url": "http://code.google.com/p/sessionstorage/",
14709
+ "title": "Support library"
14710
+ }],
14711
+ "categories": ["JS API"],
14712
+ "stats": {
14713
+ "ie": {
14714
+ "5.5": "n",
14715
+ "6": "p",
14716
+ "7": "p",
14717
+ "8": "y",
14718
+ "9": "y",
14719
+ "10": "y",
14720
+ "11": "y"
14721
+ },
14722
+ "firefox": {
14723
+ "2": "a",
14724
+ "3": "a",
14725
+ "3.5": "y",
14726
+ "3.6": "y",
14727
+ "4": "y",
14728
+ "5": "y",
14729
+ "6": "y",
14730
+ "7": "y",
14731
+ "8": "y",
14732
+ "9": "y",
14733
+ "10": "y",
14734
+ "11": "y",
14735
+ "12": "y",
14736
+ "13": "y",
14737
+ "14": "y",
14738
+ "15": "y",
14739
+ "16": "y",
14740
+ "17": "y",
14741
+ "18": "y",
14742
+ "19": "y",
14743
+ "20": "y",
14744
+ "21": "y",
14745
+ "22": "y",
14746
+ "23": "y",
14747
+ "24": "y",
14748
+ "25": "y",
14749
+ "26": "y",
14750
+ "27": "y"
14751
+ },
14752
+ "chrome": {
14753
+ "4": "y",
14754
+ "5": "y",
14755
+ "6": "y",
14756
+ "7": "y",
14757
+ "8": "y",
14758
+ "9": "y",
14759
+ "10": "y",
14760
+ "11": "y",
14761
+ "12": "y",
14762
+ "13": "y",
14763
+ "14": "y",
14764
+ "15": "y",
14765
+ "16": "y",
14766
+ "17": "y",
14767
+ "18": "y",
14768
+ "19": "y",
14769
+ "20": "y",
14770
+ "21": "y",
14771
+ "22": "y",
14772
+ "23": "y",
14773
+ "24": "y",
14774
+ "25": "y",
14775
+ "26": "y",
14776
+ "27": "y",
14777
+ "28": "y",
14778
+ "29": "y",
14779
+ "30": "y",
14780
+ "31": "y",
14781
+ "32": "y"
14782
+ },
14783
+ "safari": {
14784
+ "3.1": "n",
14785
+ "3.2": "n",
14786
+ "4": "y",
14787
+ "5": "y",
14788
+ "5.1": "y",
14789
+ "6": "y",
14790
+ "6.1": "y",
14791
+ "7": "y"
14792
+ },
14793
+ "opera": {
14794
+ "9": "n",
14795
+ "9.5-9.6": "n",
14796
+ "10.0-10.1": "n",
14797
+ "10.5": "y",
14798
+ "10.6": "y",
14799
+ "11": "y",
14800
+ "11.1": "y",
14801
+ "11.5": "y",
14802
+ "11.6": "y",
14803
+ "12": "y",
14804
+ "12.1": "y",
14805
+ "15": "y",
14806
+ "16": "y",
14807
+ "17": "y",
14808
+ "18": "y"
14809
+ },
14810
+ "ios_saf": {
14811
+ "3.2": "y",
14812
+ "4.0-4.1": "y",
14813
+ "4.2-4.3": "y",
14814
+ "5.0-5.1": "y",
14815
+ "6.0-6.1": "y",
14816
+ "7.0": "y"
14817
+ },
14818
+ "op_mini": {
14819
+ "5.0-7.0": "n"
14820
+ },
14821
+ "android": {
14822
+ "2.1": "y",
14823
+ "2.2": "y",
14824
+ "2.3": "y",
14825
+ "3": "y",
14826
+ "4": "y",
14827
+ "4.1": "y",
14828
+ "4.2-4.3": "y",
14829
+ "4.4": "y"
14830
+ },
14831
+ "bb": {
14832
+ "7": "y",
14833
+ "10": "y"
14834
+ },
14835
+ "op_mob": {
14836
+ "10": "n",
14837
+ "11": "y",
14838
+ "11.1": "y",
14839
+ "11.5": "y",
14840
+ "12": "y",
14841
+ "12.1": "y",
14842
+ "0": "y"
14843
+ },
14844
+ "and_chr": {
14845
+ "0": "y"
14846
+ },
14847
+ "and_ff": {
14848
+ "0": "y"
14849
+ },
14850
+ "ie_mob": {
14851
+ "10": "y"
14852
+ }
14853
+ },
14854
+ "notes": "In private browsing mode Safari and iOS Safari don't support setting localStorage.",
14855
+ "usage_perc_y": 89.13,
14856
+ "usage_perc_a": 0.1,
14857
+ "ucprefix": false,
14858
+ "parent": "",
14859
+ "keywords": "webstorage,local storage"
14860
+ },
14861
+ "sql-storage": {
14862
+ "title": "Web SQL Database",
14863
+ "description": "Method of storing data client-side, allows Sqlite database queries for access and manipulation",
14864
+ "spec": "http://www.w3.org/TR/webdatabase/",
14865
+ "status": "unoff",
14866
+ "links": [{
14867
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-sql-db",
14868
+ "title": "has.js test"
14869
+ }, {
14870
+ "url": "http://html5doctor.com/introducing-web-sql-databases/",
14871
+ "title": "HTML5 Doctor article"
14872
+ }],
14873
+ "categories": ["JS API"],
14874
+ "stats": {
14875
+ "ie": {
14876
+ "5.5": "n",
14877
+ "6": "n",
14878
+ "7": "n",
14879
+ "8": "n",
14880
+ "9": "n",
14881
+ "10": "n",
14882
+ "11": "n"
14883
+ },
14884
+ "firefox": {
14885
+ "2": "n",
14886
+ "3": "n",
14887
+ "3.5": "n",
14888
+ "3.6": "n",
14889
+ "4": "n",
14890
+ "5": "n",
14891
+ "6": "n",
14892
+ "7": "n",
14893
+ "8": "n",
14894
+ "9": "n",
14895
+ "10": "n",
14896
+ "11": "n",
14897
+ "12": "n",
14898
+ "13": "n",
14899
+ "14": "n",
14900
+ "15": "n",
14901
+ "16": "n",
14902
+ "17": "n",
14903
+ "18": "n",
14904
+ "19": "n",
14905
+ "20": "n",
14906
+ "21": "n",
14907
+ "22": "n",
14908
+ "23": "n",
14909
+ "24": "n",
14910
+ "25": "n",
14911
+ "26": "n",
14912
+ "27": "n"
14913
+ },
14914
+ "chrome": {
14915
+ "4": "y",
14916
+ "5": "y",
14917
+ "6": "y",
14918
+ "7": "y",
14919
+ "8": "y",
14920
+ "9": "y",
14921
+ "10": "y",
14922
+ "11": "y",
14923
+ "12": "y",
14924
+ "13": "y",
14925
+ "14": "y",
14926
+ "15": "y",
14927
+ "16": "y",
14928
+ "17": "y",
14929
+ "18": "y",
14930
+ "19": "y",
14931
+ "20": "y",
14932
+ "21": "y",
14933
+ "22": "y",
14934
+ "23": "y",
14935
+ "24": "y",
14936
+ "25": "y",
14937
+ "26": "y",
14938
+ "27": "y",
14939
+ "28": "y",
14940
+ "29": "y",
14941
+ "30": "y",
14942
+ "31": "y",
14943
+ "32": "y"
14944
+ },
14945
+ "safari": {
14946
+ "3.1": "y",
14947
+ "3.2": "y",
14948
+ "4": "y",
14949
+ "5": "y",
14950
+ "5.1": "y",
14951
+ "6": "y",
14952
+ "6.1": "y",
14953
+ "7": "y"
14954
+ },
14955
+ "opera": {
14956
+ "9": "n",
14957
+ "9.5-9.6": "n",
14958
+ "10.0-10.1": "n",
14959
+ "10.5": "y",
14960
+ "10.6": "y",
14961
+ "11": "y",
14962
+ "11.1": "y",
14963
+ "11.5": "y",
14964
+ "11.6": "y",
14965
+ "12": "y",
14966
+ "12.1": "y",
14967
+ "15": "y",
14968
+ "16": "y",
14969
+ "17": "y",
14970
+ "18": "y"
14971
+ },
14972
+ "ios_saf": {
14973
+ "3.2": "y",
14974
+ "4.0-4.1": "y",
14975
+ "4.2-4.3": "y",
14976
+ "5.0-5.1": "y",
14977
+ "6.0-6.1": "y",
14978
+ "7.0": "y"
14979
+ },
14980
+ "op_mini": {
14981
+ "5.0-7.0": "n"
14982
+ },
14983
+ "android": {
14984
+ "2.1": "y",
14985
+ "2.2": "y",
14986
+ "2.3": "y",
14987
+ "3": "y",
14988
+ "4": "y",
14989
+ "4.1": "y",
14990
+ "4.2-4.3": "y",
14991
+ "4.4": "y"
14992
+ },
14993
+ "bb": {
14994
+ "7": "y",
14995
+ "10": "y"
14996
+ },
14997
+ "op_mob": {
14998
+ "10": "n",
14999
+ "11": "y",
15000
+ "11.1": "y",
15001
+ "11.5": "y",
15002
+ "12": "y",
15003
+ "12.1": "y",
15004
+ "0": "y"
15005
+ },
15006
+ "and_chr": {
15007
+ "0": "y"
15008
+ },
15009
+ "and_ff": {
15010
+ "0": "n"
15011
+ },
15012
+ "ie_mob": {
15013
+ "10": "n"
15014
+ }
15015
+ },
15016
+ "notes": "The Web SQL Database specification is no longer being maintained and support may be dropped in future versions.",
15017
+ "usage_perc_y": 49.18,
15018
+ "usage_perc_a": 0,
15019
+ "ucprefix": false,
15020
+ "parent": "",
15021
+ "keywords": "db-storage,websql"
15022
+ },
15023
+ "indexeddb": {
15024
+ "title": "IndexedDB",
15025
+ "description": "Method of storing data client-side, allows indexed database queries. Previously known as WebSimpleDB API.",
15026
+ "spec": "http://www.w3.org/TR/IndexedDB/",
15027
+ "status": "wd",
15028
+ "links": [{
15029
+ "url": "http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/",
15030
+ "title": "Mozilla Hacks article"
15031
+ }, {
15032
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-indexeddb",
15033
+ "title": "has.js test"
15034
+ }, {
15035
+ "url": "http://docs.webplatform.org/wiki/apis/indexedDB",
15036
+ "title": "WebPlatform Docs"
15037
+ }, {
15038
+ "url": "https://github.com/axemclion/IndexedDBShim",
15039
+ "title": "Polyfill for browsers supporting WebSQL"
15040
+ }],
15041
+ "categories": ["JS API"],
15042
+ "stats": {
15043
+ "ie": {
15044
+ "5.5": "n",
15045
+ "6": "n",
15046
+ "7": "n",
15047
+ "8": "n",
15048
+ "9": "n",
15049
+ "10": "y",
15050
+ "11": "y"
15051
+ },
15052
+ "firefox": {
15053
+ "2": "n",
15054
+ "3": "n",
15055
+ "3.5": "n",
15056
+ "3.6": "n",
15057
+ "4": "a x",
15058
+ "5": "a x",
15059
+ "6": "a x",
15060
+ "7": "a x",
15061
+ "8": "a x",
15062
+ "9": "a x",
15063
+ "10": "y x",
15064
+ "11": "y x",
15065
+ "12": "y x",
15066
+ "13": "y x",
15067
+ "14": "y x",
15068
+ "15": "y x",
15069
+ "16": "y",
15070
+ "17": "y",
15071
+ "18": "y",
15072
+ "19": "y",
15073
+ "20": "y",
15074
+ "21": "y",
15075
+ "22": "y",
15076
+ "23": "y",
15077
+ "24": "y",
15078
+ "25": "y",
15079
+ "26": "y",
15080
+ "27": "y"
15081
+ },
15082
+ "chrome": {
15083
+ "4": "n",
15084
+ "5": "n",
15085
+ "6": "n",
15086
+ "7": "n",
15087
+ "8": "n",
15088
+ "9": "n",
15089
+ "10": "n",
15090
+ "11": "a x",
15091
+ "12": "a x",
15092
+ "13": "a x",
15093
+ "14": "a x",
15094
+ "15": "a x",
15095
+ "16": "a x",
15096
+ "17": "a x",
15097
+ "18": "a x",
15098
+ "19": "a x",
15099
+ "20": "a x",
15100
+ "21": "a x",
15101
+ "22": "a x",
15102
+ "23": "y x",
15103
+ "24": "y",
15104
+ "25": "y",
15105
+ "26": "y",
15106
+ "27": "y",
15107
+ "28": "y",
15108
+ "29": "y",
15109
+ "30": "y",
15110
+ "31": "y",
15111
+ "32": "y"
15112
+ },
15113
+ "safari": {
15114
+ "3.1": "n",
15115
+ "3.2": "n",
15116
+ "4": "n",
15117
+ "5": "n",
15118
+ "5.1": "n",
15119
+ "6": "n",
15120
+ "6.1": "n",
15121
+ "7": "n"
15122
+ },
15123
+ "opera": {
15124
+ "9": "n",
15125
+ "9.5-9.6": "n",
15126
+ "10.0-10.1": "n",
15127
+ "10.5": "n",
15128
+ "10.6": "n",
15129
+ "11": "n",
15130
+ "11.1": "n",
15131
+ "11.5": "n",
15132
+ "11.6": "n",
15133
+ "12": "n",
15134
+ "12.1": "n",
15135
+ "15": "y",
15136
+ "16": "y",
15137
+ "17": "y",
15138
+ "18": "y"
15139
+ },
15140
+ "ios_saf": {
15141
+ "3.2": "n",
15142
+ "4.0-4.1": "n",
15143
+ "4.2-4.3": "n",
15144
+ "5.0-5.1": "n",
15145
+ "6.0-6.1": "n",
15146
+ "7.0": "n"
15147
+ },
15148
+ "op_mini": {
15149
+ "5.0-7.0": "n"
15150
+ },
15151
+ "android": {
15152
+ "2.1": "n",
15153
+ "2.2": "n",
15154
+ "2.3": "n",
15155
+ "3": "n",
15156
+ "4": "n",
15157
+ "4.1": "n",
15158
+ "4.2-4.3": "n",
15159
+ "4.4": "y"
15160
+ },
15161
+ "bb": {
15162
+ "7": "n",
15163
+ "10": "a x"
15164
+ },
15165
+ "op_mob": {
15166
+ "10": "n",
15167
+ "11": "n",
15168
+ "11.1": "n",
15169
+ "11.5": "n",
15170
+ "12": "n",
15171
+ "12.1": "n",
15172
+ "0": "y"
15173
+ },
15174
+ "and_chr": {
15175
+ "0": "y"
15176
+ },
15177
+ "and_ff": {
15178
+ "0": "y"
15179
+ },
15180
+ "ie_mob": {
15181
+ "10": "y"
15182
+ }
15183
+ },
15184
+ "notes": "Partial support in BB10 refers to an <a href=\"http://www.w3.org/TR/2011/WD-IndexedDB-20110419/\">outdated specification</a> being implemented. Code targeting the <a href=\"http://www.w3.org/TR/IndexedDB/\">current state of the specification</a> might not work.",
15185
+ "usage_perc_y": 59.46,
15186
+ "usage_perc_a": 1.68,
15187
+ "ucprefix": false,
15188
+ "parent": "",
15189
+ "keywords": "indexdb"
15190
+ },
15191
+ "eventsource": {
15192
+ "title": "Server-sent DOM events",
15193
+ "description": "Method of continuously sending data from a server to the browser, rather than repeatedly requesting it (EventSource interface, used to fall under HTML5)",
15194
+ "spec": "http://www.w3.org/TR/eventsource/",
15195
+ "status": "cr",
15196
+ "links": [{
15197
+ "url": "http://www.html5rocks.com/tutorials/eventsource/basics/",
15198
+ "title": "HTML5 Rocks tutorial"
15199
+ }, {
15200
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-eventsource",
15201
+ "title": "has.js test"
15202
+ }, {
15203
+ "url": "http://samshull.blogspot.com/2010/10/ajax-push-in-ios-safari-and-chrome-with.html",
15204
+ "title": "Blog post with demo"
15205
+ }],
15206
+ "categories": ["JS API"],
15207
+ "stats": {
15208
+ "ie": {
15209
+ "5.5": "n",
15210
+ "6": "n",
15211
+ "7": "n",
15212
+ "8": "n",
15213
+ "9": "n",
15214
+ "10": "n",
15215
+ "11": "n"
15216
+ },
15217
+ "firefox": {
15218
+ "2": "n",
15219
+ "3": "n",
15220
+ "3.5": "n",
15221
+ "3.6": "n",
15222
+ "4": "n",
15223
+ "5": "n",
15224
+ "6": "y",
15225
+ "7": "y",
15226
+ "8": "y",
15227
+ "9": "y",
15228
+ "10": "y",
15229
+ "11": "y",
15230
+ "12": "y",
15231
+ "13": "y",
15232
+ "14": "y",
15233
+ "15": "y",
15234
+ "16": "y",
15235
+ "17": "y",
15236
+ "18": "y",
15237
+ "19": "y",
15238
+ "20": "y",
15239
+ "21": "y",
15240
+ "22": "y",
15241
+ "23": "y",
15242
+ "24": "y",
15243
+ "25": "y",
15244
+ "26": "y",
15245
+ "27": "y"
15246
+ },
15247
+ "chrome": {
15248
+ "4": "n",
15249
+ "5": "n",
15250
+ "6": "y",
15251
+ "7": "y",
15252
+ "8": "y",
15253
+ "9": "y",
15254
+ "10": "y",
15255
+ "11": "y",
15256
+ "12": "y",
15257
+ "13": "y",
15258
+ "14": "y",
15259
+ "15": "y",
15260
+ "16": "y",
15261
+ "17": "y",
15262
+ "18": "y",
15263
+ "19": "y",
15264
+ "20": "y",
15265
+ "21": "y",
15266
+ "22": "y",
15267
+ "23": "y",
15268
+ "24": "y",
15269
+ "25": "y",
15270
+ "26": "y",
15271
+ "27": "y",
15272
+ "28": "y",
15273
+ "29": "y",
15274
+ "30": "y",
15275
+ "31": "y",
15276
+ "32": "y"
15277
+ },
15278
+ "safari": {
15279
+ "3.1": "n",
15280
+ "3.2": "n",
15281
+ "4": "n",
15282
+ "5": "y",
15283
+ "5.1": "y",
15284
+ "6": "y",
15285
+ "6.1": "y",
15286
+ "7": "y"
15287
+ },
15288
+ "opera": {
15289
+ "9": "a",
15290
+ "9.5-9.6": "a",
15291
+ "10.0-10.1": "a",
15292
+ "10.5": "a",
15293
+ "10.6": "a",
15294
+ "11": "y",
15295
+ "11.1": "y",
15296
+ "11.5": "y",
15297
+ "11.6": "y",
15298
+ "12": "y",
15299
+ "12.1": "y",
15300
+ "15": "y",
15301
+ "16": "y",
15302
+ "17": "y",
15303
+ "18": "y"
15304
+ },
15305
+ "ios_saf": {
15306
+ "3.2": "n",
15307
+ "4.0-4.1": "y",
15308
+ "4.2-4.3": "y",
15309
+ "5.0-5.1": "y",
15310
+ "6.0-6.1": "y",
15311
+ "7.0": "y"
15312
+ },
15313
+ "op_mini": {
15314
+ "5.0-7.0": "n"
15315
+ },
15316
+ "android": {
15317
+ "2.1": "n",
15318
+ "2.2": "n",
15319
+ "2.3": "n",
15320
+ "3": "n",
15321
+ "4": "n",
15322
+ "4.1": "n",
15323
+ "4.2-4.3": "n",
15324
+ "4.4": "y"
15325
+ },
15326
+ "bb": {
15327
+ "7": "y",
15328
+ "10": "y"
15329
+ },
15330
+ "op_mob": {
15331
+ "10": "a",
15332
+ "11": "a",
15333
+ "11.1": "y",
15334
+ "11.5": "y",
15335
+ "12": "y",
15336
+ "12.1": "y",
15337
+ "0": "y"
15338
+ },
15339
+ "and_chr": {
15340
+ "0": "y"
15341
+ },
15342
+ "and_ff": {
15343
+ "0": "y"
15344
+ },
15345
+ "ie_mob": {
15346
+ "10": "n"
15347
+ }
15348
+ },
15349
+ "notes": "",
15350
+ "usage_perc_y": 58.8,
15351
+ "usage_perc_a": 0.06,
15352
+ "ucprefix": false,
15353
+ "parent": "",
15354
+ "keywords": "serversent,s-sent-events"
15355
+ },
15356
+ "x-doc-messaging": {
15357
+ "title": "Cross-document messaging",
15358
+ "description": "Method of sending information from a page on one domain to a page on a different one (using postMessage)",
15359
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages",
15360
+ "status": "wd",
15361
+ "links": [{
15362
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-crosswindowmessaging",
15363
+ "title": "has.js test"
15364
+ }, {
15365
+ "url": "http://html5demos.com/postmessage2",
15366
+ "title": "Simple demo"
15367
+ }, {
15368
+ "url": "https://developer.mozilla.org/en/DOM/window.postMessage",
15369
+ "title": "MDN article"
15370
+ }, {
15371
+ "url": "http://docs.webplatform.org/wiki/apis/web-messaging/methods/postMessage_%28window%29",
15372
+ "title": "WebPlatform Docs"
15373
+ }, {
15374
+ "url": "http://72lions.com/2011/05/cross-origin-communication-with-html5",
15375
+ "title": "Article and demo"
15376
+ }],
15377
+ "categories": ["JS API"],
15378
+ "stats": {
15379
+ "ie": {
15380
+ "5.5": "n",
15381
+ "6": "n",
15382
+ "7": "n",
15383
+ "8": "a",
15384
+ "9": "a",
15385
+ "10": "a",
15386
+ "11": "y"
15387
+ },
15388
+ "firefox": {
15389
+ "2": "n",
15390
+ "3": "y",
15391
+ "3.5": "y",
15392
+ "3.6": "y",
15393
+ "4": "y",
15394
+ "5": "y",
15395
+ "6": "y",
15396
+ "7": "y",
15397
+ "8": "y",
15398
+ "9": "y",
15399
+ "10": "y",
15400
+ "11": "y",
15401
+ "12": "y",
15402
+ "13": "y",
15403
+ "14": "y",
15404
+ "15": "y",
15405
+ "16": "y",
15406
+ "17": "y",
15407
+ "18": "y",
15408
+ "19": "y",
15409
+ "20": "y",
15410
+ "21": "y",
15411
+ "22": "y",
15412
+ "23": "y",
15413
+ "24": "y",
15414
+ "25": "y",
15415
+ "26": "y",
15416
+ "27": "y"
15417
+ },
15418
+ "chrome": {
15419
+ "4": "y",
15420
+ "5": "y",
15421
+ "6": "y",
15422
+ "7": "y",
15423
+ "8": "y",
15424
+ "9": "y",
15425
+ "10": "y",
15426
+ "11": "y",
15427
+ "12": "y",
15428
+ "13": "y",
15429
+ "14": "y",
15430
+ "15": "y",
15431
+ "16": "y",
15432
+ "17": "y",
15433
+ "18": "y",
15434
+ "19": "y",
15435
+ "20": "y",
15436
+ "21": "y",
15437
+ "22": "y",
15438
+ "23": "y",
15439
+ "24": "y",
15440
+ "25": "y",
15441
+ "26": "y",
15442
+ "27": "y",
15443
+ "28": "y",
15444
+ "29": "y",
15445
+ "30": "y",
15446
+ "31": "y",
15447
+ "32": "y"
15448
+ },
15449
+ "safari": {
15450
+ "3.1": "n",
15451
+ "3.2": "n",
15452
+ "4": "y",
15453
+ "5": "y",
15454
+ "5.1": "y",
15455
+ "6": "y",
15456
+ "6.1": "y",
15457
+ "7": "y"
15458
+ },
15459
+ "opera": {
15460
+ "9": "n",
15461
+ "9.5-9.6": "y",
15462
+ "10.0-10.1": "y",
15463
+ "10.5": "y",
15464
+ "10.6": "y",
15465
+ "11": "y",
15466
+ "11.1": "y",
15467
+ "11.5": "y",
15468
+ "11.6": "y",
15469
+ "12": "y",
15470
+ "12.1": "y",
15471
+ "15": "y",
15472
+ "16": "y",
15473
+ "17": "y",
15474
+ "18": "y"
15475
+ },
15476
+ "ios_saf": {
15477
+ "3.2": "y",
15478
+ "4.0-4.1": "y",
15479
+ "4.2-4.3": "y",
15480
+ "5.0-5.1": "y",
15481
+ "6.0-6.1": "y",
15482
+ "7.0": "y"
15483
+ },
15484
+ "op_mini": {
15485
+ "5.0-7.0": "y"
15486
+ },
15487
+ "android": {
15488
+ "2.1": "y",
15489
+ "2.2": "y",
15490
+ "2.3": "y",
15491
+ "3": "y",
15492
+ "4": "y",
15493
+ "4.1": "y",
15494
+ "4.2-4.3": "y",
15495
+ "4.4": "y"
15496
+ },
15497
+ "bb": {
15498
+ "7": "y",
15499
+ "10": "y"
15500
+ },
15501
+ "op_mob": {
15502
+ "10": "y",
15503
+ "11": "y",
15504
+ "11.1": "y",
15505
+ "11.5": "y",
15506
+ "12": "y",
15507
+ "12.1": "y",
15508
+ "0": "y"
15509
+ },
15510
+ "and_chr": {
15511
+ "0": "y"
15512
+ },
15513
+ "and_ff": {
15514
+ "0": "y"
15515
+ },
15516
+ "ie_mob": {
15517
+ "10": "a"
15518
+ }
15519
+ },
15520
+ "notes": "Partial support in IE8-9 refers to only working in frames/iframes (not other tabs/windows). Also in IE 9 and below an object cannot be sent using postMessage. Partial support in IE10 refers to <a href=\"http://stackoverflow.com/questions/16226924/is-cross-origin-postmessage-broken-in-ie10\">limitations in certain conditions</a>",
15521
+ "usage_perc_y": 69.31,
15522
+ "usage_perc_a": 24.52,
15523
+ "ucprefix": false,
15524
+ "parent": "",
15525
+ "keywords": ""
15526
+ },
15527
+ "datauri": {
15528
+ "title": "Data URIs",
15529
+ "description": "Method of embedding images and other files in webpages as a string of text",
15530
+ "spec": "http://www.ietf.org/rfc/rfc2397.txt",
15531
+ "status": "other",
15532
+ "links": [{
15533
+ "url": "http://www.websiteoptimization.com/speed/tweak/inline-images/",
15534
+ "title": "Data URL converter"
15535
+ }, {
15536
+ "url": "http://css-tricks.com/5970-data-uris/",
15537
+ "title": "Information page"
15538
+ }, {
15539
+ "url": "http://en.wikipedia.org/wiki/data_URI_scheme",
15540
+ "title": "Wikipedia"
15541
+ }],
15542
+ "categories": ["Other"],
15543
+ "stats": {
15544
+ "ie": {
15545
+ "5.5": "n",
15546
+ "6": "n",
15547
+ "7": "n",
15548
+ "8": "a",
15549
+ "9": "a",
15550
+ "10": "a",
15551
+ "11": "a"
15552
+ },
15553
+ "firefox": {
15554
+ "2": "y",
15555
+ "3": "y",
15556
+ "3.5": "y",
15557
+ "3.6": "y",
15558
+ "4": "y",
15559
+ "5": "y",
15560
+ "6": "y",
15561
+ "7": "y",
15562
+ "8": "y",
15563
+ "9": "y",
15564
+ "10": "y",
15565
+ "11": "y",
15566
+ "12": "y",
15567
+ "13": "y",
15568
+ "14": "y",
15569
+ "15": "y",
15570
+ "16": "y",
15571
+ "17": "y",
15572
+ "18": "y",
15573
+ "19": "y",
15574
+ "20": "y",
15575
+ "21": "y",
15576
+ "22": "y",
15577
+ "23": "y",
15578
+ "24": "y",
15579
+ "25": "y",
15580
+ "26": "y",
15581
+ "27": "y"
15582
+ },
15583
+ "chrome": {
15584
+ "4": "y",
15585
+ "5": "y",
15586
+ "6": "y",
15587
+ "7": "y",
15588
+ "8": "y",
15589
+ "9": "y",
15590
+ "10": "y",
15591
+ "11": "y",
15592
+ "12": "y",
15593
+ "13": "y",
15594
+ "14": "y",
15595
+ "15": "y",
15596
+ "16": "y",
15597
+ "17": "y",
15598
+ "18": "y",
15599
+ "19": "y",
15600
+ "20": "y",
15601
+ "21": "y",
15602
+ "22": "y",
15603
+ "23": "y",
15604
+ "24": "y",
15605
+ "25": "y",
15606
+ "26": "y",
15607
+ "27": "y",
15608
+ "28": "y",
15609
+ "29": "y",
15610
+ "30": "y",
15611
+ "31": "y",
15612
+ "32": "y"
15613
+ },
15614
+ "safari": {
15615
+ "3.1": "y",
15616
+ "3.2": "y",
15617
+ "4": "y",
15618
+ "5": "y",
15619
+ "5.1": "y",
15620
+ "6": "y",
15621
+ "6.1": "y",
15622
+ "7": "y"
15623
+ },
15624
+ "opera": {
15625
+ "9": "y",
15626
+ "9.5-9.6": "y",
15627
+ "10.0-10.1": "y",
15628
+ "10.5": "y",
15629
+ "10.6": "y",
15630
+ "11": "y",
15631
+ "11.1": "y",
15632
+ "11.5": "y",
15633
+ "11.6": "y",
15634
+ "12": "y",
15635
+ "12.1": "y",
15636
+ "15": "y",
15637
+ "16": "y",
15638
+ "17": "y",
15639
+ "18": "y"
15640
+ },
15641
+ "ios_saf": {
15642
+ "3.2": "y",
15643
+ "4.0-4.1": "y",
15644
+ "4.2-4.3": "y",
15645
+ "5.0-5.1": "y",
15646
+ "6.0-6.1": "y",
15647
+ "7.0": "y"
15648
+ },
15649
+ "op_mini": {
15650
+ "5.0-7.0": "y"
15651
+ },
15652
+ "android": {
15653
+ "2.1": "y",
15654
+ "2.2": "y",
15655
+ "2.3": "y",
15656
+ "3": "y",
15657
+ "4": "y",
15658
+ "4.1": "y",
15659
+ "4.2-4.3": "y",
15660
+ "4.4": "y"
15661
+ },
15662
+ "bb": {
15663
+ "7": "y",
15664
+ "10": "y"
15665
+ },
15666
+ "op_mob": {
15667
+ "10": "y",
15668
+ "11": "y",
15669
+ "11.1": "y",
15670
+ "11.5": "y",
15671
+ "12": "y",
15672
+ "12.1": "y",
15673
+ "0": "y"
15674
+ },
15675
+ "and_chr": {
15676
+ "0": "y"
15677
+ },
15678
+ "and_ff": {
15679
+ "0": "y"
15680
+ },
15681
+ "ie_mob": {
15682
+ "10": "a"
15683
+ }
15684
+ },
15685
+ "notes": "Support in Internet Explorer 8 is limited to images and linked resources like CSS files, not HTML files. Max URI length in IE8 is 32KB. In IE9+ JavaScript files are supported too and the maximum size limit set to 4GB.",
15686
+ "usage_perc_y": 69.23,
15687
+ "usage_perc_a": 24.63,
15688
+ "ucprefix": false,
15689
+ "parent": "",
15690
+ "keywords": "data url,datauris,data uri,dataurl,dataurls"
15691
+ },
15692
+ "mathml": {
15693
+ "title": "MathML",
15694
+ "description": "An XML language that allows mathematical formulas and notations to be written on web pages.",
15695
+ "spec": "http://www.w3.org/TR/MathML/",
15696
+ "status": "rec",
15697
+ "links": [{
15698
+ "url": "http://www.mozilla.org/projects/mathml/demo/",
15699
+ "title": "MathML demos"
15700
+ }, {
15701
+ "url": "http://en.wikipedia.org/wiki/MathML",
15702
+ "title": "Wikipedia"
15703
+ }, {
15704
+ "url": "http://www.mathjax.org",
15705
+ "title": "Cross-browser support script"
15706
+ }, {
15707
+ "url": "https://developer.mozilla.org/en/MathML/Element",
15708
+ "title": "MDN element reference"
15709
+ }],
15710
+ "categories": ["Other"],
15711
+ "stats": {
15712
+ "ie": {
15713
+ "5.5": "n",
15714
+ "6": "p",
15715
+ "7": "p",
15716
+ "8": "p",
15717
+ "9": "n",
15718
+ "10": "n",
15719
+ "11": "n"
15720
+ },
15721
+ "firefox": {
15722
+ "2": "y",
15723
+ "3": "y",
15724
+ "3.5": "y",
15725
+ "3.6": "y",
15726
+ "4": "y",
15727
+ "5": "y",
15728
+ "6": "y",
15729
+ "7": "y",
15730
+ "8": "y",
15731
+ "9": "y",
15732
+ "10": "y",
15733
+ "11": "y",
15734
+ "12": "y",
15735
+ "13": "y",
15736
+ "14": "y",
15737
+ "15": "y",
15738
+ "16": "y",
15739
+ "17": "y",
15740
+ "18": "y",
15741
+ "19": "y",
15742
+ "20": "y",
15743
+ "21": "y",
15744
+ "22": "y",
15745
+ "23": "y",
15746
+ "24": "y",
15747
+ "25": "y",
15748
+ "26": "y",
15749
+ "27": "y"
15750
+ },
15751
+ "chrome": {
15752
+ "4": "p",
15753
+ "5": "p",
15754
+ "6": "p",
15755
+ "7": "p",
15756
+ "8": "p",
15757
+ "9": "p",
15758
+ "10": "p",
15759
+ "11": "p",
15760
+ "12": "p",
15761
+ "13": "p",
15762
+ "14": "p",
15763
+ "15": "p",
15764
+ "16": "p",
15765
+ "17": "p",
15766
+ "18": "p",
15767
+ "19": "p",
15768
+ "20": "p",
15769
+ "21": "p",
15770
+ "22": "p",
15771
+ "23": "p",
15772
+ "24": "y",
15773
+ "25": "p",
15774
+ "26": "p",
15775
+ "27": "p",
15776
+ "28": "p",
15777
+ "29": "p",
15778
+ "30": "p",
15779
+ "31": "p",
15780
+ "32": "p"
15781
+ },
15782
+ "safari": {
15783
+ "3.1": "p",
15784
+ "3.2": "p",
15785
+ "4": "p",
15786
+ "5": "p",
15787
+ "5.1": "y",
15788
+ "6": "y",
15789
+ "6.1": "y",
15790
+ "7": "y"
15791
+ },
15792
+ "opera": {
15793
+ "9": "n",
15794
+ "9.5-9.6": "a",
15795
+ "10.0-10.1": "a",
15796
+ "10.5": "a",
15797
+ "10.6": "a",
15798
+ "11": "a",
15799
+ "11.1": "a",
15800
+ "11.5": "a",
15801
+ "11.6": "a",
15802
+ "12": "a",
15803
+ "12.1": "a",
15804
+ "15": "p",
15805
+ "16": "p",
15806
+ "17": "p",
15807
+ "18": "p"
15808
+ },
15809
+ "ios_saf": {
15810
+ "3.2": "p",
15811
+ "4.0-4.1": "p",
15812
+ "4.2-4.3": "p",
15813
+ "5.0-5.1": "y",
15814
+ "6.0-6.1": "y",
15815
+ "7.0": "y"
15816
+ },
15817
+ "op_mini": {
15818
+ "5.0-7.0": "p"
15819
+ },
15820
+ "android": {
15821
+ "2.1": "p",
15822
+ "2.2": "p",
15823
+ "2.3": "p",
15824
+ "3": "p",
15825
+ "4": "p",
15826
+ "4.1": "p",
15827
+ "4.2-4.3": "p",
15828
+ "4.4": "p"
15829
+ },
15830
+ "bb": {
15831
+ "7": "p",
15832
+ "10": "y"
15833
+ },
15834
+ "op_mob": {
15835
+ "10": "p",
15836
+ "11": "p",
15837
+ "11.1": "p",
15838
+ "11.5": "p",
15839
+ "12": "p",
15840
+ "12.1": "p",
15841
+ "0": "p"
15842
+ },
15843
+ "and_chr": {
15844
+ "0": "p"
15845
+ },
15846
+ "and_ff": {
15847
+ "0": "y"
15848
+ },
15849
+ "ie_mob": {
15850
+ "10": "n"
15851
+ }
15852
+ },
15853
+ "notes": "Opera's support is limited to a CSS profile of MathML. Support was added in Chrome 24, but removed afterwards due to instability.",
15854
+ "usage_perc_y": 23.15,
15855
+ "usage_perc_a": 0.63,
15856
+ "ucprefix": false,
15857
+ "parent": "",
15858
+ "keywords": ""
15859
+ },
15860
+ "css-featurequeries": {
15861
+ "title": "CSS Feature Queries",
15862
+ "description": "CSS Feature Queries allow authors to condition rules based on whether particular property declarations are supported in CSS using the @supports at rule.",
15863
+ "spec": "http://www.w3.org/TR/css3-conditional/#at-supports",
15864
+ "status": "cr",
15865
+ "links": [{
15866
+ "url": "http://dabblet.com/gist/3895764",
15867
+ "title": "Test case"
15868
+ }, {
15869
+ "url": "http://mcc.id.au/blog/2012/08/supports",
15870
+ "title": "@supports in Firefox"
15871
+ }, {
15872
+ "url": "https://developer.mozilla.org/en-US/docs/Web/CSS/@supports",
15873
+ "title": "MDN Article"
15874
+ }, {
15875
+ "url": "http://docs.webplatform.org/wiki/css/atrules/@supports",
15876
+ "title": "WebPlatform Docs"
15877
+ }],
15878
+ "categories": ["CSS3"],
15879
+ "stats": {
15880
+ "ie": {
15881
+ "5.5": "n",
15882
+ "6": "n",
15883
+ "7": "n",
15884
+ "8": "n",
15885
+ "9": "n",
15886
+ "10": "n",
15887
+ "11": "n"
15888
+ },
15889
+ "firefox": {
15890
+ "2": "n",
15891
+ "3": "n",
15892
+ "3.5": "n",
15893
+ "3.6": "n",
15894
+ "4": "n",
15895
+ "5": "n",
15896
+ "6": "n",
15897
+ "7": "n",
15898
+ "8": "n",
15899
+ "9": "n",
15900
+ "10": "n",
15901
+ "11": "n",
15902
+ "12": "n",
15903
+ "13": "n",
15904
+ "14": "n",
15905
+ "15": "n",
15906
+ "16": "n",
15907
+ "17": "n",
15908
+ "18": "n",
15909
+ "19": "n",
15910
+ "20": "n",
15911
+ "21": "n",
15912
+ "22": "y",
15913
+ "23": "y",
15914
+ "24": "y",
15915
+ "25": "y",
15916
+ "26": "y",
15917
+ "27": "y"
15918
+ },
15919
+ "chrome": {
15920
+ "4": "n",
15921
+ "5": "n",
15922
+ "6": "n",
15923
+ "7": "n",
15924
+ "8": "n",
15925
+ "9": "n",
15926
+ "10": "n",
15927
+ "11": "n",
15928
+ "12": "n",
15929
+ "13": "n",
15930
+ "14": "n",
15931
+ "15": "n",
15932
+ "16": "n",
15933
+ "17": "n",
15934
+ "18": "n",
15935
+ "19": "n",
15936
+ "20": "n",
15937
+ "21": "n",
15938
+ "22": "n",
15939
+ "23": "n",
15940
+ "24": "n",
15941
+ "25": "n",
15942
+ "26": "n",
15943
+ "27": "n",
15944
+ "28": "y",
15945
+ "29": "y",
15946
+ "30": "y",
15947
+ "31": "y",
15948
+ "32": "y"
15949
+ },
15950
+ "safari": {
15951
+ "3.1": "n",
15952
+ "3.2": "n",
15953
+ "4": "n",
15954
+ "5": "n",
15955
+ "5.1": "n",
15956
+ "6": "n",
15957
+ "6.1": "n",
15958
+ "7": "n"
15959
+ },
15960
+ "opera": {
15961
+ "9": "n",
15962
+ "9.5-9.6": "n",
15963
+ "10.0-10.1": "n",
15964
+ "10.5": "n",
15965
+ "10.6": "n",
15966
+ "11": "n",
15967
+ "11.1": "n",
15968
+ "11.5": "n",
15969
+ "11.6": "n",
15970
+ "12": "n",
15971
+ "12.1": "y",
15972
+ "15": "y",
15973
+ "16": "y",
15974
+ "17": "y",
15975
+ "18": "y"
15976
+ },
15977
+ "ios_saf": {
15978
+ "3.2": "n",
15979
+ "4.0-4.1": "n",
15980
+ "4.2-4.3": "n",
15981
+ "5.0-5.1": "n",
15982
+ "6.0-6.1": "n",
15983
+ "7.0": "n"
15984
+ },
15985
+ "op_mini": {
15986
+ "5.0-7.0": "n"
15987
+ },
15988
+ "android": {
15989
+ "2.1": "n",
15990
+ "2.2": "n",
15991
+ "2.3": "n",
15992
+ "3": "n",
15993
+ "4": "n",
15994
+ "4.1": "n",
15995
+ "4.2-4.3": "n",
15996
+ "4.4": "y"
15997
+ },
15998
+ "bb": {
15999
+ "7": "n",
16000
+ "10": "n"
16001
+ },
16002
+ "op_mob": {
16003
+ "10": "n",
16004
+ "11": "n",
16005
+ "11.1": "n",
16006
+ "11.5": "n",
16007
+ "12": "n",
16008
+ "12.1": "n",
16009
+ "0": "y"
16010
+ },
16011
+ "and_chr": {
16012
+ "0": "y"
16013
+ },
16014
+ "and_ff": {
16015
+ "0": "y"
16016
+ },
16017
+ "ie_mob": {
16018
+ "10": "n"
16019
+ }
16020
+ },
16021
+ "notes": "",
16022
+ "usage_perc_y": 45.52,
16023
+ "usage_perc_a": 0,
16024
+ "ucprefix": false,
16025
+ "parent": "",
16026
+ "keywords": "supports,conditional"
16027
+ },
16028
+ "xhtml": {
16029
+ "title": "XHTML served as application/xhtml+xml",
16030
+ "description": "A strict form of HTML, and allows embedding of other XML languages",
16031
+ "spec": "http://www.w3.org/TR/xhtml1/",
16032
+ "status": "rec",
16033
+ "links": [{
16034
+ "url": "http://en.wikipedia.org/wiki/XHTML",
16035
+ "title": "Wikipedia"
16036
+ }, {
16037
+ "url": "http://docs.webplatform.org/wiki/concepts/internet_and_web/the_web_standards_model#What_is_XHTML.3F",
16038
+ "title": "WebPlatform Docs"
16039
+ }, {
16040
+ "url": "http://www.xmlplease.com/xhtml/xhtml5polyglot/",
16041
+ "title": "Information on XHTML5"
16042
+ }],
16043
+ "categories": ["Other"],
16044
+ "stats": {
16045
+ "ie": {
16046
+ "5.5": "n",
16047
+ "6": "n",
16048
+ "7": "n",
16049
+ "8": "n",
16050
+ "9": "y",
16051
+ "10": "y",
16052
+ "11": "y"
16053
+ },
16054
+ "firefox": {
16055
+ "2": "y",
16056
+ "3": "y",
16057
+ "3.5": "y",
16058
+ "3.6": "y",
16059
+ "4": "y",
16060
+ "5": "y",
16061
+ "6": "y",
16062
+ "7": "y",
16063
+ "8": "y",
16064
+ "9": "y",
16065
+ "10": "y",
16066
+ "11": "y",
16067
+ "12": "y",
16068
+ "13": "y",
16069
+ "14": "y",
16070
+ "15": "y",
16071
+ "16": "y",
16072
+ "17": "y",
16073
+ "18": "y",
16074
+ "19": "y",
16075
+ "20": "y",
16076
+ "21": "y",
16077
+ "22": "y",
16078
+ "23": "y",
16079
+ "24": "y",
16080
+ "25": "y",
16081
+ "26": "y",
16082
+ "27": "y"
16083
+ },
16084
+ "chrome": {
16085
+ "4": "y",
16086
+ "5": "y",
16087
+ "6": "y",
16088
+ "7": "y",
16089
+ "8": "y",
16090
+ "9": "y",
16091
+ "10": "y",
16092
+ "11": "y",
16093
+ "12": "y",
16094
+ "13": "y",
16095
+ "14": "y",
16096
+ "15": "y",
16097
+ "16": "y",
16098
+ "17": "y",
16099
+ "18": "y",
16100
+ "19": "y",
16101
+ "20": "y",
16102
+ "21": "y",
16103
+ "22": "y",
16104
+ "23": "y",
16105
+ "24": "y",
16106
+ "25": "y",
16107
+ "26": "y",
16108
+ "27": "y",
16109
+ "28": "y",
16110
+ "29": "y",
16111
+ "30": "y",
16112
+ "31": "y",
16113
+ "32": "y"
16114
+ },
16115
+ "safari": {
16116
+ "3.1": "y",
16117
+ "3.2": "y",
16118
+ "4": "y",
16119
+ "5": "y",
16120
+ "5.1": "y",
16121
+ "6": "y",
16122
+ "6.1": "y",
16123
+ "7": "y"
16124
+ },
16125
+ "opera": {
16126
+ "9": "y",
16127
+ "9.5-9.6": "y",
16128
+ "10.0-10.1": "y",
16129
+ "10.5": "y",
16130
+ "10.6": "y",
16131
+ "11": "y",
16132
+ "11.1": "y",
16133
+ "11.5": "y",
16134
+ "11.6": "y",
16135
+ "12": "y",
16136
+ "12.1": "y",
16137
+ "15": "y",
16138
+ "16": "y",
16139
+ "17": "y",
16140
+ "18": "y"
16141
+ },
16142
+ "ios_saf": {
16143
+ "3.2": "y",
16144
+ "4.0-4.1": "y",
16145
+ "4.2-4.3": "y",
16146
+ "5.0-5.1": "y",
16147
+ "6.0-6.1": "y",
16148
+ "7.0": "y"
16149
+ },
16150
+ "op_mini": {
16151
+ "5.0-7.0": "y"
16152
+ },
16153
+ "android": {
16154
+ "2.1": "y",
16155
+ "2.2": "y",
16156
+ "2.3": "y",
16157
+ "3": "y",
16158
+ "4": "y",
16159
+ "4.1": "y",
16160
+ "4.2-4.3": "y",
16161
+ "4.4": "y"
16162
+ },
16163
+ "bb": {
16164
+ "7": "y",
16165
+ "10": "y"
16166
+ },
16167
+ "op_mob": {
16168
+ "10": "y",
16169
+ "11": "y",
16170
+ "11.1": "y",
16171
+ "11.5": "y",
16172
+ "12": "y",
16173
+ "12.1": "y",
16174
+ "0": "y"
16175
+ },
16176
+ "and_chr": {
16177
+ "0": "y"
16178
+ },
16179
+ "and_ff": {
16180
+ "0": "y"
16181
+ },
16182
+ "ie_mob": {
16183
+ "10": "y"
16184
+ }
16185
+ },
16186
+ "notes": "The XHTML syntax is very close to HTML, and thus is almost always (<a href=\"https://developer.mozilla.org/en-US/docs/XHTML#MIME_type_versus_DOCTYPE\">incorrectly</a>) served as text/html on the web.",
16187
+ "usage_perc_y": 85.55,
16188
+ "usage_perc_a": 0,
16189
+ "ucprefix": false,
16190
+ "parent": "",
16191
+ "keywords": "xhtml+xml"
16192
+ },
16193
+ "xhtmlsmil": {
16194
+ "title": "XHTML+SMIL animation",
16195
+ "description": "Method of using SMIL animation in web pages",
16196
+ "spec": "http://www.w3.org/TR/XHTMLplusSMIL/",
16197
+ "status": "unoff",
16198
+ "links": [{
16199
+ "url": "http://en.wikipedia.org/wiki/XHTML%2BSMIL",
16200
+ "title": "Wikipedia"
16201
+ }, {
16202
+ "url": "http://leunen.me/fakesmile/",
16203
+ "title": "JS library to support XHTML+SMIL"
16204
+ }],
16205
+ "categories": ["Other"],
16206
+ "stats": {
16207
+ "ie": {
16208
+ "5.5": "n",
16209
+ "6": "a",
16210
+ "7": "a",
16211
+ "8": "a",
16212
+ "9": "n",
16213
+ "10": "n",
16214
+ "11": "n"
16215
+ },
16216
+ "firefox": {
16217
+ "2": "p",
16218
+ "3": "p",
16219
+ "3.5": "p",
16220
+ "3.6": "p",
16221
+ "4": "p",
16222
+ "5": "p",
16223
+ "6": "p",
16224
+ "7": "p",
16225
+ "8": "p",
16226
+ "9": "p",
16227
+ "10": "p",
16228
+ "11": "p",
16229
+ "12": "p",
16230
+ "13": "p",
16231
+ "14": "p",
16232
+ "15": "p",
16233
+ "16": "p",
16234
+ "17": "p",
16235
+ "18": "p",
16236
+ "19": "p",
16237
+ "20": "p",
16238
+ "21": "p",
16239
+ "22": "p",
16240
+ "23": "p",
16241
+ "24": "p",
16242
+ "25": "p",
16243
+ "26": "p",
16244
+ "27": "p"
16245
+ },
16246
+ "chrome": {
16247
+ "4": "p",
16248
+ "5": "p",
16249
+ "6": "p",
16250
+ "7": "p",
16251
+ "8": "p",
16252
+ "9": "p",
16253
+ "10": "p",
16254
+ "11": "p",
16255
+ "12": "p",
16256
+ "13": "p",
16257
+ "14": "p",
16258
+ "15": "p",
16259
+ "16": "p",
16260
+ "17": "p",
16261
+ "18": "p",
16262
+ "19": "p",
16263
+ "20": "p",
16264
+ "21": "p",
16265
+ "22": "p",
16266
+ "23": "p",
16267
+ "24": "p",
16268
+ "25": "p",
16269
+ "26": "p",
16270
+ "27": "p",
16271
+ "28": "p",
16272
+ "29": "p",
16273
+ "30": "p",
16274
+ "31": "p",
16275
+ "32": "p"
16276
+ },
16277
+ "safari": {
16278
+ "3.1": "p",
16279
+ "3.2": "p",
16280
+ "4": "p",
16281
+ "5": "p",
16282
+ "5.1": "p",
16283
+ "6": "p",
16284
+ "6.1": "p",
16285
+ "7": "p"
16286
+ },
16287
+ "opera": {
16288
+ "9": "p",
16289
+ "9.5-9.6": "p",
16290
+ "10.0-10.1": "p",
16291
+ "10.5": "p",
16292
+ "10.6": "p",
16293
+ "11": "p",
16294
+ "11.1": "p",
16295
+ "11.5": "p",
16296
+ "11.6": "p",
16297
+ "12": "p",
16298
+ "12.1": "p",
16299
+ "15": "p",
16300
+ "16": "p",
16301
+ "17": "p",
16302
+ "18": "p"
16303
+ },
16304
+ "ios_saf": {
16305
+ "3.2": "p",
16306
+ "4.0-4.1": "p",
16307
+ "4.2-4.3": "p",
16308
+ "5.0-5.1": "p",
16309
+ "6.0-6.1": "p",
16310
+ "7.0": "p"
16311
+ },
16312
+ "op_mini": {
16313
+ "5.0-7.0": "p"
16314
+ },
16315
+ "android": {
16316
+ "2.1": "p",
16317
+ "2.2": "p",
16318
+ "2.3": "p",
16319
+ "3": "p",
16320
+ "4": "p",
16321
+ "4.1": "p",
16322
+ "4.2-4.3": "p",
16323
+ "4.4": "p"
16324
+ },
16325
+ "bb": {
16326
+ "7": "p",
16327
+ "10": "p"
16328
+ },
16329
+ "op_mob": {
16330
+ "10": "p",
16331
+ "11": "p",
16332
+ "11.1": "p",
16333
+ "11.5": "p",
16334
+ "12": "p",
16335
+ "12.1": "p",
16336
+ "0": "p"
16337
+ },
16338
+ "and_chr": {
16339
+ "0": "p"
16340
+ },
16341
+ "and_ff": {
16342
+ "0": "p"
16343
+ },
16344
+ "ie_mob": {
16345
+ "10": "n"
16346
+ }
16347
+ },
16348
+ "notes": "Internet Explorer supports the W3C proposal HTML+TIME, which is largely the same as XHTML+SMIL",
16349
+ "usage_perc_y": 0,
16350
+ "usage_perc_a": 9.02,
16351
+ "ucprefix": false,
16352
+ "parent": "xhtml",
16353
+ "keywords": ""
16354
+ },
16355
+ "wai-aria": {
16356
+ "title": "WAI-ARIA Accessibility features",
16357
+ "description": "Method of providing ways for people with disabilities to use dynamic web content and web applications.",
16358
+ "spec": "http://www.w3.org/TR/wai-aria/",
16359
+ "status": "cr",
16360
+ "links": [{
16361
+ "url": "http://www.alistapart.com/articles/the-accessibility-of-wai-aria/",
16362
+ "title": "ALA Article"
16363
+ }, {
16364
+ "url": "http://en.wikipedia.org/wiki/WAI-ARIA",
16365
+ "title": "Wikipedia"
16366
+ }, {
16367
+ "url": "http://zufelt.ca/blog/are-you-confused-html5-and-wai-aria-yet",
16368
+ "title": "HTML5/WAI-ARIA information"
16369
+ }, {
16370
+ "url": "http://www.w3.org/WAI/intro/aria",
16371
+ "title": "Information page"
16372
+ }, {
16373
+ "url": "http://www.paciellogroup.com/blog/2011/10/browser-assistive-technology-tests-redux/",
16374
+ "title": "Links to various test results"
16375
+ }],
16376
+ "categories": ["Other"],
16377
+ "stats": {
16378
+ "ie": {
16379
+ "5.5": "n",
16380
+ "6": "n",
16381
+ "7": "n",
16382
+ "8": "y",
16383
+ "9": "y",
16384
+ "10": "y",
16385
+ "11": "y"
16386
+ },
16387
+ "firefox": {
16388
+ "2": "a",
16389
+ "3": "y",
16390
+ "3.5": "y",
16391
+ "3.6": "y",
16392
+ "4": "y",
16393
+ "5": "y",
16394
+ "6": "y",
16395
+ "7": "y",
16396
+ "8": "y",
16397
+ "9": "y",
16398
+ "10": "y",
16399
+ "11": "y",
16400
+ "12": "y",
16401
+ "13": "y",
16402
+ "14": "y",
16403
+ "15": "y",
16404
+ "16": "y",
16405
+ "17": "y",
16406
+ "18": "y",
16407
+ "19": "y",
16408
+ "20": "y",
16409
+ "21": "y",
16410
+ "22": "y",
16411
+ "23": "y",
16412
+ "24": "y",
16413
+ "25": "y",
16414
+ "26": "y",
16415
+ "27": "y"
16416
+ },
16417
+ "chrome": {
16418
+ "4": "a",
16419
+ "5": "a",
16420
+ "6": "a",
16421
+ "7": "a",
16422
+ "8": "a",
16423
+ "9": "a",
16424
+ "10": "a",
16425
+ "11": "a",
16426
+ "12": "a",
16427
+ "13": "a",
16428
+ "14": "a",
16429
+ "15": "a",
16430
+ "16": "a",
16431
+ "17": "a",
16432
+ "18": "a",
16433
+ "19": "a",
16434
+ "20": "a",
16435
+ "21": "a",
16436
+ "22": "a",
16437
+ "23": "a",
16438
+ "24": "a",
16439
+ "25": "a",
16440
+ "26": "a",
16441
+ "27": "a",
16442
+ "28": "a",
16443
+ "29": "a",
16444
+ "30": "a",
16445
+ "31": "a",
16446
+ "32": "a"
16447
+ },
16448
+ "safari": {
16449
+ "3.1": "n",
16450
+ "3.2": "n",
16451
+ "4": "a",
16452
+ "5": "a",
16453
+ "5.1": "a",
16454
+ "6": "a",
16455
+ "6.1": "a",
16456
+ "7": "a"
16457
+ },
16458
+ "opera": {
16459
+ "9": "n",
16460
+ "9.5-9.6": "a",
16461
+ "10.0-10.1": "a",
16462
+ "10.5": "a",
16463
+ "10.6": "a",
16464
+ "11": "a",
16465
+ "11.1": "a",
16466
+ "11.5": "a",
16467
+ "11.6": "a",
16468
+ "12": "a",
16469
+ "12.1": "a",
16470
+ "15": "a",
16471
+ "16": "a",
16472
+ "17": "a",
16473
+ "18": "a"
16474
+ },
16475
+ "ios_saf": {
16476
+ "3.2": "a",
16477
+ "4.0-4.1": "a",
16478
+ "4.2-4.3": "a",
16479
+ "5.0-5.1": "a",
16480
+ "6.0-6.1": "a",
16481
+ "7.0": "a"
16482
+ },
16483
+ "op_mini": {
16484
+ "5.0-7.0": "a"
16485
+ },
16486
+ "android": {
16487
+ "2.1": "n",
16488
+ "2.2": "n",
16489
+ "2.3": "n",
16490
+ "3": "n",
16491
+ "4": "n",
16492
+ "4.1": "n",
16493
+ "4.2-4.3": "n",
16494
+ "4.4": "a"
16495
+ },
16496
+ "bb": {
16497
+ "7": "n",
16498
+ "10": "n"
16499
+ },
16500
+ "op_mob": {
16501
+ "10": "a",
16502
+ "11": "a",
16503
+ "11.1": "a",
16504
+ "11.5": "a",
16505
+ "12": "a",
16506
+ "12.1": "a",
16507
+ "0": "a"
16508
+ },
16509
+ "and_chr": {
16510
+ "0": "a"
16511
+ },
16512
+ "and_ff": {
16513
+ "0": "y"
16514
+ },
16515
+ "ie_mob": {
16516
+ "10": "y"
16517
+ }
16518
+ },
16519
+ "notes": "",
16520
+ "usage_perc_y": 40.05,
16521
+ "usage_perc_a": 48.6,
16522
+ "ucprefix": false,
16523
+ "parent": "",
16524
+ "keywords": "wai,aria"
16525
+ },
16526
+ "geolocation": {
16527
+ "title": "Geolocation",
16528
+ "description": "Method of informing a website of the user's geographical location",
16529
+ "spec": "http://www.w3.org/TR/geolocation-API/",
16530
+ "status": "cr",
16531
+ "links": [{
16532
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-geolocation",
16533
+ "title": "has.js test"
16534
+ }, {
16535
+ "url": "http://docs.webplatform.org/wiki/apis/geolocation",
16536
+ "title": "WebPlatform Docs"
16537
+ }, {
16538
+ "url": "http://html5demos.com/geo",
16539
+ "title": "Simple demo"
16540
+ }],
16541
+ "categories": ["JS API"],
16542
+ "stats": {
16543
+ "ie": {
16544
+ "5.5": "n",
16545
+ "6": "p",
16546
+ "7": "p",
16547
+ "8": "p",
16548
+ "9": "y",
16549
+ "10": "y",
16550
+ "11": "y"
16551
+ },
16552
+ "firefox": {
16553
+ "2": "p",
16554
+ "3": "p",
16555
+ "3.5": "y",
16556
+ "3.6": "y",
16557
+ "4": "y",
16558
+ "5": "y",
16559
+ "6": "y",
16560
+ "7": "y",
16561
+ "8": "y",
16562
+ "9": "y",
16563
+ "10": "y",
16564
+ "11": "y",
16565
+ "12": "y",
16566
+ "13": "y",
16567
+ "14": "y",
16568
+ "15": "y",
16569
+ "16": "y",
16570
+ "17": "y",
16571
+ "18": "y",
16572
+ "19": "y",
16573
+ "20": "y",
16574
+ "21": "y",
16575
+ "22": "y",
16576
+ "23": "y",
16577
+ "24": "y",
16578
+ "25": "y",
16579
+ "26": "y",
16580
+ "27": "y"
16581
+ },
16582
+ "chrome": {
16583
+ "4": "a",
16584
+ "5": "y",
16585
+ "6": "y",
16586
+ "7": "y",
16587
+ "8": "y",
16588
+ "9": "y",
16589
+ "10": "y",
16590
+ "11": "y",
16591
+ "12": "y",
16592
+ "13": "y",
16593
+ "14": "y",
16594
+ "15": "y",
16595
+ "16": "y",
16596
+ "17": "y",
16597
+ "18": "y",
16598
+ "19": "y",
16599
+ "20": "y",
16600
+ "21": "y",
16601
+ "22": "y",
16602
+ "23": "y",
16603
+ "24": "y",
16604
+ "25": "y",
16605
+ "26": "y",
16606
+ "27": "y",
16607
+ "28": "y",
16608
+ "29": "y",
16609
+ "30": "y",
16610
+ "31": "y",
16611
+ "32": "y"
16612
+ },
16613
+ "safari": {
16614
+ "3.1": "p",
16615
+ "3.2": "p",
16616
+ "4": "p",
16617
+ "5": "y",
16618
+ "5.1": "y",
16619
+ "6": "y",
16620
+ "6.1": "y",
16621
+ "7": "y"
16622
+ },
16623
+ "opera": {
16624
+ "9": "n",
16625
+ "9.5-9.6": "n",
16626
+ "10.0-10.1": "p",
16627
+ "10.5": "p",
16628
+ "10.6": "y",
16629
+ "11": "y",
16630
+ "11.1": "y",
16631
+ "11.5": "y",
16632
+ "11.6": "y",
16633
+ "12": "y",
16634
+ "12.1": "y",
16635
+ "15": "n",
16636
+ "16": "y",
16637
+ "17": "y",
16638
+ "18": "y"
16639
+ },
16640
+ "ios_saf": {
16641
+ "3.2": "y",
16642
+ "4.0-4.1": "y",
16643
+ "4.2-4.3": "y",
16644
+ "5.0-5.1": "y",
16645
+ "6.0-6.1": "y",
16646
+ "7.0": "y"
16647
+ },
16648
+ "op_mini": {
16649
+ "5.0-7.0": "n"
16650
+ },
16651
+ "android": {
16652
+ "2.1": "y",
16653
+ "2.2": "y",
16654
+ "2.3": "y",
16655
+ "3": "y",
16656
+ "4": "y",
16657
+ "4.1": "y",
16658
+ "4.2-4.3": "y",
16659
+ "4.4": "y"
16660
+ },
16661
+ "bb": {
16662
+ "7": "y",
16663
+ "10": "y"
16664
+ },
16665
+ "op_mob": {
16666
+ "10": "p",
16667
+ "11": "y",
16668
+ "11.1": "y",
16669
+ "11.5": "y",
16670
+ "12": "y",
16671
+ "12.1": "y",
16672
+ "0": "y"
16673
+ },
16674
+ "and_chr": {
16675
+ "0": "y"
16676
+ },
16677
+ "and_ff": {
16678
+ "0": "y"
16679
+ },
16680
+ "ie_mob": {
16681
+ "10": "y"
16682
+ }
16683
+ },
16684
+ "notes": "",
16685
+ "usage_perc_y": 80.65,
16686
+ "usage_perc_a": 0.02,
16687
+ "ucprefix": false,
16688
+ "parent": "",
16689
+ "keywords": ""
16690
+ },
16691
+ "flexbox": {
16692
+ "title": "Flexible Box Layout Module",
16693
+ "description": "Method of positioning elements in horizontal or vertical stacks.",
16694
+ "spec": "http://www.w3.org/TR/css3-flexbox/",
16695
+ "status": "cr",
16696
+ "links": [{
16697
+ "url": "http://css-tricks.com/snippets/css/a-guide-to-flexbox/",
16698
+ "title": "A Complete Guide to Flexbox"
16699
+ }, {
16700
+ "url": "http://bennettfeely.com/flexplorer/",
16701
+ "title": "Flexbox CSS generator"
16702
+ }, {
16703
+ "url": "http://www.adobe.com/devnet/html5/articles/working-with-flexbox-the-new-spec.html",
16704
+ "title": "Article on using the latest spec"
16705
+ }, {
16706
+ "url": "http://philipwalton.github.io/solved-by-flexbox/",
16707
+ "title": "Examples on how to solve common layout problems with flexbox"
16708
+ }, {
16709
+ "url": "http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/",
16710
+ "title": "Tutorial on cross-browser support"
16711
+ }],
16712
+ "categories": ["CSS3"],
16713
+ "stats": {
16714
+ "ie": {
16715
+ "5.5": "n",
16716
+ "6": "n",
16717
+ "7": "n",
16718
+ "8": "n",
16719
+ "9": "n",
16720
+ "10": "a x #2",
16721
+ "11": "y"
16722
+ },
16723
+ "firefox": {
16724
+ "2": "a x #1",
16725
+ "3": "a x #1",
16726
+ "3.5": "a x #1",
16727
+ "3.6": "a x #1",
16728
+ "4": "a x #1",
16729
+ "5": "a x #1",
16730
+ "6": "a x #1",
16731
+ "7": "a x #1",
16732
+ "8": "a x #1",
16733
+ "9": "a x #1",
16734
+ "10": "a x #1",
16735
+ "11": "a x #1",
16736
+ "12": "a x #1",
16737
+ "13": "a x #1",
16738
+ "14": "a x #1",
16739
+ "15": "a x #1",
16740
+ "16": "a x #1",
16741
+ "17": "a x #1",
16742
+ "18": "a x #1",
16743
+ "19": "a x #1",
16744
+ "20": "a x #1",
16745
+ "21": "a x #1",
16746
+ "22": "a #3",
16747
+ "23": "a #3",
16748
+ "24": "a #3",
16749
+ "25": "a #3",
16750
+ "26": "a #3",
16751
+ "27": "a #3"
16752
+ },
16753
+ "chrome": {
16754
+ "4": "a x #1",
16755
+ "5": "a x #1",
16756
+ "6": "a x #1",
16757
+ "7": "a x #1",
16758
+ "8": "a x #1",
16759
+ "9": "a x #1",
16760
+ "10": "a x #1",
16761
+ "11": "a x #1",
16762
+ "12": "a x #1",
16763
+ "13": "a x #1",
16764
+ "14": "a x #1",
16765
+ "15": "a x #1",
16766
+ "16": "a x #1",
16767
+ "17": "a x #1",
16768
+ "18": "a x #1",
16769
+ "19": "a x #1",
16770
+ "20": "a x #1",
16771
+ "21": "y x",
16772
+ "22": "y x",
16773
+ "23": "y x",
16774
+ "24": "y x",
16775
+ "25": "y x",
16776
+ "26": "y x",
16777
+ "27": "y x",
16778
+ "28": "y x",
16779
+ "29": "y",
16780
+ "30": "y",
16781
+ "31": "y",
16782
+ "32": "y"
16783
+ },
16784
+ "safari": {
16785
+ "3.1": "a x #1",
16786
+ "3.2": "a x #1",
16787
+ "4": "a x #1",
16788
+ "5": "a x #1",
16789
+ "5.1": "a x #1",
16790
+ "6": "a x #1",
16791
+ "6.1": "y x",
16792
+ "7": "y x"
16793
+ },
16794
+ "opera": {
16795
+ "9": "n",
16796
+ "9.5-9.6": "n",
16797
+ "10.0-10.1": "n",
16798
+ "10.5": "n",
16799
+ "10.6": "n",
16800
+ "11": "n",
16801
+ "11.1": "n",
16802
+ "11.5": "n",
16803
+ "11.6": "n",
16804
+ "12": "n",
16805
+ "12.1": "y",
16806
+ "15": "y x",
16807
+ "16": "y x",
16808
+ "17": "y",
16809
+ "18": "y"
16810
+ },
16811
+ "ios_saf": {
16812
+ "3.2": "a x #1",
16813
+ "4.0-4.1": "a x #1",
16814
+ "4.2-4.3": "a x #1",
16815
+ "5.0-5.1": "a x #1",
16816
+ "6.0-6.1": "a x #1",
16817
+ "7.0": "y x"
16818
+ },
16819
+ "op_mini": {
16820
+ "5.0-7.0": "n"
16821
+ },
16822
+ "android": {
16823
+ "2.1": "a x #1",
16824
+ "2.2": "a x #1",
16825
+ "2.3": "a x #1",
16826
+ "3": "a x #1",
16827
+ "4": "a x #1",
16828
+ "4.1": "a x #1",
16829
+ "4.2-4.3": "a x #1",
16830
+ "4.4": "y"
16831
+ },
16832
+ "bb": {
16833
+ "7": "a x #1",
16834
+ "10": "y x"
16835
+ },
16836
+ "op_mob": {
16837
+ "10": "n",
16838
+ "11": "n",
16839
+ "11.1": "n",
16840
+ "11.5": "n",
16841
+ "12": "n",
16842
+ "12.1": "y",
16843
+ "0": "y"
16844
+ },
16845
+ "and_chr": {
16846
+ "0": "y"
16847
+ },
16848
+ "and_ff": {
16849
+ "0": "a x #1"
16850
+ },
16851
+ "ie_mob": {
16852
+ "10": "a x #2"
16853
+ }
16854
+ },
16855
+ "notes": "Most partial support refers to supporting an <a href=\"http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/\">older version</a> of the specification or an <a href=\"http://www.w3.org/TR/2012/WD-css3-flexbox-20120322/\">older syntax</a>. For Firefox 21+ it refers to lack of flex-wrap & flex-flow support.",
16856
+ "usage_perc_y": 37.88,
16857
+ "usage_perc_a": 37.66,
16858
+ "ucprefix": false,
16859
+ "parent": "",
16860
+ "keywords": "flex"
16861
+ },
16862
+ "webgl": {
16863
+ "title": "WebGL - 3D Canvas graphics",
16864
+ "description": "Method of generating dynamic 3D graphics using JavaScript, accelerated through hardware",
16865
+ "spec": "https://www.khronos.org/registry/webgl/specs/1.0/",
16866
+ "status": "other",
16867
+ "links": [{
16868
+ "url": "http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation",
16869
+ "title": "Instructions on enabling WebGL"
16870
+ }, {
16871
+ "url": "http://webkit.org/blog/603/webgl-now-available-in-webkit-nightlies/",
16872
+ "title": "Webkit blog post"
16873
+ }, {
16874
+ "url": "http://www.khronos.org/webgl/wiki/Tutorial",
16875
+ "title": "Tutorial"
16876
+ }, {
16877
+ "url": "http://hacks.mozilla.org/2009/12/webgl-draft-released-today/",
16878
+ "title": "Firefox blog post"
16879
+ }, {
16880
+ "url": "http://iewebgl.com/",
16881
+ "title": "Polyfill for IE"
16882
+ }],
16883
+ "categories": ["Canvas"],
16884
+ "stats": {
16885
+ "ie": {
16886
+ "5.5": "n",
16887
+ "6": "p",
16888
+ "7": "p",
16889
+ "8": "p",
16890
+ "9": "p",
16891
+ "10": "p",
16892
+ "11": "y"
16893
+ },
16894
+ "firefox": {
16895
+ "2": "n",
16896
+ "3": "n",
16897
+ "3.5": "n",
16898
+ "3.6": "n",
16899
+ "4": "a",
16900
+ "5": "a",
16901
+ "6": "a",
16902
+ "7": "a",
16903
+ "8": "a",
16904
+ "9": "a",
16905
+ "10": "a",
16906
+ "11": "a",
16907
+ "12": "a",
16908
+ "13": "a",
16909
+ "14": "a",
16910
+ "15": "a",
16911
+ "16": "a",
16912
+ "17": "a",
16913
+ "18": "a",
16914
+ "19": "a",
16915
+ "20": "a",
16916
+ "21": "a",
16917
+ "22": "a",
16918
+ "23": "a",
16919
+ "24": "a",
16920
+ "25": "a",
16921
+ "26": "a",
16922
+ "27": "a"
16923
+ },
16924
+ "chrome": {
16925
+ "4": "n",
16926
+ "5": "n",
16927
+ "6": "n",
16928
+ "7": "n",
16929
+ "8": "a",
16930
+ "9": "a",
16931
+ "10": "a",
16932
+ "11": "a",
16933
+ "12": "a",
16934
+ "13": "a",
16935
+ "14": "a",
16936
+ "15": "a",
16937
+ "16": "a",
16938
+ "17": "a",
16939
+ "18": "y",
16940
+ "19": "y",
16941
+ "20": "y",
16942
+ "21": "y",
16943
+ "22": "y",
16944
+ "23": "y",
16945
+ "24": "y",
16946
+ "25": "y",
16947
+ "26": "y",
16948
+ "27": "y",
16949
+ "28": "y",
16950
+ "29": "y",
16951
+ "30": "y",
16952
+ "31": "y",
16953
+ "32": "y"
16954
+ },
16955
+ "safari": {
16956
+ "3.1": "n",
16957
+ "3.2": "n",
16958
+ "4": "n",
16959
+ "5": "n",
16960
+ "5.1": "a",
16961
+ "6": "a",
16962
+ "6.1": "a",
16963
+ "7": "a"
16964
+ },
16965
+ "opera": {
16966
+ "9": "n",
16967
+ "9.5-9.6": "n",
16968
+ "10.0-10.1": "n",
16969
+ "10.5": "n",
16970
+ "10.6": "n",
16971
+ "11": "n",
16972
+ "11.1": "n",
16973
+ "11.5": "n",
16974
+ "11.6": "n",
16975
+ "12": "a",
16976
+ "12.1": "a",
16977
+ "15": "y",
16978
+ "16": "y",
16979
+ "17": "y",
16980
+ "18": "y"
16981
+ },
16982
+ "ios_saf": {
16983
+ "3.2": "n",
16984
+ "4.0-4.1": "n",
16985
+ "4.2-4.3": "n",
16986
+ "5.0-5.1": "n",
16987
+ "6.0-6.1": "n",
16988
+ "7.0": "n"
16989
+ },
16990
+ "op_mini": {
16991
+ "5.0-7.0": "n"
16992
+ },
16993
+ "android": {
16994
+ "2.1": "n",
16995
+ "2.2": "n",
16996
+ "2.3": "n",
16997
+ "3": "n",
16998
+ "4": "n",
16999
+ "4.1": "n",
17000
+ "4.2-4.3": "n",
17001
+ "4.4": "n"
17002
+ },
17003
+ "bb": {
17004
+ "7": "n",
17005
+ "10": "y"
17006
+ },
17007
+ "op_mob": {
17008
+ "10": "n",
17009
+ "11": "n",
17010
+ "11.1": "n",
17011
+ "11.5": "n",
17012
+ "12": "a",
17013
+ "12.1": "a",
17014
+ "0": "y"
17015
+ },
17016
+ "and_chr": {
17017
+ "0": "n"
17018
+ },
17019
+ "and_ff": {
17020
+ "0": "y"
17021
+ },
17022
+ "ie_mob": {
17023
+ "10": "p"
17024
+ }
17025
+ },
17026
+ "notes": "Support listed as \"partial\" refers to the fact that not all users with these browsers have WebGL access. This is due to the additional requirement for users to have <a href=\"http://www.khronos.org/webgl/wiki/BlacklistsAndWhitelists\">up to date video drivers</a>. This problem was <a href=\"http://blog.chromium.org/2012/02/gpu-accelerating-2d-canvas-and-enabling.html\">solved in Chrome</a> as of version 18.\r\n\r\nNote that WebGL is part of the <a href=\"http://www.khronos.org/webgl/\">Khronos Group</a>, not the W3C. On Chrome for Android, WebGL is disabled by default, but can be enabled by enabling the \"Enable WebGL\" flag under chrome://flags",
17027
+ "usage_perc_y": 33.4,
17028
+ "usage_perc_a": 19.68,
17029
+ "ucprefix": false,
17030
+ "parent": "canvas",
17031
+ "keywords": "web gl"
17032
+ },
17033
+ "fileapi": {
17034
+ "title": "File API",
17035
+ "description": "Method of manipulating file objects in web applications client-side, as well as programmatically selecting them and accessing their data.",
17036
+ "spec": "http://www.w3.org/TR/FileAPI/",
17037
+ "status": "wd",
17038
+ "links": [{
17039
+ "url": "https://developer.mozilla.org/en/Using_files_from_web_applications",
17040
+ "title": "MDN article"
17041
+ }, {
17042
+ "url": "http://docs.webplatform.org/wiki/apis/file",
17043
+ "title": "WebPlatform Docs"
17044
+ }],
17045
+ "categories": ["JS API"],
17046
+ "stats": {
17047
+ "ie": {
17048
+ "5.5": "n",
17049
+ "6": "n",
17050
+ "7": "n",
17051
+ "8": "n",
17052
+ "9": "n",
17053
+ "10": "y",
17054
+ "11": "y"
17055
+ },
17056
+ "firefox": {
17057
+ "2": "n",
17058
+ "3": "n",
17059
+ "3.5": "n",
17060
+ "3.6": "y",
17061
+ "4": "y",
17062
+ "5": "y",
17063
+ "6": "y",
17064
+ "7": "y",
17065
+ "8": "y",
17066
+ "9": "y",
17067
+ "10": "y",
17068
+ "11": "y",
17069
+ "12": "y",
17070
+ "13": "y",
17071
+ "14": "y",
17072
+ "15": "y",
17073
+ "16": "y",
17074
+ "17": "y",
17075
+ "18": "y",
17076
+ "19": "y",
17077
+ "20": "y",
17078
+ "21": "y",
17079
+ "22": "y",
17080
+ "23": "y",
17081
+ "24": "y",
17082
+ "25": "y",
17083
+ "26": "y",
17084
+ "27": "y"
17085
+ },
17086
+ "chrome": {
17087
+ "4": "n",
17088
+ "5": "n",
17089
+ "6": "a",
17090
+ "7": "a",
17091
+ "8": "a",
17092
+ "9": "a",
17093
+ "10": "a",
17094
+ "11": "a",
17095
+ "12": "a",
17096
+ "13": "y",
17097
+ "14": "y",
17098
+ "15": "y",
17099
+ "16": "y",
17100
+ "17": "y",
17101
+ "18": "y",
17102
+ "19": "y",
17103
+ "20": "y",
17104
+ "21": "y",
17105
+ "22": "y",
17106
+ "23": "y",
17107
+ "24": "y",
17108
+ "25": "y",
17109
+ "26": "y",
17110
+ "27": "y",
17111
+ "28": "y",
17112
+ "29": "y",
17113
+ "30": "y",
17114
+ "31": "y",
17115
+ "32": "y"
17116
+ },
17117
+ "safari": {
17118
+ "3.1": "n",
17119
+ "3.2": "n",
17120
+ "4": "n",
17121
+ "5": "n",
17122
+ "5.1": "a",
17123
+ "6": "y",
17124
+ "6.1": "y",
17125
+ "7": "y"
17126
+ },
17127
+ "opera": {
17128
+ "9": "n",
17129
+ "9.5-9.6": "n",
17130
+ "10.0-10.1": "n",
17131
+ "10.5": "n",
17132
+ "10.6": "n",
17133
+ "11": "n",
17134
+ "11.1": "y",
17135
+ "11.5": "y",
17136
+ "11.6": "y",
17137
+ "12": "y",
17138
+ "12.1": "y",
17139
+ "15": "y",
17140
+ "16": "y",
17141
+ "17": "y",
17142
+ "18": "y"
17143
+ },
17144
+ "ios_saf": {
17145
+ "3.2": "n",
17146
+ "4.0-4.1": "n",
17147
+ "4.2-4.3": "n",
17148
+ "5.0-5.1": "n",
17149
+ "6.0-6.1": "y",
17150
+ "7.0": "y"
17151
+ },
17152
+ "op_mini": {
17153
+ "5.0-7.0": "n"
17154
+ },
17155
+ "android": {
17156
+ "2.1": "n",
17157
+ "2.2": "n",
17158
+ "2.3": "n",
17159
+ "3": "a",
17160
+ "4": "a",
17161
+ "4.1": "a",
17162
+ "4.2-4.3": "a",
17163
+ "4.4": "y"
17164
+ },
17165
+ "bb": {
17166
+ "7": "a",
17167
+ "10": "y"
17168
+ },
17169
+ "op_mob": {
17170
+ "10": "n",
17171
+ "11": "n",
17172
+ "11.1": "y",
17173
+ "11.5": "y",
17174
+ "12": "y",
17175
+ "12.1": "y",
17176
+ "0": "y"
17177
+ },
17178
+ "and_chr": {
17179
+ "0": "y"
17180
+ },
17181
+ "and_ff": {
17182
+ "0": "y"
17183
+ },
17184
+ "ie_mob": {
17185
+ "10": "n"
17186
+ }
17187
+ },
17188
+ "notes": "Partial support in older Safari refers to lacking FileReader support. ",
17189
+ "usage_perc_y": 67.73,
17190
+ "usage_perc_a": 5.38,
17191
+ "ucprefix": false,
17192
+ "parent": "",
17193
+ "keywords": "FileReader"
17194
+ },
17195
+ "shadowdom": {
17196
+ "title": "Shadow DOM",
17197
+ "description": "Method of establishing and maintaining functional boundaries between DOM trees and how these trees interact with each other within a document, thus enabling better functional encapsulation within the DOM.",
17198
+ "spec": "http://www.w3.org/TR/shadow-dom/",
17199
+ "status": "wd",
17200
+ "links": [{
17201
+ "url": "http://www.html5rocks.com/tutorials/webcomponents/shadowdom/",
17202
+ "title": "HTML5Rocks - Shadow DOM 101 article"
17203
+ }, {
17204
+ "url": "http://html5-demos.appspot.com/static/shadowdom-visualizer/index.html",
17205
+ "title": "Shadow DOM Visualizer"
17206
+ }],
17207
+ "categories": ["DOM", "HTML5"],
17208
+ "stats": {
17209
+ "ie": {
17210
+ "5.5": "n",
17211
+ "6": "n",
17212
+ "7": "n",
17213
+ "8": "n",
17214
+ "9": "n",
17215
+ "10": "n",
17216
+ "11": "n"
17217
+ },
17218
+ "firefox": {
17219
+ "2": "n",
17220
+ "3": "n",
17221
+ "3.5": "n",
17222
+ "3.6": "n",
17223
+ "4": "n",
17224
+ "5": "n",
17225
+ "6": "n",
17226
+ "7": "n",
17227
+ "8": "n",
17228
+ "9": "n",
17229
+ "10": "n",
17230
+ "11": "n",
17231
+ "12": "n",
17232
+ "13": "n",
17233
+ "14": "n",
17234
+ "15": "n",
17235
+ "16": "n",
17236
+ "17": "n",
17237
+ "18": "n",
17238
+ "19": "n",
17239
+ "20": "n",
17240
+ "21": "n",
17241
+ "22": "n",
17242
+ "23": "n",
17243
+ "24": "n",
17244
+ "25": "n",
17245
+ "26": "n",
17246
+ "27": "n"
17247
+ },
17248
+ "chrome": {
17249
+ "4": "n",
17250
+ "5": "n",
17251
+ "6": "n",
17252
+ "7": "n",
17253
+ "8": "n",
17254
+ "9": "n",
17255
+ "10": "n",
17256
+ "11": "n",
17257
+ "12": "n",
17258
+ "13": "n",
17259
+ "14": "n",
17260
+ "15": "n",
17261
+ "16": "n",
17262
+ "17": "n",
17263
+ "18": "n",
17264
+ "19": "n",
17265
+ "20": "n",
17266
+ "21": "n",
17267
+ "22": "n",
17268
+ "23": "n",
17269
+ "24": "n",
17270
+ "25": "y x",
17271
+ "26": "y",
17272
+ "27": "y",
17273
+ "28": "y",
17274
+ "29": "y",
17275
+ "30": "y",
17276
+ "31": "y",
17277
+ "32": "y"
17278
+ },
17279
+ "safari": {
17280
+ "3.1": "n",
17281
+ "3.2": "n",
17282
+ "4": "n",
17283
+ "5": "n",
17284
+ "5.1": "n",
17285
+ "6": "n",
17286
+ "6.1": "u",
17287
+ "7": "u"
17288
+ },
17289
+ "opera": {
17290
+ "9": "n",
17291
+ "9.5-9.6": "n",
17292
+ "10.0-10.1": "n",
17293
+ "10.5": "n",
17294
+ "10.6": "n",
17295
+ "11": "n",
17296
+ "11.1": "n",
17297
+ "11.5": "n",
17298
+ "11.6": "n",
17299
+ "12": "n",
17300
+ "12.1": "n",
17301
+ "15": "y",
17302
+ "16": "y",
17303
+ "17": "y",
17304
+ "18": "y"
17305
+ },
17306
+ "ios_saf": {
17307
+ "3.2": "n",
17308
+ "4.0-4.1": "n",
17309
+ "4.2-4.3": "n",
17310
+ "5.0-5.1": "n",
17311
+ "6.0-6.1": "n",
17312
+ "7.0": "n"
17313
+ },
17314
+ "op_mini": {
17315
+ "5.0-7.0": "n"
17316
+ },
17317
+ "android": {
17318
+ "2.1": "n",
17319
+ "2.2": "n",
17320
+ "2.3": "n",
17321
+ "3": "n",
17322
+ "4": "n",
17323
+ "4.1": "n",
17324
+ "4.2-4.3": "n",
17325
+ "4.4": "y x"
17326
+ },
17327
+ "bb": {
17328
+ "7": "n",
17329
+ "10": "n"
17330
+ },
17331
+ "op_mob": {
17332
+ "10": "n",
17333
+ "11": "n",
17334
+ "11.1": "n",
17335
+ "11.5": "n",
17336
+ "12": "n",
17337
+ "12.1": "n",
17338
+ "0": "y x"
17339
+ },
17340
+ "and_chr": {
17341
+ "0": "y x"
17342
+ },
17343
+ "and_ff": {
17344
+ "0": "n"
17345
+ },
17346
+ "ie_mob": {
17347
+ "10": "n"
17348
+ }
17349
+ },
17350
+ "notes": "",
17351
+ "usage_perc_y": 33.29,
17352
+ "usage_perc_a": 0,
17353
+ "ucprefix": false,
17354
+ "parent": "",
17355
+ "keywords": "web components"
17356
+ },
17357
+ "websockets": {
17358
+ "title": "Web Sockets",
17359
+ "description": "Bidirectional communication technology for web apps",
17360
+ "spec": "http://www.w3.org/TR/websockets/",
17361
+ "status": "cr",
17362
+ "links": [{
17363
+ "url": "http://docs.webplatform.org/wiki/apis/websocket",
17364
+ "title": "WebPlatform Docs"
17365
+ }, {
17366
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-websockets",
17367
+ "title": "has.js test"
17368
+ }, {
17369
+ "url": "http://websocket.org/aboutwebsocket.html",
17370
+ "title": "WebSockets information"
17371
+ }, {
17372
+ "url": "http://en.wikipedia.org/wiki/WebSocket",
17373
+ "title": "Wikipedia"
17374
+ }, {
17375
+ "url": "http://updates.html5rocks.com/2011/08/What-s-different-in-the-new-WebSocket-protocol",
17376
+ "title": "Details on newer protocol"
17377
+ }],
17378
+ "categories": ["JS API"],
17379
+ "stats": {
17380
+ "ie": {
17381
+ "5.5": "n",
17382
+ "6": "n",
17383
+ "7": "n",
17384
+ "8": "n",
17385
+ "9": "n",
17386
+ "10": "y",
17387
+ "11": "y"
17388
+ },
17389
+ "firefox": {
17390
+ "2": "n",
17391
+ "3": "n",
17392
+ "3.5": "n",
17393
+ "3.6": "n",
17394
+ "4": "a",
17395
+ "5": "a",
17396
+ "6": "y x",
17397
+ "7": "y x",
17398
+ "8": "y x",
17399
+ "9": "y x",
17400
+ "10": "y x",
17401
+ "11": "y",
17402
+ "12": "y",
17403
+ "13": "y",
17404
+ "14": "y",
17405
+ "15": "y",
17406
+ "16": "y",
17407
+ "17": "y",
17408
+ "18": "y",
17409
+ "19": "y",
17410
+ "20": "y",
17411
+ "21": "y",
17412
+ "22": "y",
17413
+ "23": "y",
17414
+ "24": "y",
17415
+ "25": "y",
17416
+ "26": "y",
17417
+ "27": "y"
17418
+ },
17419
+ "chrome": {
17420
+ "4": "a",
17421
+ "5": "a",
17422
+ "6": "a",
17423
+ "7": "a",
17424
+ "8": "a",
17425
+ "9": "a",
17426
+ "10": "a",
17427
+ "11": "a",
17428
+ "12": "a",
17429
+ "13": "a",
17430
+ "14": "y",
17431
+ "15": "y",
17432
+ "16": "y",
17433
+ "17": "y",
17434
+ "18": "y",
17435
+ "19": "y",
17436
+ "20": "y",
17437
+ "21": "y",
17438
+ "22": "y",
17439
+ "23": "y",
17440
+ "24": "y",
17441
+ "25": "y",
17442
+ "26": "y",
17443
+ "27": "y",
17444
+ "28": "y",
17445
+ "29": "y",
17446
+ "30": "y",
17447
+ "31": "y",
17448
+ "32": "y"
17449
+ },
17450
+ "safari": {
17451
+ "3.1": "n",
17452
+ "3.2": "n",
17453
+ "4": "n",
17454
+ "5": "a",
17455
+ "5.1": "a",
17456
+ "6": "y",
17457
+ "6.1": "y",
17458
+ "7": "y"
17459
+ },
17460
+ "opera": {
17461
+ "9": "n",
17462
+ "9.5-9.6": "n",
17463
+ "10.0-10.1": "n",
17464
+ "10.5": "n",
17465
+ "10.6": "n",
17466
+ "11": "a",
17467
+ "11.1": "a",
17468
+ "11.5": "a",
17469
+ "11.6": "a",
17470
+ "12": "a",
17471
+ "12.1": "y",
17472
+ "15": "y",
17473
+ "16": "y",
17474
+ "17": "y",
17475
+ "18": "y"
17476
+ },
17477
+ "ios_saf": {
17478
+ "3.2": "n",
17479
+ "4.0-4.1": "n",
17480
+ "4.2-4.3": "a",
17481
+ "5.0-5.1": "a",
17482
+ "6.0-6.1": "y",
17483
+ "7.0": "y"
17484
+ },
17485
+ "op_mini": {
17486
+ "5.0-7.0": "n"
17487
+ },
17488
+ "android": {
17489
+ "2.1": "n",
17490
+ "2.2": "n",
17491
+ "2.3": "n",
17492
+ "3": "n",
17493
+ "4": "n",
17494
+ "4.1": "n",
17495
+ "4.2-4.3": "n",
17496
+ "4.4": "y"
17497
+ },
17498
+ "bb": {
17499
+ "7": "y",
17500
+ "10": "y"
17501
+ },
17502
+ "op_mob": {
17503
+ "10": "n",
17504
+ "11": "a",
17505
+ "11.1": "a",
17506
+ "11.5": "a",
17507
+ "12": "a",
17508
+ "12.1": "y",
17509
+ "0": "y"
17510
+ },
17511
+ "and_chr": {
17512
+ "0": "y"
17513
+ },
17514
+ "and_ff": {
17515
+ "0": "y"
17516
+ },
17517
+ "ie_mob": {
17518
+ "10": "y"
17519
+ }
17520
+ },
17521
+ "notes": "Partial support refers to the websockets implementation using an older version of the protocol and/or the implementation being disabled by default (due to security issues with the older protocol).",
17522
+ "usage_perc_y": 67.46,
17523
+ "usage_perc_a": 2.62,
17524
+ "ucprefix": true,
17525
+ "parent": "",
17526
+ "keywords": ""
17527
+ },
17528
+ "script-async": {
17529
+ "title": "async attribute for external scripts",
17530
+ "description": "The boolean async attribute on script elements allows the external JavaScript file to run when it's available, without delaying page load first.",
17531
+ "spec": "http://www.w3.org/TR/html5/scripting-1.html#attr-script-async",
17532
+ "status": "cr",
17533
+ "links": [{
17534
+ "url": "https://developer.mozilla.org/en/HTML/Element/script#Attributes",
17535
+ "title": "MDN article"
17536
+ }, {
17537
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/script.js#script-async",
17538
+ "title": "has.js test"
17539
+ }, {
17540
+ "url": "http://ie.microsoft.com/testdrive/Performance/AsyncScripts/Default.html",
17541
+ "title": "Demo"
17542
+ }],
17543
+ "categories": ["HTML5", "DOM"],
17544
+ "stats": {
17545
+ "ie": {
17546
+ "5.5": "n",
17547
+ "6": "n",
17548
+ "7": "n",
17549
+ "8": "n",
17550
+ "9": "n",
17551
+ "10": "y",
17552
+ "11": "y"
17553
+ },
17554
+ "firefox": {
17555
+ "2": "n",
17556
+ "3": "n",
17557
+ "3.5": "n",
17558
+ "3.6": "y",
17559
+ "4": "y",
17560
+ "5": "y",
17561
+ "6": "y",
17562
+ "7": "y",
17563
+ "8": "y",
17564
+ "9": "y",
17565
+ "10": "y",
17566
+ "11": "y",
17567
+ "12": "y",
17568
+ "13": "y",
17569
+ "14": "y",
17570
+ "15": "y",
17571
+ "16": "y",
17572
+ "17": "y",
17573
+ "18": "y",
17574
+ "19": "y",
17575
+ "20": "y",
17576
+ "21": "y",
17577
+ "22": "y",
17578
+ "23": "y",
17579
+ "24": "y",
17580
+ "25": "y",
17581
+ "26": "y",
17582
+ "27": "y"
17583
+ },
17584
+ "chrome": {
17585
+ "4": "n",
17586
+ "5": "n",
17587
+ "6": "n",
17588
+ "7": "n",
17589
+ "8": "y",
17590
+ "9": "y",
17591
+ "10": "y",
17592
+ "11": "y",
17593
+ "12": "y",
17594
+ "13": "y",
17595
+ "14": "y",
17596
+ "15": "y",
17597
+ "16": "y",
17598
+ "17": "y",
17599
+ "18": "y",
17600
+ "19": "y",
17601
+ "20": "y",
17602
+ "21": "y",
17603
+ "22": "y",
17604
+ "23": "y",
17605
+ "24": "y",
17606
+ "25": "y",
17607
+ "26": "y",
17608
+ "27": "y",
17609
+ "28": "y",
17610
+ "29": "y",
17611
+ "30": "y",
17612
+ "31": "y",
17613
+ "32": "y"
17614
+ },
17615
+ "safari": {
17616
+ "3.1": "n",
17617
+ "3.2": "n",
17618
+ "4": "n",
17619
+ "5": "a",
17620
+ "5.1": "y",
17621
+ "6": "y",
17622
+ "6.1": "y",
17623
+ "7": "y"
17624
+ },
17625
+ "opera": {
17626
+ "9": "n",
17627
+ "9.5-9.6": "n",
17628
+ "10.0-10.1": "n",
17629
+ "10.5": "n",
17630
+ "10.6": "n",
17631
+ "11": "n",
17632
+ "11.1": "n",
17633
+ "11.5": "n",
17634
+ "11.6": "n",
17635
+ "12": "n",
17636
+ "12.1": "n",
17637
+ "15": "y",
17638
+ "16": "y",
17639
+ "17": "y",
17640
+ "18": "y"
17641
+ },
17642
+ "ios_saf": {
17643
+ "3.2": "n",
17644
+ "4.0-4.1": "n",
17645
+ "4.2-4.3": "n",
17646
+ "5.0-5.1": "y",
17647
+ "6.0-6.1": "y",
17648
+ "7.0": "y"
17649
+ },
17650
+ "op_mini": {
17651
+ "5.0-7.0": "n"
17652
+ },
17653
+ "android": {
17654
+ "2.1": "n",
17655
+ "2.2": "n",
17656
+ "2.3": "n",
17657
+ "3": "y",
17658
+ "4": "y",
17659
+ "4.1": "y",
17660
+ "4.2-4.3": "y",
17661
+ "4.4": "y"
17662
+ },
17663
+ "bb": {
17664
+ "7": "y",
17665
+ "10": "y"
17666
+ },
17667
+ "op_mob": {
17668
+ "10": "n",
17669
+ "11": "n",
17670
+ "11.1": "n",
17671
+ "11.5": "n",
17672
+ "12": "n",
17673
+ "12.1": "n",
17674
+ "0": "y"
17675
+ },
17676
+ "and_chr": {
17677
+ "0": "y"
17678
+ },
17679
+ "and_ff": {
17680
+ "0": "y"
17681
+ },
17682
+ "ie_mob": {
17683
+ "10": "y"
17684
+ }
17685
+ },
17686
+ "notes": "Using script.async = false; to maintain execution order for dynamically-added scripts isn't supported in Safari 5.0",
17687
+ "usage_perc_y": 72.82,
17688
+ "usage_perc_a": 0.31,
17689
+ "ucprefix": false,
17690
+ "parent": "",
17691
+ "keywords": ""
17692
+ },
17693
+ "cors": {
17694
+ "title": "Cross-Origin Resource Sharing",
17695
+ "description": "Method of performing XMLHttpRequests across domains",
17696
+ "spec": "http://www.w3.org/TR/cors/",
17697
+ "status": "cr",
17698
+ "links": [{
17699
+ "url": "http://saltybeagle.com/2009/09/cross-origin-resource-sharing-demo/",
17700
+ "title": "Demo and script with cross-browser support"
17701
+ }, {
17702
+ "url": "http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/",
17703
+ "title": "Mozilla Hacks blog post"
17704
+ }, {
17705
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-cors-xhr",
17706
+ "title": "has.js test"
17707
+ }, {
17708
+ "url": "http://msdn.microsoft.com/en-us/library/cc288060(VS.85).aspx",
17709
+ "title": "Alternative implementation by IE8"
17710
+ }, {
17711
+ "url": "http://dev.opera.com/articles/view/dom-access-control-using-cross-origin-resource-sharing/",
17712
+ "title": "DOM access using CORS"
17713
+ }],
17714
+ "categories": ["JS API"],
17715
+ "stats": {
17716
+ "ie": {
17717
+ "5.5": "n",
17718
+ "6": "n",
17719
+ "7": "n",
17720
+ "8": "a",
17721
+ "9": "a",
17722
+ "10": "y",
17723
+ "11": "y"
17724
+ },
17725
+ "firefox": {
17726
+ "2": "n",
17727
+ "3": "n",
17728
+ "3.5": "y",
17729
+ "3.6": "y",
17730
+ "4": "y",
17731
+ "5": "y",
17732
+ "6": "y",
17733
+ "7": "y",
17734
+ "8": "y",
17735
+ "9": "y",
17736
+ "10": "y",
17737
+ "11": "y",
17738
+ "12": "y",
17739
+ "13": "y",
17740
+ "14": "y",
17741
+ "15": "y",
17742
+ "16": "y",
17743
+ "17": "y",
17744
+ "18": "y",
17745
+ "19": "y",
17746
+ "20": "y",
17747
+ "21": "y",
17748
+ "22": "y",
17749
+ "23": "y",
17750
+ "24": "y",
17751
+ "25": "y",
17752
+ "26": "y",
17753
+ "27": "y"
17754
+ },
17755
+ "chrome": {
17756
+ "4": "y",
17757
+ "5": "y",
17758
+ "6": "y",
17759
+ "7": "y",
17760
+ "8": "y",
17761
+ "9": "y",
17762
+ "10": "y",
17763
+ "11": "y",
17764
+ "12": "y",
17765
+ "13": "y",
17766
+ "14": "y",
17767
+ "15": "y",
17768
+ "16": "y",
17769
+ "17": "y",
17770
+ "18": "y",
17771
+ "19": "y",
17772
+ "20": "y",
17773
+ "21": "y",
17774
+ "22": "y",
17775
+ "23": "y",
17776
+ "24": "y",
17777
+ "25": "y",
17778
+ "26": "y",
17779
+ "27": "y",
17780
+ "28": "y",
17781
+ "29": "y",
17782
+ "30": "y",
17783
+ "31": "y",
17784
+ "32": "y"
17785
+ },
17786
+ "safari": {
17787
+ "3.1": "n",
17788
+ "3.2": "n",
17789
+ "4": "y",
17790
+ "5": "y",
17791
+ "5.1": "y",
17792
+ "6": "y",
17793
+ "6.1": "y",
17794
+ "7": "y"
17795
+ },
17796
+ "opera": {
17797
+ "9": "n",
17798
+ "9.5-9.6": "n",
17799
+ "10.0-10.1": "n",
17800
+ "10.5": "n",
17801
+ "10.6": "n",
17802
+ "11": "n",
17803
+ "11.1": "n",
17804
+ "11.5": "n",
17805
+ "11.6": "n",
17806
+ "12": "y",
17807
+ "12.1": "y",
17808
+ "15": "y",
17809
+ "16": "y",
17810
+ "17": "y",
17811
+ "18": "y"
17812
+ },
17813
+ "ios_saf": {
17814
+ "3.2": "y",
17815
+ "4.0-4.1": "y",
17816
+ "4.2-4.3": "y",
17817
+ "5.0-5.1": "y",
17818
+ "6.0-6.1": "y",
17819
+ "7.0": "y"
17820
+ },
17821
+ "op_mini": {
17822
+ "5.0-7.0": "n"
17823
+ },
17824
+ "android": {
17825
+ "2.1": "y",
17826
+ "2.2": "y",
17827
+ "2.3": "y",
17828
+ "3": "y",
17829
+ "4": "y",
17830
+ "4.1": "y",
17831
+ "4.2-4.3": "y",
17832
+ "4.4": "y"
17833
+ },
17834
+ "bb": {
17835
+ "7": "y",
17836
+ "10": "y"
17837
+ },
17838
+ "op_mob": {
17839
+ "10": "n",
17840
+ "11": "n",
17841
+ "11.1": "n",
17842
+ "11.5": "n",
17843
+ "12": "y",
17844
+ "12.1": "y",
17845
+ "0": "y"
17846
+ },
17847
+ "and_chr": {
17848
+ "0": "y"
17849
+ },
17850
+ "and_ff": {
17851
+ "0": "y"
17852
+ },
17853
+ "ie_mob": {
17854
+ "10": "y"
17855
+ }
17856
+ },
17857
+ "notes": "Supported somewhat in IE8 and IE9 using the XDomainRequest object (but has <a href=\" http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\">limitations</a>)",
17858
+ "usage_perc_y": 75.51,
17859
+ "usage_perc_a": 13.52,
17860
+ "ucprefix": false,
17861
+ "parent": "",
17862
+ "keywords": ""
17863
+ },
17864
+ "calc": {
17865
+ "title": "calc() as CSS unit value",
17866
+ "description": "Method of allowing calculated values for length units, i.e. width: calc(100% - 3em)",
17867
+ "spec": "http://www.w3.org/TR/css3-values/#calc",
17868
+ "status": "cr",
17869
+ "links": [{
17870
+ "url": "http://docs.webplatform.org/wiki/css/functions/calc",
17871
+ "title": "WebPlatform Docs"
17872
+ }, {
17873
+ "url": "https://developer.mozilla.org/en/CSS/-moz-calc",
17874
+ "title": "MDN article"
17875
+ }, {
17876
+ "url": "http://hacks.mozilla.org/2010/06/css3-calc/",
17877
+ "title": "Mozilla Hacks article"
17878
+ }],
17879
+ "categories": ["CSS3"],
17880
+ "stats": {
17881
+ "ie": {
17882
+ "5.5": "n",
17883
+ "6": "n",
17884
+ "7": "n",
17885
+ "8": "n",
17886
+ "9": "y",
17887
+ "10": "y",
17888
+ "11": "y"
17889
+ },
17890
+ "firefox": {
17891
+ "2": "n",
17892
+ "3": "n",
17893
+ "3.5": "n",
17894
+ "3.6": "n",
17895
+ "4": "y x",
17896
+ "5": "y x",
17897
+ "6": "y x",
17898
+ "7": "y x",
17899
+ "8": "y x",
17900
+ "9": "y x",
17901
+ "10": "y x",
17902
+ "11": "y x",
17903
+ "12": "y x",
17904
+ "13": "y x",
17905
+ "14": "y x",
17906
+ "15": "y x",
17907
+ "16": "y",
17908
+ "17": "y",
17909
+ "18": "y",
17910
+ "19": "y",
17911
+ "20": "y",
17912
+ "21": "y",
17913
+ "22": "y",
17914
+ "23": "y",
17915
+ "24": "y",
17916
+ "25": "y",
17917
+ "26": "y",
17918
+ "27": "y"
17919
+ },
17920
+ "chrome": {
17921
+ "4": "n",
17922
+ "5": "n",
17923
+ "6": "n",
17924
+ "7": "n",
17925
+ "8": "n",
17926
+ "9": "n",
17927
+ "10": "n",
17928
+ "11": "n",
17929
+ "12": "n",
17930
+ "13": "n",
17931
+ "14": "n",
17932
+ "15": "n",
17933
+ "16": "n",
17934
+ "17": "n",
17935
+ "18": "n",
17936
+ "19": "y x",
17937
+ "20": "y x",
17938
+ "21": "y x",
17939
+ "22": "y x",
17940
+ "23": "y x",
17941
+ "24": "y x",
17942
+ "25": "y x",
17943
+ "26": "y",
17944
+ "27": "y",
17945
+ "28": "y",
17946
+ "29": "y",
17947
+ "30": "y",
17948
+ "31": "y",
17949
+ "32": "y"
17950
+ },
17951
+ "safari": {
17952
+ "3.1": "n",
17953
+ "3.2": "n",
17954
+ "4": "n",
17955
+ "5": "n",
17956
+ "5.1": "n",
17957
+ "6": "y x",
17958
+ "6.1": "y",
17959
+ "7": "y"
17960
+ },
17961
+ "opera": {
17962
+ "9": "n",
17963
+ "9.5-9.6": "n",
17964
+ "10.0-10.1": "n",
17965
+ "10.5": "n",
17966
+ "10.6": "n",
17967
+ "11": "n",
17968
+ "11.1": "n",
17969
+ "11.5": "n",
17970
+ "11.6": "n",
17971
+ "12": "n",
17972
+ "12.1": "n",
17973
+ "15": "y",
17974
+ "16": "y",
17975
+ "17": "y",
17976
+ "18": "y"
17977
+ },
17978
+ "ios_saf": {
17979
+ "3.2": "n",
17980
+ "4.0-4.1": "n",
17981
+ "4.2-4.3": "n",
17982
+ "5.0-5.1": "n",
17983
+ "6.0-6.1": "y x",
17984
+ "7.0": "y"
17985
+ },
17986
+ "op_mini": {
17987
+ "5.0-7.0": "n"
17988
+ },
17989
+ "android": {
17990
+ "2.1": "n",
17991
+ "2.2": "n",
17992
+ "2.3": "n",
17993
+ "3": "n",
17994
+ "4": "n",
17995
+ "4.1": "n",
17996
+ "4.2-4.3": "n",
17997
+ "4.4": "y"
17998
+ },
17999
+ "bb": {
18000
+ "7": "n",
18001
+ "10": "y x"
18002
+ },
18003
+ "op_mob": {
18004
+ "10": "n",
18005
+ "11": "n",
18006
+ "11.1": "n",
18007
+ "11.5": "n",
18008
+ "12": "n",
18009
+ "12.1": "n",
18010
+ "0": "y"
18011
+ },
18012
+ "and_chr": {
18013
+ "0": "y"
18014
+ },
18015
+ "and_ff": {
18016
+ "0": "y"
18017
+ },
18018
+ "ie_mob": {
18019
+ "10": "y"
18020
+ }
18021
+ },
18022
+ "notes": "Support can be somewhat emulated in older versions of IE using the non-standard expression() syntax. ",
18023
+ "usage_perc_y": 71.77,
18024
+ "usage_perc_a": 0,
18025
+ "ucprefix": false,
18026
+ "parent": "",
18027
+ "keywords": ""
18028
+ },
18029
+ "ruby": {
18030
+ "title": "Ruby annotation",
18031
+ "description": "Method of adding pronunciation or other annotations using ruby elements (primarily used in East Asian typography)",
18032
+ "spec": "http://www.w3.org/TR/html-markup/ruby.html",
18033
+ "status": "wd",
18034
+ "links": [{
18035
+ "url": "https://addons.mozilla.org/firefox/addon/6812/",
18036
+ "title": "Addon \"HTML Ruby\" for Firefox support"
18037
+ }, {
18038
+ "url": "http://html5doctor.com/ruby-rt-rp-element/",
18039
+ "title": "HTML5 Doctor article"
18040
+ }, {
18041
+ "url": "http://docs.webplatform.org/wiki/html/elements/ruby",
18042
+ "title": "WebPlatform Docs"
18043
+ }, {
18044
+ "url": "https://addons.mozilla.org/firefox/addon/1935/",
18045
+ "title": "Add-on \"XHTML Ruby Support\" for Firefox"
18046
+ }],
18047
+ "categories": ["HTML5"],
18048
+ "stats": {
18049
+ "ie": {
18050
+ "5.5": "a",
18051
+ "6": "a",
18052
+ "7": "a",
18053
+ "8": "a",
18054
+ "9": "a",
18055
+ "10": "a",
18056
+ "11": "a"
18057
+ },
18058
+ "firefox": {
18059
+ "2": "p",
18060
+ "3": "p",
18061
+ "3.5": "p",
18062
+ "3.6": "p",
18063
+ "4": "p",
18064
+ "5": "p",
18065
+ "6": "p",
18066
+ "7": "p",
18067
+ "8": "p",
18068
+ "9": "p",
18069
+ "10": "p",
18070
+ "11": "p",
18071
+ "12": "p",
18072
+ "13": "p",
18073
+ "14": "p",
18074
+ "15": "p",
18075
+ "16": "p",
18076
+ "17": "p",
18077
+ "18": "p",
18078
+ "19": "p",
18079
+ "20": "p",
18080
+ "21": "p",
18081
+ "22": "p",
18082
+ "23": "p",
18083
+ "24": "p",
18084
+ "25": "p",
18085
+ "26": "p",
18086
+ "27": "p"
18087
+ },
18088
+ "chrome": {
18089
+ "4": "p",
18090
+ "5": "a",
18091
+ "6": "a",
18092
+ "7": "a",
18093
+ "8": "a",
18094
+ "9": "a",
18095
+ "10": "a",
18096
+ "11": "a",
18097
+ "12": "a",
18098
+ "13": "a",
18099
+ "14": "a",
18100
+ "15": "a",
18101
+ "16": "a",
18102
+ "17": "a",
18103
+ "18": "a",
18104
+ "19": "a",
18105
+ "20": "a",
18106
+ "21": "a",
18107
+ "22": "a",
18108
+ "23": "a",
18109
+ "24": "a",
18110
+ "25": "a",
18111
+ "26": "a",
18112
+ "27": "a",
18113
+ "28": "a",
18114
+ "29": "a",
18115
+ "30": "a",
18116
+ "31": "a",
18117
+ "32": "a"
18118
+ },
18119
+ "safari": {
18120
+ "3.1": "p",
18121
+ "3.2": "p",
18122
+ "4": "p",
18123
+ "5": "a",
18124
+ "5.1": "a",
18125
+ "6": "a",
18126
+ "6.1": "a",
18127
+ "7": "a"
18128
+ },
18129
+ "opera": {
18130
+ "9": "p",
18131
+ "9.5-9.6": "p",
18132
+ "10.0-10.1": "p",
18133
+ "10.5": "p",
18134
+ "10.6": "p",
18135
+ "11": "p",
18136
+ "11.1": "p",
18137
+ "11.5": "p",
18138
+ "11.6": "p",
18139
+ "12": "p",
18140
+ "12.1": "p",
18141
+ "15": "a",
18142
+ "16": "a",
18143
+ "17": "a",
18144
+ "18": "a"
18145
+ },
18146
+ "ios_saf": {
18147
+ "3.2": "p",
18148
+ "4.0-4.1": "p",
18149
+ "4.2-4.3": "p",
18150
+ "5.0-5.1": "a",
18151
+ "6.0-6.1": "a",
18152
+ "7.0": "a"
18153
+ },
18154
+ "op_mini": {
18155
+ "5.0-7.0": "p"
18156
+ },
18157
+ "android": {
18158
+ "2.1": "p",
18159
+ "2.2": "p",
18160
+ "2.3": "p",
18161
+ "3": "a",
18162
+ "4": "a",
18163
+ "4.1": "a",
18164
+ "4.2-4.3": "a",
18165
+ "4.4": "a"
18166
+ },
18167
+ "bb": {
18168
+ "7": "p",
18169
+ "10": "a"
18170
+ },
18171
+ "op_mob": {
18172
+ "10": "p",
18173
+ "11": "p",
18174
+ "11.1": "p",
18175
+ "11.5": "p",
18176
+ "12": "p",
18177
+ "12.1": "p",
18178
+ "0": "a"
18179
+ },
18180
+ "and_chr": {
18181
+ "0": "a"
18182
+ },
18183
+ "and_ff": {
18184
+ "0": "p"
18185
+ },
18186
+ "ie_mob": {
18187
+ "10": "a"
18188
+ }
18189
+ },
18190
+ "notes": "Browsers without native support can still simulate support using CSS. Partial support refers to only supporting basic ruby, may still be missing writing-mode, Complex ruby and CSS3 Ruby",
18191
+ "usage_perc_y": 0,
18192
+ "usage_perc_a": 72.03,
18193
+ "ucprefix": false,
18194
+ "parent": "",
18195
+ "keywords": ""
18196
+ },
18197
+ "css-opacity": {
18198
+ "title": "CSS3 Opacity",
18199
+ "description": "Method of setting the transparency level of an element",
18200
+ "spec": "http://www.w3.org/TR/css3-color/",
18201
+ "status": "rec",
18202
+ "links": [{
18203
+ "url": "http://www.css3files.com/color/#opacity",
18204
+ "title": "Information page"
18205
+ }, {
18206
+ "url": "http://docs.webplatform.org/wiki/css/properties/opacity",
18207
+ "title": "WebPlatform Docs"
18208
+ }],
18209
+ "categories": ["CSS3"],
18210
+ "stats": {
18211
+ "ie": {
18212
+ "5.5": "a",
18213
+ "6": "a",
18214
+ "7": "a",
18215
+ "8": "a",
18216
+ "9": "y",
18217
+ "10": "y",
18218
+ "11": "y"
18219
+ },
18220
+ "firefox": {
18221
+ "2": "y",
18222
+ "3": "y",
18223
+ "3.5": "y",
18224
+ "3.6": "y",
18225
+ "4": "y",
18226
+ "5": "y",
18227
+ "6": "y",
18228
+ "7": "y",
18229
+ "8": "y",
18230
+ "9": "y",
18231
+ "10": "y",
18232
+ "11": "y",
18233
+ "12": "y",
18234
+ "13": "y",
18235
+ "14": "y",
18236
+ "15": "y",
18237
+ "16": "y",
18238
+ "17": "y",
18239
+ "18": "y",
18240
+ "19": "y",
18241
+ "20": "y",
18242
+ "21": "y",
18243
+ "22": "y",
18244
+ "23": "y",
18245
+ "24": "y",
18246
+ "25": "y",
18247
+ "26": "y",
18248
+ "27": "y"
18249
+ },
18250
+ "chrome": {
18251
+ "4": "y",
18252
+ "5": "y",
18253
+ "6": "y",
18254
+ "7": "y",
18255
+ "8": "y",
18256
+ "9": "y",
18257
+ "10": "y",
18258
+ "11": "y",
18259
+ "12": "y",
18260
+ "13": "y",
18261
+ "14": "y",
18262
+ "15": "y",
18263
+ "16": "y",
18264
+ "17": "y",
18265
+ "18": "y",
18266
+ "19": "y",
18267
+ "20": "y",
18268
+ "21": "y",
18269
+ "22": "y",
18270
+ "23": "y",
18271
+ "24": "y",
18272
+ "25": "y",
18273
+ "26": "y",
18274
+ "27": "y",
18275
+ "28": "y",
18276
+ "29": "y",
18277
+ "30": "y",
18278
+ "31": "y",
18279
+ "32": "y"
18280
+ },
18281
+ "safari": {
18282
+ "3.1": "y",
18283
+ "3.2": "y",
18284
+ "4": "y",
18285
+ "5": "y",
18286
+ "5.1": "y",
18287
+ "6": "y",
18288
+ "6.1": "y",
18289
+ "7": "y"
18290
+ },
18291
+ "opera": {
18292
+ "9": "y",
18293
+ "9.5-9.6": "y",
18294
+ "10.0-10.1": "y",
18295
+ "10.5": "y",
18296
+ "10.6": "y",
18297
+ "11": "y",
18298
+ "11.1": "y",
18299
+ "11.5": "y",
18300
+ "11.6": "y",
18301
+ "12": "y",
18302
+ "12.1": "y",
18303
+ "15": "y",
18304
+ "16": "y",
18305
+ "17": "y",
18306
+ "18": "y"
18307
+ },
18308
+ "ios_saf": {
18309
+ "3.2": "y",
18310
+ "4.0-4.1": "y",
18311
+ "4.2-4.3": "y",
18312
+ "5.0-5.1": "y",
18313
+ "6.0-6.1": "y",
18314
+ "7.0": "y"
18315
+ },
18316
+ "op_mini": {
18317
+ "5.0-7.0": "y"
18318
+ },
18319
+ "android": {
18320
+ "2.1": "y",
18321
+ "2.2": "y",
18322
+ "2.3": "y",
18323
+ "3": "y",
18324
+ "4": "y",
18325
+ "4.1": "y",
18326
+ "4.2-4.3": "y",
18327
+ "4.4": "y"
18328
+ },
18329
+ "bb": {
18330
+ "7": "y",
18331
+ "10": "y"
18332
+ },
18333
+ "op_mob": {
18334
+ "10": "y",
18335
+ "11": "y",
18336
+ "11.1": "y",
18337
+ "11.5": "y",
18338
+ "12": "y",
18339
+ "12.1": "y",
18340
+ "0": "y"
18341
+ },
18342
+ "and_chr": {
18343
+ "0": "y"
18344
+ },
18345
+ "and_ff": {
18346
+ "0": "y"
18347
+ },
18348
+ "ie_mob": {
18349
+ "10": "y"
18350
+ }
18351
+ },
18352
+ "notes": "Transparency for elements in IE8 and older can be achieved using the proprietary \"filter\" property and does not work well with PNG images using alpha transparency.",
18353
+ "usage_perc_y": 85.55,
18354
+ "usage_perc_a": 9.03,
18355
+ "ucprefix": false,
18356
+ "parent": "",
18357
+ "keywords": "transparent,transparency,alpha"
18358
+ },
18359
+ "form-validation": {
18360
+ "title": "Form validation",
18361
+ "description": "Method of setting required fields and field types without requiring JavaScript",
18362
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#client-side-form-validation",
18363
+ "status": "wd",
18364
+ "links": [{
18365
+ "url": "http://docs.webplatform.org/wiki/html/attributes/required",
18366
+ "title": "WebPlatform Docs"
18367
+ }],
18368
+ "categories": ["HTML5"],
18369
+ "stats": {
18370
+ "ie": {
18371
+ "5.5": "n",
18372
+ "6": "n",
18373
+ "7": "n",
18374
+ "8": "n",
18375
+ "9": "n",
18376
+ "10": "y",
18377
+ "11": "y"
18378
+ },
18379
+ "firefox": {
18380
+ "2": "n",
18381
+ "3": "n",
18382
+ "3.5": "n",
18383
+ "3.6": "n",
18384
+ "4": "y",
18385
+ "5": "y",
18386
+ "6": "y",
18387
+ "7": "y",
18388
+ "8": "y",
18389
+ "9": "y",
18390
+ "10": "y",
18391
+ "11": "y",
18392
+ "12": "y",
18393
+ "13": "y",
18394
+ "14": "y",
18395
+ "15": "y",
18396
+ "16": "y",
18397
+ "17": "y",
18398
+ "18": "y",
18399
+ "19": "y",
18400
+ "20": "y",
18401
+ "21": "y",
18402
+ "22": "y",
18403
+ "23": "y",
18404
+ "24": "y",
18405
+ "25": "y",
18406
+ "26": "y",
18407
+ "27": "y"
18408
+ },
18409
+ "chrome": {
18410
+ "4": "n",
18411
+ "5": "n",
18412
+ "6": "n",
18413
+ "7": "n",
18414
+ "8": "n",
18415
+ "9": "n",
18416
+ "10": "y",
18417
+ "11": "y",
18418
+ "12": "y",
18419
+ "13": "y",
18420
+ "14": "y",
18421
+ "15": "y",
18422
+ "16": "y",
18423
+ "17": "y",
18424
+ "18": "y",
18425
+ "19": "y",
18426
+ "20": "y",
18427
+ "21": "y",
18428
+ "22": "y",
18429
+ "23": "y",
18430
+ "24": "y",
18431
+ "25": "y",
18432
+ "26": "y",
18433
+ "27": "y",
18434
+ "28": "y",
18435
+ "29": "y",
18436
+ "30": "y",
18437
+ "31": "y",
18438
+ "32": "y"
18439
+ },
18440
+ "safari": {
18441
+ "3.1": "n",
18442
+ "3.2": "n",
18443
+ "4": "n",
18444
+ "5": "a",
18445
+ "5.1": "a",
18446
+ "6": "a",
18447
+ "6.1": "a",
18448
+ "7": "a"
18449
+ },
18450
+ "opera": {
18451
+ "9": "n",
18452
+ "9.5-9.6": "n",
18453
+ "10.0-10.1": "y",
18454
+ "10.5": "y",
18455
+ "10.6": "y",
18456
+ "11": "y",
18457
+ "11.1": "y",
18458
+ "11.5": "y",
18459
+ "11.6": "y",
18460
+ "12": "y",
18461
+ "12.1": "y",
18462
+ "15": "y",
18463
+ "16": "y",
18464
+ "17": "y",
18465
+ "18": "y"
18466
+ },
18467
+ "ios_saf": {
18468
+ "3.2": "n",
18469
+ "4.0-4.1": "n",
18470
+ "4.2-4.3": "n",
18471
+ "5.0-5.1": "n",
18472
+ "6.0-6.1": "n",
18473
+ "7.0": "n"
18474
+ },
18475
+ "op_mini": {
18476
+ "5.0-7.0": "n"
18477
+ },
18478
+ "android": {
18479
+ "2.1": "n",
18480
+ "2.2": "n",
18481
+ "2.3": "n",
18482
+ "3": "n",
18483
+ "4": "n",
18484
+ "4.1": "n",
18485
+ "4.2-4.3": "n",
18486
+ "4.4": "n"
18487
+ },
18488
+ "bb": {
18489
+ "7": "n",
18490
+ "10": "y"
18491
+ },
18492
+ "op_mob": {
18493
+ "10": "y",
18494
+ "11": "y",
18495
+ "11.1": "y",
18496
+ "11.5": "y",
18497
+ "12": "y",
18498
+ "12.1": "y",
18499
+ "0": "y"
18500
+ },
18501
+ "and_chr": {
18502
+ "0": "y"
18503
+ },
18504
+ "and_ff": {
18505
+ "0": "y"
18506
+ },
18507
+ "ie_mob": {
18508
+ "10": "a"
18509
+ }
18510
+ },
18511
+ "notes": "Partial support in Safari refers to lack of notice when form with required fields is attempted to be submitted. Partial support in IE10 mobile refers to lack of warning when blocking submission.",
18512
+ "usage_perc_y": 61.75,
18513
+ "usage_perc_a": 4.07,
18514
+ "ucprefix": false,
18515
+ "parent": "forms",
18516
+ "keywords": ""
18517
+ },
18518
+ "history": {
18519
+ "title": "Session history management",
18520
+ "description": "Method of manipulating the user's browser's session history in JavaScript using history.pushState, history.replaceState and the popstate event",
18521
+ "spec": "http://www.w3.org/TR/html5/browsers.html#history-1",
18522
+ "status": "cr",
18523
+ "links": [{
18524
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-history-state",
18525
+ "title": "has.js test"
18526
+ }, {
18527
+ "url": "https://github.com/browserstate/history.js",
18528
+ "title": "History.js polyfill "
18529
+ }, {
18530
+ "url": "http://docs.webplatform.org/wiki/dom/history",
18531
+ "title": "WebPlatform Docs"
18532
+ }, {
18533
+ "url": "http://html5demos.com/history",
18534
+ "title": "Demo page"
18535
+ }, {
18536
+ "url": "http://www.adequatelygood.com/2010/7/Saner-HTML5-History-Management",
18537
+ "title": "Introduction to history management"
18538
+ }, {
18539
+ "url": "https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history",
18540
+ "title": "MDN article"
18541
+ }],
18542
+ "categories": ["HTML5"],
18543
+ "stats": {
18544
+ "ie": {
18545
+ "5.5": "n",
18546
+ "6": "n",
18547
+ "7": "n",
18548
+ "8": "n",
18549
+ "9": "n",
18550
+ "10": "y",
18551
+ "11": "y"
18552
+ },
18553
+ "firefox": {
18554
+ "2": "n",
18555
+ "3": "n",
18556
+ "3.5": "n",
18557
+ "3.6": "n",
18558
+ "4": "y",
18559
+ "5": "y",
18560
+ "6": "y",
18561
+ "7": "y",
18562
+ "8": "y",
18563
+ "9": "y",
18564
+ "10": "y",
18565
+ "11": "y",
18566
+ "12": "y",
18567
+ "13": "y",
18568
+ "14": "y",
18569
+ "15": "y",
18570
+ "16": "y",
18571
+ "17": "y",
18572
+ "18": "y",
18573
+ "19": "y",
18574
+ "20": "y",
18575
+ "21": "y",
18576
+ "22": "y",
18577
+ "23": "y",
18578
+ "24": "y",
18579
+ "25": "y",
18580
+ "26": "y",
18581
+ "27": "y"
18582
+ },
18583
+ "chrome": {
18584
+ "4": "n",
18585
+ "5": "y",
18586
+ "6": "y",
18587
+ "7": "y",
18588
+ "8": "y",
18589
+ "9": "y",
18590
+ "10": "y",
18591
+ "11": "y",
18592
+ "12": "y",
18593
+ "13": "y",
18594
+ "14": "y",
18595
+ "15": "y",
18596
+ "16": "y",
18597
+ "17": "y",
18598
+ "18": "y",
18599
+ "19": "y",
18600
+ "20": "y",
18601
+ "21": "y",
18602
+ "22": "y",
18603
+ "23": "y",
18604
+ "24": "y",
18605
+ "25": "y",
18606
+ "26": "y",
18607
+ "27": "y",
18608
+ "28": "y",
18609
+ "29": "y",
18610
+ "30": "y",
18611
+ "31": "y",
18612
+ "32": "y"
18613
+ },
18614
+ "safari": {
18615
+ "3.1": "n",
18616
+ "3.2": "n",
18617
+ "4": "n",
18618
+ "5": "a",
18619
+ "5.1": "a",
18620
+ "6": "a",
18621
+ "6.1": "a",
18622
+ "7": "a"
18623
+ },
18624
+ "opera": {
18625
+ "9": "n",
18626
+ "9.5-9.6": "n",
18627
+ "10.0-10.1": "n",
18628
+ "10.5": "n",
18629
+ "10.6": "n",
18630
+ "11": "n",
18631
+ "11.1": "n",
18632
+ "11.5": "y",
18633
+ "11.6": "y",
18634
+ "12": "y",
18635
+ "12.1": "y",
18636
+ "15": "y",
18637
+ "16": "y",
18638
+ "17": "y",
18639
+ "18": "y"
18640
+ },
18641
+ "ios_saf": {
18642
+ "3.2": "n",
18643
+ "4.0-4.1": "n",
18644
+ "4.2-4.3": "a",
18645
+ "5.0-5.1": "y",
18646
+ "6.0-6.1": "y",
18647
+ "7.0": "y"
18648
+ },
18649
+ "op_mini": {
18650
+ "5.0-7.0": "n"
18651
+ },
18652
+ "android": {
18653
+ "2.1": "n",
18654
+ "2.2": "y",
18655
+ "2.3": "y",
18656
+ "3": "n",
18657
+ "4": "n",
18658
+ "4.1": "n",
18659
+ "4.2-4.3": "y",
18660
+ "4.4": "y"
18661
+ },
18662
+ "bb": {
18663
+ "7": "y",
18664
+ "10": "y"
18665
+ },
18666
+ "op_mob": {
18667
+ "10": "n",
18668
+ "11": "n",
18669
+ "11.1": "y",
18670
+ "11.5": "y",
18671
+ "12": "y",
18672
+ "12.1": "y",
18673
+ "0": "y"
18674
+ },
18675
+ "and_chr": {
18676
+ "0": "y"
18677
+ },
18678
+ "and_ff": {
18679
+ "0": "y"
18680
+ },
18681
+ "ie_mob": {
18682
+ "10": "y"
18683
+ }
18684
+ },
18685
+ "notes": "Older iOS versions and Android 4.0.4 claim support, but implementation is too buggy to be useful. Partial support in other Safari browsers refers to other buggy behavior.",
18686
+ "usage_perc_y": 68.29,
18687
+ "usage_perc_a": 3.89,
18688
+ "ucprefix": false,
18689
+ "parent": "",
18690
+ "keywords": "onpushstate,onreplacestate"
18691
+ },
18692
+ "json": {
18693
+ "title": "JSON parsing",
18694
+ "description": "Method of converting JavaScript objects to JSON strings and JSON back to objects using JSON.stringify() and JSON.parse()",
18695
+ "spec": "http://es5.github.com/#x15.12",
18696
+ "status": "other",
18697
+ "links": [{
18698
+ "url": "http://docs.webplatform.org/wiki/apis/json",
18699
+ "title": "WebPlatform Docs"
18700
+ }, {
18701
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/json.js#json",
18702
+ "title": "has.js test"
18703
+ }, {
18704
+ "url": "http://www.json.org/js.html",
18705
+ "title": "JSON in JS (includes script w/support)"
18706
+ }, {
18707
+ "url": "https://developer.mozilla.org/En/Using_native_JSON",
18708
+ "title": "MDN article"
18709
+ }],
18710
+ "categories": ["JS API"],
18711
+ "stats": {
18712
+ "ie": {
18713
+ "5.5": "n",
18714
+ "6": "n",
18715
+ "7": "n",
18716
+ "8": "y",
18717
+ "9": "y",
18718
+ "10": "y",
18719
+ "11": "y"
18720
+ },
18721
+ "firefox": {
18722
+ "2": "n",
18723
+ "3": "n",
18724
+ "3.5": "y",
18725
+ "3.6": "y",
18726
+ "4": "y",
18727
+ "5": "y",
18728
+ "6": "y",
18729
+ "7": "y",
18730
+ "8": "y",
18731
+ "9": "y",
18732
+ "10": "y",
18733
+ "11": "y",
18734
+ "12": "y",
18735
+ "13": "y",
18736
+ "14": "y",
18737
+ "15": "y",
18738
+ "16": "y",
18739
+ "17": "y",
18740
+ "18": "y",
18741
+ "19": "y",
18742
+ "20": "y",
18743
+ "21": "y",
18744
+ "22": "y",
18745
+ "23": "y",
18746
+ "24": "y",
18747
+ "25": "y",
18748
+ "26": "y",
18749
+ "27": "y"
18750
+ },
18751
+ "chrome": {
18752
+ "4": "y",
18753
+ "5": "y",
18754
+ "6": "y",
18755
+ "7": "y",
18756
+ "8": "y",
18757
+ "9": "y",
18758
+ "10": "y",
18759
+ "11": "y",
18760
+ "12": "y",
18761
+ "13": "y",
18762
+ "14": "y",
18763
+ "15": "y",
18764
+ "16": "y",
18765
+ "17": "y",
18766
+ "18": "y",
18767
+ "19": "y",
18768
+ "20": "y",
18769
+ "21": "y",
18770
+ "22": "y",
18771
+ "23": "y",
18772
+ "24": "y",
18773
+ "25": "y",
18774
+ "26": "y",
18775
+ "27": "y",
18776
+ "28": "y",
18777
+ "29": "y",
18778
+ "30": "y",
18779
+ "31": "y",
18780
+ "32": "y"
18781
+ },
18782
+ "safari": {
18783
+ "3.1": "n",
18784
+ "3.2": "n",
18785
+ "4": "y",
18786
+ "5": "y",
18787
+ "5.1": "y",
18788
+ "6": "y",
18789
+ "6.1": "y",
18790
+ "7": "y"
18791
+ },
18792
+ "opera": {
18793
+ "9": "n",
18794
+ "9.5-9.6": "n",
18795
+ "10.0-10.1": "n",
18796
+ "10.5": "y",
18797
+ "10.6": "y",
18798
+ "11": "y",
18799
+ "11.1": "y",
18800
+ "11.5": "y",
18801
+ "11.6": "y",
18802
+ "12": "y",
18803
+ "12.1": "y",
18804
+ "15": "y",
18805
+ "16": "y",
18806
+ "17": "y",
18807
+ "18": "y"
18808
+ },
18809
+ "ios_saf": {
18810
+ "3.2": "n",
18811
+ "4.0-4.1": "y",
18812
+ "4.2-4.3": "y",
18813
+ "5.0-5.1": "y",
18814
+ "6.0-6.1": "y",
18815
+ "7.0": "y"
18816
+ },
18817
+ "op_mini": {
18818
+ "5.0-7.0": "y"
18819
+ },
18820
+ "android": {
18821
+ "2.1": "y",
18822
+ "2.2": "y",
18823
+ "2.3": "y",
18824
+ "3": "y",
18825
+ "4": "y",
18826
+ "4.1": "y",
18827
+ "4.2-4.3": "y",
18828
+ "4.4": "y"
18829
+ },
18830
+ "bb": {
18831
+ "7": "y",
18832
+ "10": "y"
18833
+ },
18834
+ "op_mob": {
18835
+ "10": "y",
18836
+ "11": "y",
18837
+ "11.1": "y",
18838
+ "11.5": "y",
18839
+ "12": "y",
18840
+ "12.1": "y",
18841
+ "0": "y"
18842
+ },
18843
+ "and_chr": {
18844
+ "0": "y"
18845
+ },
18846
+ "and_ff": {
18847
+ "0": "y"
18848
+ },
18849
+ "ie_mob": {
18850
+ "10": "y"
18851
+ }
18852
+ },
18853
+ "notes": "Requires document to be in IE8+ <a href=\"http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx\">standards mode</a> to work in IE8.",
18854
+ "usage_perc_y": 93.71,
18855
+ "usage_perc_a": 0,
18856
+ "ucprefix": false,
18857
+ "parent": "",
18858
+ "keywords": ""
18859
+ },
18860
+ "classlist": {
18861
+ "title": "classList (DOMTokenList )",
18862
+ "description": "Method of easily manipulating classes on elements, using the DOMTokenList object.",
18863
+ "spec": "http://www.w3.org/TR/dom/#dom-element-classlist",
18864
+ "status": "wd",
18865
+ "links": [{
18866
+ "url": "https://github.com/eligrey/classList.js",
18867
+ "title": "Polyfill script"
18868
+ }, {
18869
+ "url": "http://hacks.mozilla.org/2010/01/classlist-in-firefox-3-6/",
18870
+ "title": "Mozilla Hacks article"
18871
+ }, {
18872
+ "url": "http://docs.webplatform.org/wiki/dom/properties/classList",
18873
+ "title": "WebPlatform Docs"
18874
+ }, {
18875
+ "url": "https://github.com/eligrey/classList.js/pull/12",
18876
+ "title": "Polyfill script for classList on SVG elements on WebKit"
18877
+ }],
18878
+ "categories": ["DOM", "HTML5"],
18879
+ "stats": {
18880
+ "ie": {
18881
+ "5.5": "p",
18882
+ "6": "p",
18883
+ "7": "p",
18884
+ "8": "p",
18885
+ "9": "p",
18886
+ "10": "y",
18887
+ "11": "y"
18888
+ },
18889
+ "firefox": {
18890
+ "2": "p",
18891
+ "3": "p",
18892
+ "3.5": "p",
18893
+ "3.6": "y",
18894
+ "4": "y",
18895
+ "5": "y",
18896
+ "6": "y",
18897
+ "7": "y",
18898
+ "8": "y",
18899
+ "9": "y",
18900
+ "10": "y",
18901
+ "11": "y",
18902
+ "12": "y",
18903
+ "13": "y",
18904
+ "14": "y",
18905
+ "15": "y",
18906
+ "16": "y",
18907
+ "17": "y",
18908
+ "18": "y",
18909
+ "19": "y",
18910
+ "20": "y",
18911
+ "21": "y",
18912
+ "22": "y",
18913
+ "23": "y",
18914
+ "24": "y",
18915
+ "25": "y",
18916
+ "26": "y",
18917
+ "27": "y"
18918
+ },
18919
+ "chrome": {
18920
+ "4": "p",
18921
+ "5": "p",
18922
+ "6": "p",
18923
+ "7": "p",
18924
+ "8": "y",
18925
+ "9": "y",
18926
+ "10": "y",
18927
+ "11": "y",
18928
+ "12": "y",
18929
+ "13": "y",
18930
+ "14": "y",
18931
+ "15": "y",
18932
+ "16": "y",
18933
+ "17": "y",
18934
+ "18": "y",
18935
+ "19": "y",
18936
+ "20": "y",
18937
+ "21": "y",
18938
+ "22": "y",
18939
+ "23": "y",
18940
+ "24": "y",
18941
+ "25": "y",
18942
+ "26": "y",
18943
+ "27": "y",
18944
+ "28": "y",
18945
+ "29": "y",
18946
+ "30": "y",
18947
+ "31": "y",
18948
+ "32": "y"
18949
+ },
18950
+ "safari": {
18951
+ "3.1": "p",
18952
+ "3.2": "p",
18953
+ "4": "p",
18954
+ "5": "p",
18955
+ "5.1": "y",
18956
+ "6": "y",
18957
+ "6.1": "y",
18958
+ "7": "y"
18959
+ },
18960
+ "opera": {
18961
+ "9": "p",
18962
+ "9.5-9.6": "p",
18963
+ "10.0-10.1": "p",
18964
+ "10.5": "p",
18965
+ "10.6": "p",
18966
+ "11": "p",
18967
+ "11.1": "p",
18968
+ "11.5": "y",
18969
+ "11.6": "y",
18970
+ "12": "y",
18971
+ "12.1": "y",
18972
+ "15": "y",
18973
+ "16": "y",
18974
+ "17": "y",
18975
+ "18": "y"
18976
+ },
18977
+ "ios_saf": {
18978
+ "3.2": "p",
18979
+ "4.0-4.1": "p",
18980
+ "4.2-4.3": "p",
18981
+ "5.0-5.1": "y",
18982
+ "6.0-6.1": "y",
18983
+ "7.0": "y"
18984
+ },
18985
+ "op_mini": {
18986
+ "5.0-7.0": "p"
18987
+ },
18988
+ "android": {
18989
+ "2.1": "p",
18990
+ "2.2": "p",
18991
+ "2.3": "p",
18992
+ "3": "y",
18993
+ "4": "y",
18994
+ "4.1": "y",
18995
+ "4.2-4.3": "y",
18996
+ "4.4": "y"
18997
+ },
18998
+ "bb": {
18999
+ "7": "y",
19000
+ "10": "y"
19001
+ },
19002
+ "op_mob": {
19003
+ "10": "p",
19004
+ "11": "p",
19005
+ "11.1": "y",
19006
+ "11.5": "y",
19007
+ "12": "y",
19008
+ "12.1": "y",
19009
+ "0": "y"
19010
+ },
19011
+ "and_chr": {
19012
+ "0": "y"
19013
+ },
19014
+ "and_ff": {
19015
+ "0": "y"
19016
+ },
19017
+ "ie_mob": {
19018
+ "10": "y"
19019
+ }
19020
+ },
19021
+ "notes": "",
19022
+ "usage_perc_y": 73.54,
19023
+ "usage_perc_a": 0,
19024
+ "ucprefix": false,
19025
+ "parent": "",
19026
+ "keywords": ""
19027
+ },
19028
+ "text-overflow": {
19029
+ "title": "CSS3 Text-overflow",
19030
+ "description": "Append ellipsis when text overflows its containing element",
19031
+ "spec": "http://www.w3.org/TR/css3-ui/#text-overflow0",
19032
+ "status": "wd",
19033
+ "links": [{
19034
+ "url": "http://www.css3files.com/text/",
19035
+ "title": "Information page"
19036
+ }, {
19037
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/css.js#css-text-overflow",
19038
+ "title": "has.js test"
19039
+ }, {
19040
+ "url": "http://docs.webplatform.org/wiki/css/properties/text-overflow",
19041
+ "title": "WebPlatform Docs"
19042
+ }, {
19043
+ "url": "https://developer.mozilla.org/En/CSS/Text-overflow",
19044
+ "title": "MDN article"
19045
+ }, {
19046
+ "url": "https://github.com/rmorse/AutoEllipsis",
19047
+ "title": "jQuery polyfill for Firefox"
19048
+ }],
19049
+ "categories": ["CSS3"],
19050
+ "stats": {
19051
+ "ie": {
19052
+ "5.5": "n",
19053
+ "6": "y",
19054
+ "7": "y",
19055
+ "8": "y",
19056
+ "9": "y",
19057
+ "10": "y",
19058
+ "11": "y"
19059
+ },
19060
+ "firefox": {
19061
+ "2": "p",
19062
+ "3": "p",
19063
+ "3.5": "p",
19064
+ "3.6": "p",
19065
+ "4": "p",
19066
+ "5": "p",
19067
+ "6": "p",
19068
+ "7": "y",
19069
+ "8": "y",
19070
+ "9": "y",
19071
+ "10": "y",
19072
+ "11": "y",
19073
+ "12": "y",
19074
+ "13": "y",
19075
+ "14": "y",
19076
+ "15": "y",
19077
+ "16": "y",
19078
+ "17": "y",
19079
+ "18": "y",
19080
+ "19": "y",
19081
+ "20": "y",
19082
+ "21": "y",
19083
+ "22": "y",
19084
+ "23": "y",
19085
+ "24": "y",
19086
+ "25": "y",
19087
+ "26": "y",
19088
+ "27": "y"
19089
+ },
19090
+ "chrome": {
19091
+ "4": "y",
19092
+ "5": "y",
19093
+ "6": "y",
19094
+ "7": "y",
19095
+ "8": "y",
19096
+ "9": "y",
19097
+ "10": "y",
19098
+ "11": "y",
19099
+ "12": "y",
19100
+ "13": "y",
19101
+ "14": "y",
19102
+ "15": "y",
19103
+ "16": "y",
19104
+ "17": "y",
19105
+ "18": "y",
19106
+ "19": "y",
19107
+ "20": "y",
19108
+ "21": "y",
19109
+ "22": "y",
19110
+ "23": "y",
19111
+ "24": "y",
19112
+ "25": "y",
19113
+ "26": "y",
19114
+ "27": "y",
19115
+ "28": "y",
19116
+ "29": "y",
19117
+ "30": "y",
19118
+ "31": "y",
19119
+ "32": "y"
19120
+ },
19121
+ "safari": {
19122
+ "3.1": "y",
19123
+ "3.2": "y",
19124
+ "4": "y",
19125
+ "5": "y",
19126
+ "5.1": "y",
19127
+ "6": "y",
19128
+ "6.1": "y",
19129
+ "7": "y"
19130
+ },
19131
+ "opera": {
19132
+ "9": "y x",
19133
+ "9.5-9.6": "y x",
19134
+ "10.0-10.1": "y x",
19135
+ "10.5": "y x",
19136
+ "10.6": "y x",
19137
+ "11": "y",
19138
+ "11.1": "y",
19139
+ "11.5": "y",
19140
+ "11.6": "y",
19141
+ "12": "y",
19142
+ "12.1": "y",
19143
+ "15": "y",
19144
+ "16": "y",
19145
+ "17": "y",
19146
+ "18": "y"
19147
+ },
19148
+ "ios_saf": {
19149
+ "3.2": "y",
19150
+ "4.0-4.1": "y",
19151
+ "4.2-4.3": "y",
19152
+ "5.0-5.1": "y",
19153
+ "6.0-6.1": "y",
19154
+ "7.0": "y"
19155
+ },
19156
+ "op_mini": {
19157
+ "5.0-7.0": "y x"
19158
+ },
19159
+ "android": {
19160
+ "2.1": "y",
19161
+ "2.2": "y",
19162
+ "2.3": "y",
19163
+ "3": "y",
19164
+ "4": "y",
19165
+ "4.1": "y",
19166
+ "4.2-4.3": "y",
19167
+ "4.4": "y"
19168
+ },
19169
+ "bb": {
19170
+ "7": "y",
19171
+ "10": "y"
19172
+ },
19173
+ "op_mob": {
19174
+ "10": "y x",
19175
+ "11": "y x",
19176
+ "11.1": "y x",
19177
+ "11.5": "y x",
19178
+ "12": "y x",
19179
+ "12.1": "y",
19180
+ "0": "y"
19181
+ },
19182
+ "and_chr": {
19183
+ "0": "y"
19184
+ },
19185
+ "and_ff": {
19186
+ "0": "y"
19187
+ },
19188
+ "ie_mob": {
19189
+ "10": "y"
19190
+ }
19191
+ },
19192
+ "notes": "",
19193
+ "usage_perc_y": 93.95,
19194
+ "usage_perc_a": 0,
19195
+ "ucprefix": false,
19196
+ "parent": "",
19197
+ "keywords": "textoverflow,ellipsis"
19198
+ },
19199
+ "webm": {
19200
+ "title": "WebM/VP8 video format",
19201
+ "description": "Multimedia format designed to provide a royalty-free, high-quality open video compression format for use with HTML5 video.",
19202
+ "spec": "http://www.webmproject.org/",
19203
+ "status": "other",
19204
+ "links": [{
19205
+ "url": "http://perian.org/",
19206
+ "title": "Perian :Mac OSX Webm Codec install"
19207
+ }, {
19208
+ "url": "https://tools.google.com/dlpage/webmmf",
19209
+ "title": "Codec for IE9 support"
19210
+ }, {
19211
+ "url": "http://webmproject.org",
19212
+ "title": "Officical website"
19213
+ }, {
19214
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/video.js#video-webm",
19215
+ "title": "has.js test"
19216
+ }, {
19217
+ "url": "http://www.broken-links.com/2010/09/01/playing-webm-in-safari-with-plugins/",
19218
+ "title": "Info on supporting WebM in Safari"
19219
+ }],
19220
+ "categories": ["Other"],
19221
+ "stats": {
19222
+ "ie": {
19223
+ "5.5": "n",
19224
+ "6": "n",
19225
+ "7": "n",
19226
+ "8": "n",
19227
+ "9": "p",
19228
+ "10": "p",
19229
+ "11": "p"
19230
+ },
19231
+ "firefox": {
19232
+ "2": "n",
19233
+ "3": "n",
19234
+ "3.5": "n",
19235
+ "3.6": "n",
19236
+ "4": "y",
19237
+ "5": "y",
19238
+ "6": "y",
19239
+ "7": "y",
19240
+ "8": "y",
19241
+ "9": "y",
19242
+ "10": "y",
19243
+ "11": "y",
19244
+ "12": "y",
19245
+ "13": "y",
19246
+ "14": "y",
19247
+ "15": "y",
19248
+ "16": "y",
19249
+ "17": "y",
19250
+ "18": "y",
19251
+ "19": "y",
19252
+ "20": "y",
19253
+ "21": "y",
19254
+ "22": "y",
19255
+ "23": "y",
19256
+ "24": "y",
19257
+ "25": "y",
19258
+ "26": "y",
19259
+ "27": "y"
19260
+ },
19261
+ "chrome": {
19262
+ "4": "n",
19263
+ "5": "n",
19264
+ "6": "y",
19265
+ "7": "y",
19266
+ "8": "y",
19267
+ "9": "y",
19268
+ "10": "y",
19269
+ "11": "y",
19270
+ "12": "y",
19271
+ "13": "y",
19272
+ "14": "y",
19273
+ "15": "y",
19274
+ "16": "y",
19275
+ "17": "y",
19276
+ "18": "y",
19277
+ "19": "y",
19278
+ "20": "y",
19279
+ "21": "y",
19280
+ "22": "y",
19281
+ "23": "y",
19282
+ "24": "y",
19283
+ "25": "y",
19284
+ "26": "y",
19285
+ "27": "y",
19286
+ "28": "y",
19287
+ "29": "y",
19288
+ "30": "y",
19289
+ "31": "y",
19290
+ "32": "y"
19291
+ },
19292
+ "safari": {
19293
+ "3.1": "n",
19294
+ "3.2": "p",
19295
+ "4": "p",
19296
+ "5": "p",
19297
+ "5.1": "p",
19298
+ "6": "p",
19299
+ "6.1": "p",
19300
+ "7": "p"
19301
+ },
19302
+ "opera": {
19303
+ "9": "n",
19304
+ "9.5-9.6": "n",
19305
+ "10.0-10.1": "n",
19306
+ "10.5": "n",
19307
+ "10.6": "y",
19308
+ "11": "y",
19309
+ "11.1": "y",
19310
+ "11.5": "y",
19311
+ "11.6": "y",
19312
+ "12": "y",
19313
+ "12.1": "y",
19314
+ "15": "y",
19315
+ "16": "y",
19316
+ "17": "y",
19317
+ "18": "y"
19318
+ },
19319
+ "ios_saf": {
19320
+ "3.2": "n",
19321
+ "4.0-4.1": "n",
19322
+ "4.2-4.3": "n",
19323
+ "5.0-5.1": "n",
19324
+ "6.0-6.1": "n",
19325
+ "7.0": "n"
19326
+ },
19327
+ "op_mini": {
19328
+ "5.0-7.0": "n"
19329
+ },
19330
+ "android": {
19331
+ "2.1": "n",
19332
+ "2.2": "n",
19333
+ "2.3": "y",
19334
+ "3": "y",
19335
+ "4": "y",
19336
+ "4.1": "y",
19337
+ "4.2-4.3": "y",
19338
+ "4.4": "y"
19339
+ },
19340
+ "bb": {
19341
+ "7": "n",
19342
+ "10": "n"
19343
+ },
19344
+ "op_mob": {
19345
+ "10": "n",
19346
+ "11": "n",
19347
+ "11.1": "n",
19348
+ "11.5": "n",
19349
+ "12": "n",
19350
+ "12.1": "n",
19351
+ "0": "y"
19352
+ },
19353
+ "and_chr": {
19354
+ "0": "y"
19355
+ },
19356
+ "and_ff": {
19357
+ "0": "y"
19358
+ },
19359
+ "ie_mob": {
19360
+ "10": "p"
19361
+ }
19362
+ },
19363
+ "notes": "Will work in IE9+ and Safari/MacOSX provided the user has the WebM codecs installed.",
19364
+ "usage_perc_y": 55.72,
19365
+ "usage_perc_a": 0,
19366
+ "ucprefix": false,
19367
+ "parent": "video",
19368
+ "keywords": "matroska"
19369
+ },
19370
+ "mpeg4": {
19371
+ "title": "MPEG-4/H.264 video format",
19372
+ "description": "Commonly used video compression format (not royalty-free)",
19373
+ "spec": "http://ip.hhi.de/imagecom_G1/assets/pdfs/csvt_overview_0305.pdf",
19374
+ "status": "other",
19375
+ "links": [{
19376
+ "url": "http://www.interoperabilitybridges.com/html5-extension-for-wmp-plugin",
19377
+ "title": "Firefox extension allowing support in Win7"
19378
+ }, {
19379
+ "url": "http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC",
19380
+ "title": "Wikipedia article"
19381
+ }],
19382
+ "categories": ["Other"],
19383
+ "stats": {
19384
+ "ie": {
19385
+ "5.5": "n",
19386
+ "6": "n",
19387
+ "7": "n",
19388
+ "8": "n",
19389
+ "9": "y",
19390
+ "10": "y",
19391
+ "11": "y"
19392
+ },
19393
+ "firefox": {
19394
+ "2": "n",
19395
+ "3": "n",
19396
+ "3.5": "n",
19397
+ "3.6": "n",
19398
+ "4": "n",
19399
+ "5": "n",
19400
+ "6": "n",
19401
+ "7": "n",
19402
+ "8": "n",
19403
+ "9": "n",
19404
+ "10": "n",
19405
+ "11": "n",
19406
+ "12": "n",
19407
+ "13": "n",
19408
+ "14": "n",
19409
+ "15": "n",
19410
+ "16": "n",
19411
+ "17": "n",
19412
+ "18": "n",
19413
+ "19": "n",
19414
+ "20": "n",
19415
+ "21": "a",
19416
+ "22": "a",
19417
+ "23": "a",
19418
+ "24": "a",
19419
+ "25": "a",
19420
+ "26": "a",
19421
+ "27": "a"
19422
+ },
19423
+ "chrome": {
19424
+ "4": "y",
19425
+ "5": "y",
19426
+ "6": "y",
19427
+ "7": "y",
19428
+ "8": "y",
19429
+ "9": "y",
19430
+ "10": "y",
19431
+ "11": "y",
19432
+ "12": "y",
19433
+ "13": "y",
19434
+ "14": "y",
19435
+ "15": "y",
19436
+ "16": "y",
19437
+ "17": "y",
19438
+ "18": "y",
19439
+ "19": "y",
19440
+ "20": "y",
19441
+ "21": "y",
19442
+ "22": "y",
19443
+ "23": "y",
19444
+ "24": "y",
19445
+ "25": "y",
19446
+ "26": "y",
19447
+ "27": "y",
19448
+ "28": "y",
19449
+ "29": "y",
19450
+ "30": "y",
19451
+ "31": "y",
19452
+ "32": "y"
19453
+ },
19454
+ "safari": {
19455
+ "3.1": "n",
19456
+ "3.2": "y",
19457
+ "4": "y",
19458
+ "5": "y",
19459
+ "5.1": "y",
19460
+ "6": "y",
19461
+ "6.1": "y",
19462
+ "7": "y"
19463
+ },
19464
+ "opera": {
19465
+ "9": "n",
19466
+ "9.5-9.6": "n",
19467
+ "10.0-10.1": "n",
19468
+ "10.5": "n",
19469
+ "10.6": "n",
19470
+ "11": "n",
19471
+ "11.1": "n",
19472
+ "11.5": "n",
19473
+ "11.6": "n",
19474
+ "12": "n",
19475
+ "12.1": "n",
19476
+ "15": "n",
19477
+ "16": "n",
19478
+ "17": "n",
19479
+ "18": "n"
19480
+ },
19481
+ "ios_saf": {
19482
+ "3.2": "y",
19483
+ "4.0-4.1": "y",
19484
+ "4.2-4.3": "y",
19485
+ "5.0-5.1": "y",
19486
+ "6.0-6.1": "y",
19487
+ "7.0": "y"
19488
+ },
19489
+ "op_mini": {
19490
+ "5.0-7.0": "n"
19491
+ },
19492
+ "android": {
19493
+ "2.1": "a",
19494
+ "2.2": "a",
19495
+ "2.3": "a",
19496
+ "3": "a",
19497
+ "4": "a",
19498
+ "4.1": "a",
19499
+ "4.2-4.3": "a",
19500
+ "4.4": "y"
19501
+ },
19502
+ "bb": {
19503
+ "7": "y",
19504
+ "10": "y"
19505
+ },
19506
+ "op_mob": {
19507
+ "10": "n",
19508
+ "11": "y",
19509
+ "11.1": "y",
19510
+ "11.5": "y",
19511
+ "12": "y",
19512
+ "12.1": "y",
19513
+ "0": "y"
19514
+ },
19515
+ "and_chr": {
19516
+ "0": "y"
19517
+ },
19518
+ "and_ff": {
19519
+ "0": "a"
19520
+ },
19521
+ "ie_mob": {
19522
+ "10": "y"
19523
+ }
19524
+ },
19525
+ "notes": "The Android 2.3 browser currently requires <a href=\"http://www.broken-links.com/2010/07/08/making-html5-video-work-on-android-phones/\">specific handling</a> to play videos. Firefox <a href=\"http://blog.lizardwrangler.com/2012/03/18/video-user-experience-and-our-mission/\">will include support</a> on some platforms in upcoming versions. Firefox supports H.264 on Windows 7 and later since version 21. Partial support for Firefox refers to the lack of support in OSX & Linux platforms, for Android Firefox it refers to the inability of hardware acceleration.",
19526
+ "usage_perc_y": 59.55,
19527
+ "usage_perc_a": 18.1,
19528
+ "ucprefix": false,
19529
+ "parent": "video",
19530
+ "keywords": "avc,mp4,mpv,mov,aac"
19531
+ },
19532
+ "ogv": {
19533
+ "title": "Ogg/Theora video format",
19534
+ "description": "Free lossy video compression format.",
19535
+ "spec": "http://theora.org/doc/",
19536
+ "status": "other",
19537
+ "links": [{
19538
+ "url": "http://en.wikipedia.org/wiki/Theora",
19539
+ "title": "Wikipedia article"
19540
+ }],
19541
+ "categories": ["Other"],
19542
+ "stats": {
19543
+ "ie": {
19544
+ "5.5": "n",
19545
+ "6": "n",
19546
+ "7": "n",
19547
+ "8": "n",
19548
+ "9": "p",
19549
+ "10": "p",
19550
+ "11": "p"
19551
+ },
19552
+ "firefox": {
19553
+ "2": "n",
19554
+ "3": "n",
19555
+ "3.5": "y",
19556
+ "3.6": "y",
19557
+ "4": "y",
19558
+ "5": "y",
19559
+ "6": "y",
19560
+ "7": "y",
19561
+ "8": "y",
19562
+ "9": "y",
19563
+ "10": "y",
19564
+ "11": "y",
19565
+ "12": "y",
19566
+ "13": "y",
19567
+ "14": "y",
19568
+ "15": "y",
19569
+ "16": "y",
19570
+ "17": "y",
19571
+ "18": "y",
19572
+ "19": "y",
19573
+ "20": "y",
19574
+ "21": "y",
19575
+ "22": "y",
19576
+ "23": "y",
19577
+ "24": "y",
19578
+ "25": "y",
19579
+ "26": "y",
19580
+ "27": "y"
19581
+ },
19582
+ "chrome": {
19583
+ "4": "y",
19584
+ "5": "y",
19585
+ "6": "y",
19586
+ "7": "y",
19587
+ "8": "y",
19588
+ "9": "y",
19589
+ "10": "y",
19590
+ "11": "y",
19591
+ "12": "y",
19592
+ "13": "y",
19593
+ "14": "y",
19594
+ "15": "y",
19595
+ "16": "y",
19596
+ "17": "y",
19597
+ "18": "y",
19598
+ "19": "y",
19599
+ "20": "y",
19600
+ "21": "y",
19601
+ "22": "y",
19602
+ "23": "y",
19603
+ "24": "y",
19604
+ "25": "y",
19605
+ "26": "y",
19606
+ "27": "y",
19607
+ "28": "y",
19608
+ "29": "y",
19609
+ "30": "y",
19610
+ "31": "y",
19611
+ "32": "y"
19612
+ },
19613
+ "safari": {
19614
+ "3.1": "n",
19615
+ "3.2": "n",
19616
+ "4": "n",
19617
+ "5": "n",
19618
+ "5.1": "n",
19619
+ "6": "n",
19620
+ "6.1": "n",
19621
+ "7": "n"
19622
+ },
19623
+ "opera": {
19624
+ "9": "n",
19625
+ "9.5-9.6": "n",
19626
+ "10.0-10.1": "n",
19627
+ "10.5": "y",
19628
+ "10.6": "y",
19629
+ "11": "y",
19630
+ "11.1": "y",
19631
+ "11.5": "y",
19632
+ "11.6": "y",
19633
+ "12": "y",
19634
+ "12.1": "y",
19635
+ "15": "y",
19636
+ "16": "y",
19637
+ "17": "y",
19638
+ "18": "y"
19639
+ },
19640
+ "ios_saf": {
19641
+ "3.2": "n",
19642
+ "4.0-4.1": "n",
19643
+ "4.2-4.3": "n",
19644
+ "5.0-5.1": "n",
19645
+ "6.0-6.1": "n",
19646
+ "7.0": "n"
19647
+ },
19648
+ "op_mini": {
19649
+ "5.0-7.0": "n"
19650
+ },
19651
+ "android": {
19652
+ "2.1": "n",
19653
+ "2.2": "n",
19654
+ "2.3": "n",
19655
+ "3": "n",
19656
+ "4": "n",
19657
+ "4.1": "n",
19658
+ "4.2-4.3": "n",
19659
+ "4.4": "n"
19660
+ },
19661
+ "bb": {
19662
+ "7": "n",
19663
+ "10": "n"
19664
+ },
19665
+ "op_mob": {
19666
+ "10": "n",
19667
+ "11": "n",
19668
+ "11.1": "n",
19669
+ "11.5": "n",
19670
+ "12": "n",
19671
+ "12.1": "n",
19672
+ "0": "n"
19673
+ },
19674
+ "and_chr": {
19675
+ "0": "n"
19676
+ },
19677
+ "and_ff": {
19678
+ "0": "y"
19679
+ },
19680
+ "ie_mob": {
19681
+ "10": "p"
19682
+ }
19683
+ },
19684
+ "notes": "",
19685
+ "usage_perc_y": 49.8,
19686
+ "usage_perc_a": 0,
19687
+ "ucprefix": false,
19688
+ "parent": "video",
19689
+ "keywords": "xiph"
19690
+ },
19691
+ "wordwrap": {
19692
+ "title": "CSS3 Overflow-wrap",
19693
+ "description": "Allows lines to be broken within words if an otherwise unbreakable string is too long to fit.",
19694
+ "spec": "http://www.w3.org/TR/css3-text/#overflow-wrap",
19695
+ "status": "wd",
19696
+ "links": [{
19697
+ "url": "http://docs.webplatform.org/wiki/css/properties/word-wrap",
19698
+ "title": "WebPlatform Docs"
19699
+ }, {
19700
+ "url": "https://developer.mozilla.org/En/CSS/Word-wrap",
19701
+ "title": "MDN article"
19702
+ }, {
19703
+ "url": "http://www.css3files.com/text/#wordwrap",
19704
+ "title": "Information page"
19705
+ }],
19706
+ "categories": ["CSS3"],
19707
+ "stats": {
19708
+ "ie": {
19709
+ "5.5": "a",
19710
+ "6": "a",
19711
+ "7": "a",
19712
+ "8": "a",
19713
+ "9": "a",
19714
+ "10": "a",
19715
+ "11": "a"
19716
+ },
19717
+ "firefox": {
19718
+ "2": "n",
19719
+ "3": "n",
19720
+ "3.5": "a",
19721
+ "3.6": "a",
19722
+ "4": "a",
19723
+ "5": "a",
19724
+ "6": "a",
19725
+ "7": "a",
19726
+ "8": "a",
19727
+ "9": "a",
19728
+ "10": "a",
19729
+ "11": "a",
19730
+ "12": "a",
19731
+ "13": "a",
19732
+ "14": "a",
19733
+ "15": "a",
19734
+ "16": "a",
19735
+ "17": "a",
19736
+ "18": "a",
19737
+ "19": "a",
19738
+ "20": "a",
19739
+ "21": "a",
19740
+ "22": "a",
19741
+ "23": "a",
19742
+ "24": "a",
19743
+ "25": "a",
19744
+ "26": "a",
19745
+ "27": "a"
19746
+ },
19747
+ "chrome": {
19748
+ "4": "a",
19749
+ "5": "a",
19750
+ "6": "a",
19751
+ "7": "a",
19752
+ "8": "a",
19753
+ "9": "a",
19754
+ "10": "a",
19755
+ "11": "a",
19756
+ "12": "a",
19757
+ "13": "a",
19758
+ "14": "a",
19759
+ "15": "a",
19760
+ "16": "a",
19761
+ "17": "a",
19762
+ "18": "a",
19763
+ "19": "a",
19764
+ "20": "a",
19765
+ "21": "a",
19766
+ "22": "a",
19767
+ "23": "y",
19768
+ "24": "y",
19769
+ "25": "y",
19770
+ "26": "y",
19771
+ "27": "y",
19772
+ "28": "y",
19773
+ "29": "y",
19774
+ "30": "y",
19775
+ "31": "y",
19776
+ "32": "y"
19777
+ },
19778
+ "safari": {
19779
+ "3.1": "a",
19780
+ "3.2": "a",
19781
+ "4": "a",
19782
+ "5": "a",
19783
+ "5.1": "a",
19784
+ "6": "a",
19785
+ "6.1": "y",
19786
+ "7": "y"
19787
+ },
19788
+ "opera": {
19789
+ "9": "n",
19790
+ "9.5-9.6": "n",
19791
+ "10.0-10.1": "n",
19792
+ "10.5": "a",
19793
+ "10.6": "a",
19794
+ "11": "a",
19795
+ "11.1": "a",
19796
+ "11.5": "a",
19797
+ "11.6": "a",
19798
+ "12": "a",
19799
+ "12.1": "y",
19800
+ "15": "y",
19801
+ "16": "y",
19802
+ "17": "y",
19803
+ "18": "y"
19804
+ },
19805
+ "ios_saf": {
19806
+ "3.2": "a",
19807
+ "4.0-4.1": "a",
19808
+ "4.2-4.3": "a",
19809
+ "5.0-5.1": "a",
19810
+ "6.0-6.1": "a",
19811
+ "7.0": "y"
19812
+ },
19813
+ "op_mini": {
19814
+ "5.0-7.0": "a"
19815
+ },
19816
+ "android": {
19817
+ "2.1": "a",
19818
+ "2.2": "a",
19819
+ "2.3": "a",
19820
+ "3": "a",
19821
+ "4": "a",
19822
+ "4.1": "a",
19823
+ "4.2-4.3": "a",
19824
+ "4.4": "y"
19825
+ },
19826
+ "bb": {
19827
+ "7": "a",
19828
+ "10": "y"
19829
+ },
19830
+ "op_mob": {
19831
+ "10": "a",
19832
+ "11": "a",
19833
+ "11.1": "a",
19834
+ "11.5": "a",
19835
+ "12": "a",
19836
+ "12.1": "a",
19837
+ "0": "y"
19838
+ },
19839
+ "and_chr": {
19840
+ "0": "y"
19841
+ },
19842
+ "and_ff": {
19843
+ "0": "a"
19844
+ },
19845
+ "ie_mob": {
19846
+ "10": "a"
19847
+ }
19848
+ },
19849
+ "notes": "Partial support refers to requiring the legacy name \"word-wrap\" (rather than overflow-wrap) to work.",
19850
+ "usage_perc_y": 36.93,
19851
+ "usage_perc_a": 57.51,
19852
+ "ucprefix": false,
19853
+ "parent": "",
19854
+ "keywords": "wordwrap,word-wrap"
19855
+ },
19856
+ "progressmeter": {
19857
+ "title": "Progress & Meter",
19858
+ "description": "Method of indicating a progress state (progress element) or the current level of a gauge (meter element).\r\n",
19859
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-progress-element",
19860
+ "status": "wd",
19861
+ "links": [{
19862
+ "url": "http://dev.opera.com/articles/view/new-form-features-in-HTML5/#newoutput",
19863
+ "title": "Dev.Opera article"
19864
+ }, {
19865
+ "url": "http://peter.sh/examples/?/html/meter-progress.html",
19866
+ "title": "Examples of progress and meter elements"
19867
+ }, {
19868
+ "url": "http://docs.webplatform.org/wiki/html/elements/progress",
19869
+ "title": "WebPlatform Docs"
19870
+ }, {
19871
+ "url": "http://html5doctor.com/measure-up-with-the-meter-tag/",
19872
+ "title": "HTML5 Doctor on meter element "
19873
+ }],
19874
+ "categories": ["HTML5"],
19875
+ "stats": {
19876
+ "ie": {
19877
+ "5.5": "n",
19878
+ "6": "n",
19879
+ "7": "n",
19880
+ "8": "n",
19881
+ "9": "n",
19882
+ "10": "a",
19883
+ "11": "a"
19884
+ },
19885
+ "firefox": {
19886
+ "2": "n",
19887
+ "3": "n",
19888
+ "3.5": "n",
19889
+ "3.6": "n",
19890
+ "4": "n",
19891
+ "5": "n",
19892
+ "6": "a",
19893
+ "7": "a",
19894
+ "8": "a",
19895
+ "9": "a",
19896
+ "10": "a",
19897
+ "11": "a",
19898
+ "12": "a",
19899
+ "13": "a",
19900
+ "14": "a",
19901
+ "15": "a",
19902
+ "16": "y",
19903
+ "17": "y",
19904
+ "18": "y",
19905
+ "19": "y",
19906
+ "20": "y",
19907
+ "21": "y",
19908
+ "22": "y",
19909
+ "23": "y",
19910
+ "24": "y",
19911
+ "25": "y",
19912
+ "26": "y",
19913
+ "27": "y"
19914
+ },
19915
+ "chrome": {
19916
+ "4": "n",
19917
+ "5": "n",
19918
+ "6": "n",
19919
+ "7": "n",
19920
+ "8": "y",
19921
+ "9": "y",
19922
+ "10": "y",
19923
+ "11": "y",
19924
+ "12": "y",
19925
+ "13": "y",
19926
+ "14": "y",
19927
+ "15": "y",
19928
+ "16": "y",
19929
+ "17": "y",
19930
+ "18": "y",
19931
+ "19": "y",
19932
+ "20": "y",
19933
+ "21": "y",
19934
+ "22": "y",
19935
+ "23": "y",
19936
+ "24": "y",
19937
+ "25": "y",
19938
+ "26": "y",
19939
+ "27": "y",
19940
+ "28": "y",
19941
+ "29": "y",
19942
+ "30": "y",
19943
+ "31": "y",
19944
+ "32": "y"
19945
+ },
19946
+ "safari": {
19947
+ "3.1": "n",
19948
+ "3.2": "n",
19949
+ "4": "n",
19950
+ "5": "n",
19951
+ "5.1": "n",
19952
+ "6": "y",
19953
+ "6.1": "y",
19954
+ "7": "y"
19955
+ },
19956
+ "opera": {
19957
+ "9": "n",
19958
+ "9.5-9.6": "n",
19959
+ "10.0-10.1": "n",
19960
+ "10.5": "n",
19961
+ "10.6": "n",
19962
+ "11": "y",
19963
+ "11.1": "y",
19964
+ "11.5": "y",
19965
+ "11.6": "y",
19966
+ "12": "y",
19967
+ "12.1": "y",
19968
+ "15": "y",
19969
+ "16": "y",
19970
+ "17": "y",
19971
+ "18": "y"
19972
+ },
19973
+ "ios_saf": {
19974
+ "3.2": "n",
19975
+ "4.0-4.1": "n",
19976
+ "4.2-4.3": "n",
19977
+ "5.0-5.1": "n",
19978
+ "6.0-6.1": "n",
19979
+ "7.0": "a"
19980
+ },
19981
+ "op_mini": {
19982
+ "5.0-7.0": "n"
19983
+ },
19984
+ "android": {
19985
+ "2.1": "n",
19986
+ "2.2": "n",
19987
+ "2.3": "n",
19988
+ "3": "n",
19989
+ "4": "n",
19990
+ "4.1": "n",
19991
+ "4.2-4.3": "n",
19992
+ "4.4": "y"
19993
+ },
19994
+ "bb": {
19995
+ "7": "y",
19996
+ "10": "y"
19997
+ },
19998
+ "op_mob": {
19999
+ "10": "n",
20000
+ "11": "y",
20001
+ "11.1": "y",
20002
+ "11.5": "y",
20003
+ "12": "y",
20004
+ "12.1": "y",
20005
+ "0": "y"
20006
+ },
20007
+ "and_chr": {
20008
+ "0": "y"
20009
+ },
20010
+ "and_ff": {
20011
+ "0": "y"
20012
+ },
20013
+ "ie_mob": {
20014
+ "10": "a"
20015
+ }
20016
+ },
20017
+ "notes": "Partial support in Firefox 6-15, IE10 & iOS7 Safari refers to supporting the progress element, but not the meter element. iOS7 Safari also does not support \"indeterminate\" progress elements.",
20018
+ "usage_perc_y": 52.21,
20019
+ "usage_perc_a": 14.58,
20020
+ "ucprefix": false,
20021
+ "parent": "forms",
20022
+ "keywords": ""
20023
+ },
20024
+ "object-fit": {
20025
+ "title": "CSS3 object-fit/object-position",
20026
+ "description": "Method of specifying how an object (image or video) should fit inside its box. object-fit options include \"contain\" (fit according to aspect ratio), \"fill\" (stretches object to fill) and \"cover\" (overflows box but maintains ratio), where object-position allows the object to be repositioned like background-image does.",
20027
+ "spec": "http://www.w3.org/TR/css3-images/",
20028
+ "status": "cr",
20029
+ "links": [{
20030
+ "url": "http://dev.opera.com/articles/view/css3-object-fit-object-position/",
20031
+ "title": "Dev.Opera article"
20032
+ }, {
20033
+ "url": "http://docs.webplatform.org/wiki/css/properties/object-fit",
20034
+ "title": "WebPlatform Docs"
20035
+ }],
20036
+ "categories": ["CSS3"],
20037
+ "stats": {
20038
+ "ie": {
20039
+ "5.5": "n",
20040
+ "6": "n",
20041
+ "7": "n",
20042
+ "8": "n",
20043
+ "9": "n",
20044
+ "10": "n",
20045
+ "11": "n"
20046
+ },
20047
+ "firefox": {
20048
+ "2": "n",
20049
+ "3": "n",
20050
+ "3.5": "n",
20051
+ "3.6": "n",
20052
+ "4": "n",
20053
+ "5": "n",
20054
+ "6": "n",
20055
+ "7": "n",
20056
+ "8": "n",
20057
+ "9": "n",
20058
+ "10": "n",
20059
+ "11": "n",
20060
+ "12": "n",
20061
+ "13": "n",
20062
+ "14": "n",
20063
+ "15": "n",
20064
+ "16": "n",
20065
+ "17": "n",
20066
+ "18": "n",
20067
+ "19": "n",
20068
+ "20": "n",
20069
+ "21": "n",
20070
+ "22": "n",
20071
+ "23": "n",
20072
+ "24": "n",
20073
+ "25": "n",
20074
+ "26": "u",
20075
+ "27": "u"
20076
+ },
20077
+ "chrome": {
20078
+ "4": "n",
20079
+ "5": "n",
20080
+ "6": "n",
20081
+ "7": "n",
20082
+ "8": "n",
20083
+ "9": "n",
20084
+ "10": "n",
20085
+ "11": "n",
20086
+ "12": "n",
20087
+ "13": "n",
20088
+ "14": "n",
20089
+ "15": "n",
20090
+ "16": "n",
20091
+ "17": "n",
20092
+ "18": "n",
20093
+ "19": "n",
20094
+ "20": "n",
20095
+ "21": "n",
20096
+ "22": "n",
20097
+ "23": "n",
20098
+ "24": "n",
20099
+ "25": "n",
20100
+ "26": "n",
20101
+ "27": "n",
20102
+ "28": "n",
20103
+ "29": "n",
20104
+ "30": "n",
20105
+ "31": "n",
20106
+ "32": "y"
20107
+ },
20108
+ "safari": {
20109
+ "3.1": "n",
20110
+ "3.2": "n",
20111
+ "4": "n",
20112
+ "5": "n",
20113
+ "5.1": "n",
20114
+ "6": "n",
20115
+ "6.1": "u",
20116
+ "7": "u"
20117
+ },
20118
+ "opera": {
20119
+ "9": "n",
20120
+ "9.5-9.6": "n",
20121
+ "10.0-10.1": "n",
20122
+ "10.5": "n",
20123
+ "10.6": "y x",
20124
+ "11": "y x",
20125
+ "11.1": "y x",
20126
+ "11.5": "y x",
20127
+ "11.6": "y x",
20128
+ "12": "y x",
20129
+ "12.1": "y x",
20130
+ "15": "n",
20131
+ "16": "n",
20132
+ "17": "n",
20133
+ "18": "n"
20134
+ },
20135
+ "ios_saf": {
20136
+ "3.2": "n",
20137
+ "4.0-4.1": "n",
20138
+ "4.2-4.3": "n",
20139
+ "5.0-5.1": "n",
20140
+ "6.0-6.1": "n",
20141
+ "7.0": "n"
20142
+ },
20143
+ "op_mini": {
20144
+ "5.0-7.0": "n"
20145
+ },
20146
+ "android": {
20147
+ "2.1": "n",
20148
+ "2.2": "n",
20149
+ "2.3": "n",
20150
+ "3": "n",
20151
+ "4": "n",
20152
+ "4.1": "n",
20153
+ "4.2-4.3": "n",
20154
+ "4.4": "n"
20155
+ },
20156
+ "bb": {
20157
+ "7": "n",
20158
+ "10": "n"
20159
+ },
20160
+ "op_mob": {
20161
+ "10": "n",
20162
+ "11": "y x",
20163
+ "11.1": "y x",
20164
+ "11.5": "y x",
20165
+ "12": "y x",
20166
+ "12.1": "y x",
20167
+ "0": "n"
20168
+ },
20169
+ "and_chr": {
20170
+ "0": "n"
20171
+ },
20172
+ "and_ff": {
20173
+ "0": "n"
20174
+ },
20175
+ "ie_mob": {
20176
+ "10": "n"
20177
+ }
20178
+ },
20179
+ "notes": "Can be enabled in Chrome 31+ and Opera 18+ by enabling experimental Web Platform features under chrome://flags/ or opera://flags/.",
20180
+ "usage_perc_y": 0.81,
20181
+ "usage_perc_a": 0,
20182
+ "ucprefix": false,
20183
+ "parent": "",
20184
+ "keywords": "objectfit,objectposition"
20185
+ },
20186
+ "xhr2": {
20187
+ "title": "XMLHttpRequest 2",
20188
+ "description": "Adds more functionality to AJAX requests like file uploads, transfer progress information and the ability to send form data.",
20189
+ "spec": "http://www.w3.org/TR/XMLHttpRequest2/",
20190
+ "status": "wd",
20191
+ "links": [{
20192
+ "url": "http://docs.webplatform.org/wiki/apis/xhr/XMLHttpRequest",
20193
+ "title": "WebPlatform Docs"
20194
+ }, {
20195
+ "url": "http://www.profilepicture.co.uk/tutorials/ajax-file-upload-xmlhttprequest-level-2/",
20196
+ "title": "Article with file upload demo"
20197
+ }, {
20198
+ "url": "https://developer.mozilla.org/en/XMLHttpRequest/FormData",
20199
+ "title": "MDN article on FormData"
20200
+ }, {
20201
+ "url": "https://github.com/3nr1c/jUri.js",
20202
+ "title": "Polyfill for FormData object"
20203
+ }],
20204
+ "categories": ["DOM", "JS API"],
20205
+ "stats": {
20206
+ "ie": {
20207
+ "5.5": "n",
20208
+ "6": "n",
20209
+ "7": "n",
20210
+ "8": "n",
20211
+ "9": "n",
20212
+ "10": "y",
20213
+ "11": "y"
20214
+ },
20215
+ "firefox": {
20216
+ "2": "n",
20217
+ "3": "n",
20218
+ "3.5": "a",
20219
+ "3.6": "a",
20220
+ "4": "y",
20221
+ "5": "y",
20222
+ "6": "y",
20223
+ "7": "y",
20224
+ "8": "y",
20225
+ "9": "y",
20226
+ "10": "y",
20227
+ "11": "y",
20228
+ "12": "y",
20229
+ "13": "y",
20230
+ "14": "y",
20231
+ "15": "y",
20232
+ "16": "y",
20233
+ "17": "y",
20234
+ "18": "y",
20235
+ "19": "y",
20236
+ "20": "y",
20237
+ "21": "y",
20238
+ "22": "y",
20239
+ "23": "y",
20240
+ "24": "y",
20241
+ "25": "y",
20242
+ "26": "y",
20243
+ "27": "y"
20244
+ },
20245
+ "chrome": {
20246
+ "4": "u",
20247
+ "5": "u",
20248
+ "6": "u",
20249
+ "7": "y",
20250
+ "8": "y",
20251
+ "9": "y",
20252
+ "10": "y",
20253
+ "11": "y",
20254
+ "12": "y",
20255
+ "13": "y",
20256
+ "14": "y",
20257
+ "15": "y",
20258
+ "16": "y",
20259
+ "17": "y",
20260
+ "18": "y",
20261
+ "19": "y",
20262
+ "20": "y",
20263
+ "21": "y",
20264
+ "22": "y",
20265
+ "23": "y",
20266
+ "24": "y",
20267
+ "25": "y",
20268
+ "26": "y",
20269
+ "27": "y",
20270
+ "28": "y",
20271
+ "29": "y",
20272
+ "30": "y",
20273
+ "31": "y",
20274
+ "32": "y"
20275
+ },
20276
+ "safari": {
20277
+ "3.1": "n",
20278
+ "3.2": "n",
20279
+ "4": "n",
20280
+ "5": "y",
20281
+ "5.1": "y",
20282
+ "6": "y",
20283
+ "6.1": "y",
20284
+ "7": "y"
20285
+ },
20286
+ "opera": {
20287
+ "9": "n",
20288
+ "9.5-9.6": "n",
20289
+ "10.0-10.1": "n",
20290
+ "10.5": "n",
20291
+ "10.6": "n",
20292
+ "11": "n",
20293
+ "11.1": "n",
20294
+ "11.5": "n",
20295
+ "11.6": "n",
20296
+ "12": "y",
20297
+ "12.1": "y",
20298
+ "15": "y",
20299
+ "16": "y",
20300
+ "17": "y",
20301
+ "18": "y"
20302
+ },
20303
+ "ios_saf": {
20304
+ "3.2": "n",
20305
+ "4.0-4.1": "n",
20306
+ "4.2-4.3": "n",
20307
+ "5.0-5.1": "y",
20308
+ "6.0-6.1": "y",
20309
+ "7.0": "y"
20310
+ },
20311
+ "op_mini": {
20312
+ "5.0-7.0": "n"
20313
+ },
20314
+ "android": {
20315
+ "2.1": "n",
20316
+ "2.2": "n",
20317
+ "2.3": "n",
20318
+ "3": "y",
20319
+ "4": "y",
20320
+ "4.1": "y",
20321
+ "4.2-4.3": "y",
20322
+ "4.4": "y"
20323
+ },
20324
+ "bb": {
20325
+ "7": "y",
20326
+ "10": "y"
20327
+ },
20328
+ "op_mob": {
20329
+ "10": "n",
20330
+ "11": "n",
20331
+ "11.1": "n",
20332
+ "11.5": "n",
20333
+ "12": "y",
20334
+ "12.1": "y",
20335
+ "0": "y"
20336
+ },
20337
+ "and_chr": {
20338
+ "0": "y"
20339
+ },
20340
+ "and_ff": {
20341
+ "0": "y"
20342
+ },
20343
+ "ie_mob": {
20344
+ "10": "y"
20345
+ }
20346
+ },
20347
+ "notes": "",
20348
+ "usage_perc_y": 73.51,
20349
+ "usage_perc_a": 0.35,
20350
+ "ucprefix": false,
20351
+ "parent": "",
20352
+ "keywords": "formdata"
20353
+ },
20354
+ "minmaxwh": {
20355
+ "title": "CSS min/max-width/height",
20356
+ "description": "Method of setting a minimum or maximum width or height to an element. ",
20357
+ "spec": "http://www.w3.org/TR/CSS21/visudet.html#min-max-widths",
20358
+ "status": "rec",
20359
+ "links": [{
20360
+ "url": "http://docs.webplatform.org/wiki/css/properties/min-width",
20361
+ "title": "WebPlatform Docs"
20362
+ }, {
20363
+ "url": "http://code.google.com/p/ie7-js/",
20364
+ "title": "JS library with support"
20365
+ }, {
20366
+ "url": "http://www.impressivewebs.com/min-max-width-height-css/",
20367
+ "title": "CSS Basics post"
20368
+ }],
20369
+ "categories": ["CSS2"],
20370
+ "stats": {
20371
+ "ie": {
20372
+ "5.5": "p",
20373
+ "6": "p",
20374
+ "7": "y",
20375
+ "8": "y",
20376
+ "9": "y",
20377
+ "10": "y",
20378
+ "11": "y"
20379
+ },
20380
+ "firefox": {
20381
+ "2": "y",
20382
+ "3": "y",
20383
+ "3.5": "y",
20384
+ "3.6": "y",
20385
+ "4": "y",
20386
+ "5": "y",
20387
+ "6": "y",
20388
+ "7": "y",
20389
+ "8": "y",
20390
+ "9": "y",
20391
+ "10": "y",
20392
+ "11": "y",
20393
+ "12": "y",
20394
+ "13": "y",
20395
+ "14": "y",
20396
+ "15": "y",
20397
+ "16": "y",
20398
+ "17": "y",
20399
+ "18": "y",
20400
+ "19": "y",
20401
+ "20": "y",
20402
+ "21": "y",
20403
+ "22": "y",
20404
+ "23": "y",
20405
+ "24": "y",
20406
+ "25": "y",
20407
+ "26": "y",
20408
+ "27": "y"
20409
+ },
20410
+ "chrome": {
20411
+ "4": "y",
20412
+ "5": "y",
20413
+ "6": "y",
20414
+ "7": "y",
20415
+ "8": "y",
20416
+ "9": "y",
20417
+ "10": "y",
20418
+ "11": "y",
20419
+ "12": "y",
20420
+ "13": "y",
20421
+ "14": "y",
20422
+ "15": "y",
20423
+ "16": "y",
20424
+ "17": "y",
20425
+ "18": "y",
20426
+ "19": "y",
20427
+ "20": "y",
20428
+ "21": "y",
20429
+ "22": "y",
20430
+ "23": "y",
20431
+ "24": "y",
20432
+ "25": "y",
20433
+ "26": "y",
20434
+ "27": "y",
20435
+ "28": "y",
20436
+ "29": "y",
20437
+ "30": "y",
20438
+ "31": "y",
20439
+ "32": "y"
20440
+ },
20441
+ "safari": {
20442
+ "3.1": "y",
20443
+ "3.2": "y",
20444
+ "4": "y",
20445
+ "5": "y",
20446
+ "5.1": "y",
20447
+ "6": "y",
20448
+ "6.1": "y",
20449
+ "7": "y"
20450
+ },
20451
+ "opera": {
20452
+ "9": "y",
20453
+ "9.5-9.6": "y",
20454
+ "10.0-10.1": "y",
20455
+ "10.5": "y",
20456
+ "10.6": "y",
20457
+ "11": "y",
20458
+ "11.1": "y",
20459
+ "11.5": "y",
20460
+ "11.6": "y",
20461
+ "12": "y",
20462
+ "12.1": "y",
20463
+ "15": "y",
20464
+ "16": "y",
20465
+ "17": "y",
20466
+ "18": "y"
20467
+ },
20468
+ "ios_saf": {
20469
+ "3.2": "y",
20470
+ "4.0-4.1": "y",
20471
+ "4.2-4.3": "y",
20472
+ "5.0-5.1": "y",
20473
+ "6.0-6.1": "y",
20474
+ "7.0": "y"
20475
+ },
20476
+ "op_mini": {
20477
+ "5.0-7.0": "y"
20478
+ },
20479
+ "android": {
20480
+ "2.1": "y",
20481
+ "2.2": "y",
20482
+ "2.3": "y",
20483
+ "3": "y",
20484
+ "4": "y",
20485
+ "4.1": "y",
20486
+ "4.2-4.3": "y",
20487
+ "4.4": "y"
20488
+ },
20489
+ "bb": {
20490
+ "7": "y",
20491
+ "10": "y"
20492
+ },
20493
+ "op_mob": {
20494
+ "10": "y",
20495
+ "11": "y",
20496
+ "11.1": "y",
20497
+ "11.5": "y",
20498
+ "12": "y",
20499
+ "12.1": "y",
20500
+ "0": "y"
20501
+ },
20502
+ "and_chr": {
20503
+ "0": "y"
20504
+ },
20505
+ "and_ff": {
20506
+ "0": "y"
20507
+ },
20508
+ "ie_mob": {
20509
+ "10": "y"
20510
+ }
20511
+ },
20512
+ "notes": "IE7 does not support \"inherit\" as a value on any of these properties. IE8 has some bugs with max-width/height combined with overflow: auto/scroll.",
20513
+ "usage_perc_y": 94.36,
20514
+ "usage_perc_a": 0,
20515
+ "ucprefix": false,
20516
+ "parent": "",
20517
+ "keywords": "min-width,min-height,max-width,max-height"
20518
+ },
20519
+ "details": {
20520
+ "title": "Details & Summary elements",
20521
+ "description": "The &lt;details> element generates a simple no-JavaScript widget to show/hide element contents, optionally by clicking on its child &lt;summary> element.",
20522
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#the-details-element",
20523
+ "status": "wd",
20524
+ "links": [{
20525
+ "url": "http://html5doctor.com/summary-figcaption-element/",
20526
+ "title": "HTML5 Doctor article"
20527
+ }, {
20528
+ "url": "http://mathiasbynens.be/notes/html5-details-jquery",
20529
+ "title": "jQuery fallback script"
20530
+ }, {
20531
+ "url": "http://docs.webplatform.org/wiki/html/elements/details",
20532
+ "title": "WebPlatform Docs"
20533
+ }, {
20534
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-details",
20535
+ "title": "has.js test"
20536
+ }, {
20537
+ "url": "https://gist.github.com/370590",
20538
+ "title": "Fallback script"
20539
+ }],
20540
+ "categories": ["HTML5"],
20541
+ "stats": {
20542
+ "ie": {
20543
+ "5.5": "n",
20544
+ "6": "p",
20545
+ "7": "p",
20546
+ "8": "p",
20547
+ "9": "n",
20548
+ "10": "n",
20549
+ "11": "n"
20550
+ },
20551
+ "firefox": {
20552
+ "2": "n",
20553
+ "3": "p",
20554
+ "3.5": "p",
20555
+ "3.6": "p",
20556
+ "4": "p",
20557
+ "5": "p",
20558
+ "6": "p",
20559
+ "7": "p",
20560
+ "8": "p",
20561
+ "9": "p",
20562
+ "10": "p",
20563
+ "11": "p",
20564
+ "12": "p",
20565
+ "13": "p",
20566
+ "14": "p",
20567
+ "15": "p",
20568
+ "16": "p",
20569
+ "17": "p",
20570
+ "18": "p",
20571
+ "19": "p",
20572
+ "20": "p",
20573
+ "21": "p",
20574
+ "22": "p",
20575
+ "23": "p",
20576
+ "24": "p",
20577
+ "25": "p",
20578
+ "26": "p",
20579
+ "27": "p"
20580
+ },
20581
+ "chrome": {
20582
+ "4": "p",
20583
+ "5": "p",
20584
+ "6": "p",
20585
+ "7": "p",
20586
+ "8": "p",
20587
+ "9": "p",
20588
+ "10": "p",
20589
+ "11": "p",
20590
+ "12": "y",
20591
+ "13": "y",
20592
+ "14": "y",
20593
+ "15": "y",
20594
+ "16": "y",
20595
+ "17": "y",
20596
+ "18": "y",
20597
+ "19": "y",
20598
+ "20": "y",
20599
+ "21": "y",
20600
+ "22": "y",
20601
+ "23": "y",
20602
+ "24": "y",
20603
+ "25": "y",
20604
+ "26": "y",
20605
+ "27": "y",
20606
+ "28": "y",
20607
+ "29": "y",
20608
+ "30": "y",
20609
+ "31": "y",
20610
+ "32": "y"
20611
+ },
20612
+ "safari": {
20613
+ "3.1": "p",
20614
+ "3.2": "p",
20615
+ "4": "p",
20616
+ "5": "p",
20617
+ "5.1": "p",
20618
+ "6": "y",
20619
+ "6.1": "y",
20620
+ "7": "y"
20621
+ },
20622
+ "opera": {
20623
+ "9": "p",
20624
+ "9.5-9.6": "p",
20625
+ "10.0-10.1": "p",
20626
+ "10.5": "p",
20627
+ "10.6": "p",
20628
+ "11": "p",
20629
+ "11.1": "n",
20630
+ "11.5": "n",
20631
+ "11.6": "n",
20632
+ "12": "n",
20633
+ "12.1": "n",
20634
+ "15": "y",
20635
+ "16": "y",
20636
+ "17": "y",
20637
+ "18": "y"
20638
+ },
20639
+ "ios_saf": {
20640
+ "3.2": "p",
20641
+ "4.0-4.1": "p",
20642
+ "4.2-4.3": "p",
20643
+ "5.0-5.1": "p",
20644
+ "6.0-6.1": "y",
20645
+ "7.0": "y"
20646
+ },
20647
+ "op_mini": {
20648
+ "5.0-7.0": "p"
20649
+ },
20650
+ "android": {
20651
+ "2.1": "p",
20652
+ "2.2": "p",
20653
+ "2.3": "p",
20654
+ "3": "p",
20655
+ "4": "y",
20656
+ "4.1": "y",
20657
+ "4.2-4.3": "y",
20658
+ "4.4": "y"
20659
+ },
20660
+ "bb": {
20661
+ "7": "p",
20662
+ "10": "y"
20663
+ },
20664
+ "op_mob": {
20665
+ "10": "p",
20666
+ "11": "p",
20667
+ "11.1": "p",
20668
+ "11.5": "p",
20669
+ "12": "p",
20670
+ "12.1": "p",
20671
+ "0": "y"
20672
+ },
20673
+ "and_chr": {
20674
+ "0": "y"
20675
+ },
20676
+ "and_ff": {
20677
+ "0": "n"
20678
+ },
20679
+ "ie_mob": {
20680
+ "10": "n"
20681
+ }
20682
+ },
20683
+ "notes": "",
20684
+ "usage_perc_y": 44.5,
20685
+ "usage_perc_a": 0,
20686
+ "ucprefix": false,
20687
+ "parent": "",
20688
+ "keywords": ""
20689
+ },
20690
+ "text-stroke": {
20691
+ "title": "CSS text-stroke",
20692
+ "description": "Method of declaring the outline (stroke) width and color for text.",
20693
+ "spec": "http://developer.apple.com/library/safari/documentation/appleapplications/reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266-_webkit_text_stroke",
20694
+ "status": "unoff",
20695
+ "links": [{
20696
+ "url": "http://www.westciv.com/tools/textStroke/",
20697
+ "title": "Live editor"
20698
+ }, {
20699
+ "url": "http://css-tricks.com/7405-adding-stroke-to-web-text/",
20700
+ "title": "Information & workarounds"
20701
+ }],
20702
+ "categories": ["CSS"],
20703
+ "stats": {
20704
+ "ie": {
20705
+ "5.5": "n",
20706
+ "6": "n",
20707
+ "7": "n",
20708
+ "8": "n",
20709
+ "9": "n",
20710
+ "10": "n",
20711
+ "11": "n"
20712
+ },
20713
+ "firefox": {
20714
+ "2": "n",
20715
+ "3": "n",
20716
+ "3.5": "n",
20717
+ "3.6": "n",
20718
+ "4": "n",
20719
+ "5": "n",
20720
+ "6": "n",
20721
+ "7": "n",
20722
+ "8": "n",
20723
+ "9": "n",
20724
+ "10": "n",
20725
+ "11": "n",
20726
+ "12": "n",
20727
+ "13": "n",
20728
+ "14": "n",
20729
+ "15": "n",
20730
+ "16": "n",
20731
+ "17": "n",
20732
+ "18": "n",
20733
+ "19": "n",
20734
+ "20": "n",
20735
+ "21": "n",
20736
+ "22": "n",
20737
+ "23": "n",
20738
+ "24": "n",
20739
+ "25": "n",
20740
+ "26": "u",
20741
+ "27": "u"
20742
+ },
20743
+ "chrome": {
20744
+ "4": "y x",
20745
+ "5": "y x",
20746
+ "6": "y x",
20747
+ "7": "y x",
20748
+ "8": "y x",
20749
+ "9": "y x",
20750
+ "10": "y x",
20751
+ "11": "y x",
20752
+ "12": "y x",
20753
+ "13": "y x",
20754
+ "14": "y x",
20755
+ "15": "y x",
20756
+ "16": "y x",
20757
+ "17": "y x",
20758
+ "18": "y x",
20759
+ "19": "y x",
20760
+ "20": "y x",
20761
+ "21": "y x",
20762
+ "22": "y x",
20763
+ "23": "y x",
20764
+ "24": "y x",
20765
+ "25": "y x",
20766
+ "26": "y x",
20767
+ "27": "y x",
20768
+ "28": "y x",
20769
+ "29": "y x",
20770
+ "30": "y x",
20771
+ "31": "y x",
20772
+ "32": "y x"
20773
+ },
20774
+ "safari": {
20775
+ "3.1": "y x",
20776
+ "3.2": "y x",
20777
+ "4": "y x",
20778
+ "5": "y x",
20779
+ "5.1": "y x",
20780
+ "6": "y x",
20781
+ "6.1": "y x",
20782
+ "7": "y x"
20783
+ },
20784
+ "opera": {
20785
+ "9": "n",
20786
+ "9.5-9.6": "n",
20787
+ "10.0-10.1": "n",
20788
+ "10.5": "n",
20789
+ "10.6": "n",
20790
+ "11": "n",
20791
+ "11.1": "n",
20792
+ "11.5": "n",
20793
+ "11.6": "n",
20794
+ "12": "n",
20795
+ "12.1": "n",
20796
+ "15": "y x",
20797
+ "16": "y x",
20798
+ "17": "y x",
20799
+ "18": "y x"
20800
+ },
20801
+ "ios_saf": {
20802
+ "3.2": "a x",
20803
+ "4.0-4.1": "y x",
20804
+ "4.2-4.3": "y x",
20805
+ "5.0-5.1": "y x",
20806
+ "6.0-6.1": "y x",
20807
+ "7.0": "y x"
20808
+ },
20809
+ "op_mini": {
20810
+ "5.0-7.0": "n"
20811
+ },
20812
+ "android": {
20813
+ "2.1": "y x",
20814
+ "2.2": "y x",
20815
+ "2.3": "y x",
20816
+ "3": "n",
20817
+ "4": "y x",
20818
+ "4.1": "y x",
20819
+ "4.2-4.3": "y x",
20820
+ "4.4": "y x"
20821
+ },
20822
+ "bb": {
20823
+ "7": "y x",
20824
+ "10": "y x"
20825
+ },
20826
+ "op_mob": {
20827
+ "10": "n",
20828
+ "11": "n",
20829
+ "11.1": "n",
20830
+ "11.5": "n",
20831
+ "12": "n",
20832
+ "12.1": "n",
20833
+ "0": "y x"
20834
+ },
20835
+ "and_chr": {
20836
+ "0": "y x"
20837
+ },
20838
+ "and_ff": {
20839
+ "0": "n"
20840
+ },
20841
+ "ie_mob": {
20842
+ "10": "n"
20843
+ }
20844
+ },
20845
+ "notes": "Does not yet appear in any W3C specification. Was briefly included in a spec as the \"text-outline\" property, but this was removed.",
20846
+ "usage_perc_y": 48.41,
20847
+ "usage_perc_a": 0,
20848
+ "ucprefix": false,
20849
+ "parent": "",
20850
+ "keywords": "textstroke,stroke-color,stroke-width,fill-color"
20851
+ },
20852
+ "inline-block": {
20853
+ "title": "CSS inline-block",
20854
+ "description": "Method of displaying an element as a block while flowing it with text. ",
20855
+ "spec": "http://www.w3.org/TR/CSS21/visuren.html#fixed-positioning",
20856
+ "status": "rec",
20857
+ "links": [{
20858
+ "url": "http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/",
20859
+ "title": "Blog post w/info"
20860
+ }, {
20861
+ "url": "http://docs.webplatform.org/wiki/css/properties/display",
20862
+ "title": "WebPlatform Docs"
20863
+ }, {
20864
+ "url": "http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/",
20865
+ "title": "Info on cross browser support"
20866
+ }],
20867
+ "categories": ["CSS2"],
20868
+ "stats": {
20869
+ "ie": {
20870
+ "5.5": "a",
20871
+ "6": "a",
20872
+ "7": "a",
20873
+ "8": "y",
20874
+ "9": "y",
20875
+ "10": "y",
20876
+ "11": "y"
20877
+ },
20878
+ "firefox": {
20879
+ "2": "a x",
20880
+ "3": "y",
20881
+ "3.5": "y",
20882
+ "3.6": "y",
20883
+ "4": "y",
20884
+ "5": "y",
20885
+ "6": "y",
20886
+ "7": "y",
20887
+ "8": "y",
20888
+ "9": "y",
20889
+ "10": "y",
20890
+ "11": "y",
20891
+ "12": "y",
20892
+ "13": "y",
20893
+ "14": "y",
20894
+ "15": "y",
20895
+ "16": "y",
20896
+ "17": "y",
20897
+ "18": "y",
20898
+ "19": "y",
20899
+ "20": "y",
20900
+ "21": "y",
20901
+ "22": "y",
20902
+ "23": "y",
20903
+ "24": "y",
20904
+ "25": "y",
20905
+ "26": "y",
20906
+ "27": "y"
20907
+ },
20908
+ "chrome": {
20909
+ "4": "y",
20910
+ "5": "y",
20911
+ "6": "y",
20912
+ "7": "y",
20913
+ "8": "y",
20914
+ "9": "y",
20915
+ "10": "y",
20916
+ "11": "y",
20917
+ "12": "y",
20918
+ "13": "y",
20919
+ "14": "y",
20920
+ "15": "y",
20921
+ "16": "y",
20922
+ "17": "y",
20923
+ "18": "y",
20924
+ "19": "y",
20925
+ "20": "y",
20926
+ "21": "y",
20927
+ "22": "y",
20928
+ "23": "y",
20929
+ "24": "y",
20930
+ "25": "y",
20931
+ "26": "y",
20932
+ "27": "y",
20933
+ "28": "y",
20934
+ "29": "y",
20935
+ "30": "y",
20936
+ "31": "y",
20937
+ "32": "y"
20938
+ },
20939
+ "safari": {
20940
+ "3.1": "y",
20941
+ "3.2": "y",
20942
+ "4": "y",
20943
+ "5": "y",
20944
+ "5.1": "y",
20945
+ "6": "y",
20946
+ "6.1": "y",
20947
+ "7": "y"
20948
+ },
20949
+ "opera": {
20950
+ "9": "y",
20951
+ "9.5-9.6": "y",
20952
+ "10.0-10.1": "y",
20953
+ "10.5": "y",
20954
+ "10.6": "y",
20955
+ "11": "y",
20956
+ "11.1": "y",
20957
+ "11.5": "y",
20958
+ "11.6": "y",
20959
+ "12": "y",
20960
+ "12.1": "y",
20961
+ "15": "y",
20962
+ "16": "y",
20963
+ "17": "y",
20964
+ "18": "y"
20965
+ },
20966
+ "ios_saf": {
20967
+ "3.2": "y",
20968
+ "4.0-4.1": "y",
20969
+ "4.2-4.3": "y",
20970
+ "5.0-5.1": "y",
20971
+ "6.0-6.1": "y",
20972
+ "7.0": "y"
20973
+ },
20974
+ "op_mini": {
20975
+ "5.0-7.0": "y"
20976
+ },
20977
+ "android": {
20978
+ "2.1": "y",
20979
+ "2.2": "y",
20980
+ "2.3": "y",
20981
+ "3": "y",
20982
+ "4": "y",
20983
+ "4.1": "y",
20984
+ "4.2-4.3": "y",
20985
+ "4.4": "y"
20986
+ },
20987
+ "bb": {
20988
+ "7": "y",
20989
+ "10": "y"
20990
+ },
20991
+ "op_mob": {
20992
+ "10": "y",
20993
+ "11": "y",
20994
+ "11.1": "y",
20995
+ "11.5": "y",
20996
+ "12": "y",
20997
+ "12.1": "y",
20998
+ "0": "y"
20999
+ },
21000
+ "and_chr": {
21001
+ "0": "y"
21002
+ },
21003
+ "and_ff": {
21004
+ "0": "y"
21005
+ },
21006
+ "ie_mob": {
21007
+ "10": "y"
21008
+ }
21009
+ },
21010
+ "notes": "Only supported in IE6 and IE7 on elements with a display of \"inline\" by default. <a href=\"http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/\">Alternative properties</a> are available to provide complete cross-browser support.",
21011
+ "usage_perc_y": 93.84,
21012
+ "usage_perc_a": 0.74,
21013
+ "ucprefix": false,
21014
+ "parent": "",
21015
+ "keywords": "inlineblock"
21016
+ },
21017
+ "notifications": {
21018
+ "title": "Web Notifications",
21019
+ "description": "Method of alerting the user outside of a web page by displaying notifications (that do not require interaction by the user).",
21020
+ "spec": "http://www.w3.org/TR/notifications/",
21021
+ "status": "wd",
21022
+ "links": [{
21023
+ "url": "http://www.html5rocks.com/tutorials/notifications/quick/",
21024
+ "title": "HTML5 Rocks tutorial"
21025
+ }, {
21026
+ "url": "http://www.chromium.org/developers/design-documents/desktop-notifications/api-specification",
21027
+ "title": "Chromium API"
21028
+ }, {
21029
+ "url": "https://addons.mozilla.org/en-us/firefox/addon/221523/",
21030
+ "title": "Add-on "
21031
+ }],
21032
+ "categories": ["JS API"],
21033
+ "stats": {
21034
+ "ie": {
21035
+ "5.5": "n",
21036
+ "6": "n",
21037
+ "7": "n",
21038
+ "8": "n",
21039
+ "9": "n",
21040
+ "10": "n",
21041
+ "11": "n"
21042
+ },
21043
+ "firefox": {
21044
+ "2": "n",
21045
+ "3": "n",
21046
+ "3.5": "n",
21047
+ "3.6": "n",
21048
+ "4": "n",
21049
+ "5": "n",
21050
+ "6": "n",
21051
+ "7": "n",
21052
+ "8": "n",
21053
+ "9": "n",
21054
+ "10": "n",
21055
+ "11": "n",
21056
+ "12": "n",
21057
+ "13": "n",
21058
+ "14": "n",
21059
+ "15": "n",
21060
+ "16": "n",
21061
+ "17": "n",
21062
+ "18": "n",
21063
+ "19": "n",
21064
+ "20": "n",
21065
+ "21": "n",
21066
+ "22": "y",
21067
+ "23": "y",
21068
+ "24": "y",
21069
+ "25": "y",
21070
+ "26": "y",
21071
+ "27": "y"
21072
+ },
21073
+ "chrome": {
21074
+ "4": "n",
21075
+ "5": "a x",
21076
+ "6": "a x",
21077
+ "7": "a x",
21078
+ "8": "a x",
21079
+ "9": "a x",
21080
+ "10": "a x",
21081
+ "11": "a x",
21082
+ "12": "a x",
21083
+ "13": "a x",
21084
+ "14": "a x",
21085
+ "15": "a x",
21086
+ "16": "a x",
21087
+ "17": "a x",
21088
+ "18": "a x",
21089
+ "19": "a x",
21090
+ "20": "a x",
21091
+ "21": "a x",
21092
+ "22": "y",
21093
+ "23": "y",
21094
+ "24": "y",
21095
+ "25": "y",
21096
+ "26": "y",
21097
+ "27": "y",
21098
+ "28": "y",
21099
+ "29": "y",
21100
+ "30": "y",
21101
+ "31": "y",
21102
+ "32": "y"
21103
+ },
21104
+ "safari": {
21105
+ "3.1": "n",
21106
+ "3.2": "n",
21107
+ "4": "n",
21108
+ "5": "n",
21109
+ "5.1": "n",
21110
+ "6": "n",
21111
+ "6.1": "n",
21112
+ "7": "y"
21113
+ },
21114
+ "opera": {
21115
+ "9": "n",
21116
+ "9.5-9.6": "n",
21117
+ "10.0-10.1": "n",
21118
+ "10.5": "n",
21119
+ "10.6": "n",
21120
+ "11": "n",
21121
+ "11.1": "n",
21122
+ "11.5": "n",
21123
+ "11.6": "n",
21124
+ "12": "n",
21125
+ "12.1": "n",
21126
+ "15": "n",
21127
+ "16": "n",
21128
+ "17": "n",
21129
+ "18": "n"
21130
+ },
21131
+ "ios_saf": {
21132
+ "3.2": "n",
21133
+ "4.0-4.1": "n",
21134
+ "4.2-4.3": "n",
21135
+ "5.0-5.1": "n",
21136
+ "6.0-6.1": "n",
21137
+ "7.0": "n"
21138
+ },
21139
+ "op_mini": {
21140
+ "5.0-7.0": "n"
21141
+ },
21142
+ "android": {
21143
+ "2.1": "n",
21144
+ "2.2": "n",
21145
+ "2.3": "n",
21146
+ "3": "n",
21147
+ "4": "n",
21148
+ "4.1": "n",
21149
+ "4.2-4.3": "n",
21150
+ "4.4": "a x"
21151
+ },
21152
+ "bb": {
21153
+ "7": "n",
21154
+ "10": "y"
21155
+ },
21156
+ "op_mob": {
21157
+ "10": "n",
21158
+ "11": "n",
21159
+ "11.1": "n",
21160
+ "11.5": "n",
21161
+ "12": "n",
21162
+ "12.1": "n",
21163
+ "0": "a x"
21164
+ },
21165
+ "and_chr": {
21166
+ "0": "a x"
21167
+ },
21168
+ "and_ff": {
21169
+ "0": "y"
21170
+ },
21171
+ "ie_mob": {
21172
+ "10": "n"
21173
+ }
21174
+ },
21175
+ "notes": "",
21176
+ "usage_perc_y": 45.27,
21177
+ "usage_perc_a": 2.66,
21178
+ "ucprefix": false,
21179
+ "parent": "",
21180
+ "keywords": ""
21181
+ },
21182
+ "stream": {
21183
+ "title": "getUserMedia/Stream API",
21184
+ "description": "Method of accessing external device data (such as a webcam video stream). Formerly this was envisioned as the &lt;device> element.",
21185
+ "spec": "http://www.w3.org/TR/mediacapture-streams/",
21186
+ "status": "wd",
21187
+ "links": [{
21188
+ "url": "http://my.opera.com/core/blog/2011/03/23/webcam-orientation-preview",
21189
+ "title": "Technology preview from Opera"
21190
+ }, {
21191
+ "url": "http://docs.webplatform.org/wiki/dom/methods/getUserMedia",
21192
+ "title": "WebPlatform Docs"
21193
+ }],
21194
+ "categories": ["HTML5", "JS API"],
21195
+ "stats": {
21196
+ "ie": {
21197
+ "5.5": "n",
21198
+ "6": "n",
21199
+ "7": "n",
21200
+ "8": "n",
21201
+ "9": "n",
21202
+ "10": "n",
21203
+ "11": "n"
21204
+ },
21205
+ "firefox": {
21206
+ "2": "n",
21207
+ "3": "n",
21208
+ "3.5": "n",
21209
+ "3.6": "n",
21210
+ "4": "n",
21211
+ "5": "n",
21212
+ "6": "n",
21213
+ "7": "n",
21214
+ "8": "n",
21215
+ "9": "n",
21216
+ "10": "n",
21217
+ "11": "n",
21218
+ "12": "n",
21219
+ "13": "n",
21220
+ "14": "n",
21221
+ "15": "n",
21222
+ "16": "n",
21223
+ "17": "y x",
21224
+ "18": "y x",
21225
+ "19": "y x",
21226
+ "20": "y x",
21227
+ "21": "y x",
21228
+ "22": "y x",
21229
+ "23": "y x",
21230
+ "24": "y x",
21231
+ "25": "y x",
21232
+ "26": "y x",
21233
+ "27": "y x"
21234
+ },
21235
+ "chrome": {
21236
+ "4": "n",
21237
+ "5": "n",
21238
+ "6": "n",
21239
+ "7": "n",
21240
+ "8": "n",
21241
+ "9": "n",
21242
+ "10": "n",
21243
+ "11": "n",
21244
+ "12": "n",
21245
+ "13": "n",
21246
+ "14": "n",
21247
+ "15": "n",
21248
+ "16": "n",
21249
+ "17": "n",
21250
+ "18": "n",
21251
+ "19": "n",
21252
+ "20": "n",
21253
+ "21": "y x",
21254
+ "22": "y x",
21255
+ "23": "y x",
21256
+ "24": "y x",
21257
+ "25": "y x",
21258
+ "26": "y x",
21259
+ "27": "y x",
21260
+ "28": "y x",
21261
+ "29": "y x",
21262
+ "30": "y x",
21263
+ "31": "y x",
21264
+ "32": "y x"
21265
+ },
21266
+ "safari": {
21267
+ "3.1": "n",
21268
+ "3.2": "n",
21269
+ "4": "n",
21270
+ "5": "n",
21271
+ "5.1": "n",
21272
+ "6": "n",
21273
+ "6.1": "u",
21274
+ "7": "u"
21275
+ },
21276
+ "opera": {
21277
+ "9": "n",
21278
+ "9.5-9.6": "n",
21279
+ "10.0-10.1": "n",
21280
+ "10.5": "n",
21281
+ "10.6": "n",
21282
+ "11": "n",
21283
+ "11.1": "n",
21284
+ "11.5": "n",
21285
+ "11.6": "n",
21286
+ "12": "y",
21287
+ "12.1": "y",
21288
+ "15": "n",
21289
+ "16": "n",
21290
+ "17": "n",
21291
+ "18": "y x"
21292
+ },
21293
+ "ios_saf": {
21294
+ "3.2": "n",
21295
+ "4.0-4.1": "n",
21296
+ "4.2-4.3": "n",
21297
+ "5.0-5.1": "n",
21298
+ "6.0-6.1": "n",
21299
+ "7.0": "n"
21300
+ },
21301
+ "op_mini": {
21302
+ "5.0-7.0": "n"
21303
+ },
21304
+ "android": {
21305
+ "2.1": "n",
21306
+ "2.2": "n",
21307
+ "2.3": "n",
21308
+ "3": "n",
21309
+ "4": "n",
21310
+ "4.1": "n",
21311
+ "4.2-4.3": "n",
21312
+ "4.4": "y"
21313
+ },
21314
+ "bb": {
21315
+ "7": "n",
21316
+ "10": "y x"
21317
+ },
21318
+ "op_mob": {
21319
+ "10": "n",
21320
+ "11": "n",
21321
+ "11.1": "n",
21322
+ "11.5": "n",
21323
+ "12": "y",
21324
+ "12.1": "y",
21325
+ "0": "y x"
21326
+ },
21327
+ "and_chr": {
21328
+ "0": "y"
21329
+ },
21330
+ "and_ff": {
21331
+ "0": "y x"
21332
+ },
21333
+ "ie_mob": {
21334
+ "10": "n"
21335
+ }
21336
+ },
21337
+ "notes": "",
21338
+ "usage_perc_y": 48.44,
21339
+ "usage_perc_a": 0,
21340
+ "ucprefix": false,
21341
+ "parent": "",
21342
+ "keywords": "camera,device,getUserMedia,media stream,Media Capture API"
21343
+ },
21344
+ "svg-img": {
21345
+ "title": "SVG in HTML img element",
21346
+ "description": "Method of displaying SVG images in HTML using &lt;img>",
21347
+ "spec": "http://www.w3.org/TR/html5/embedded-content-1.html#the-img-element",
21348
+ "status": "cr",
21349
+ "links": [{
21350
+ "url": "http://www.codedread.com/blog/",
21351
+ "title": "Blog with SVGs an images"
21352
+ }, {
21353
+ "url": "http://blog.dholbert.org/2010/10/svg-as-image.html",
21354
+ "title": "Blog post with examples"
21355
+ }],
21356
+ "categories": ["SVG"],
21357
+ "stats": {
21358
+ "ie": {
21359
+ "5.5": "n",
21360
+ "6": "n",
21361
+ "7": "n",
21362
+ "8": "n",
21363
+ "9": "y",
21364
+ "10": "y",
21365
+ "11": "y"
21366
+ },
21367
+ "firefox": {
21368
+ "2": "n",
21369
+ "3": "n",
21370
+ "3.5": "n",
21371
+ "3.6": "n",
21372
+ "4": "y",
21373
+ "5": "y",
21374
+ "6": "y",
21375
+ "7": "y",
21376
+ "8": "y",
21377
+ "9": "y",
21378
+ "10": "y",
21379
+ "11": "y",
21380
+ "12": "y",
21381
+ "13": "y",
21382
+ "14": "y",
21383
+ "15": "y",
21384
+ "16": "y",
21385
+ "17": "y",
21386
+ "18": "y",
21387
+ "19": "y",
21388
+ "20": "y",
21389
+ "21": "y",
21390
+ "22": "y",
21391
+ "23": "y",
21392
+ "24": "y",
21393
+ "25": "y",
21394
+ "26": "y",
21395
+ "27": "y"
21396
+ },
21397
+ "chrome": {
21398
+ "4": "y",
21399
+ "5": "y",
21400
+ "6": "y",
21401
+ "7": "y",
21402
+ "8": "y",
21403
+ "9": "y",
21404
+ "10": "y",
21405
+ "11": "y",
21406
+ "12": "y",
21407
+ "13": "y",
21408
+ "14": "y",
21409
+ "15": "y",
21410
+ "16": "y",
21411
+ "17": "y",
21412
+ "18": "y",
21413
+ "19": "y",
21414
+ "20": "y",
21415
+ "21": "y",
21416
+ "22": "y",
21417
+ "23": "y",
21418
+ "24": "y",
21419
+ "25": "y",
21420
+ "26": "y",
21421
+ "27": "y",
21422
+ "28": "y",
21423
+ "29": "y",
21424
+ "30": "y",
21425
+ "31": "y",
21426
+ "32": "y"
21427
+ },
21428
+ "safari": {
21429
+ "3.1": "n",
21430
+ "3.2": "a",
21431
+ "4": "y",
21432
+ "5": "y",
21433
+ "5.1": "y",
21434
+ "6": "y",
21435
+ "6.1": "y",
21436
+ "7": "y"
21437
+ },
21438
+ "opera": {
21439
+ "9": "y",
21440
+ "9.5-9.6": "y",
21441
+ "10.0-10.1": "y",
21442
+ "10.5": "y",
21443
+ "10.6": "y",
21444
+ "11": "y",
21445
+ "11.1": "y",
21446
+ "11.5": "y",
21447
+ "11.6": "y",
21448
+ "12": "y",
21449
+ "12.1": "y",
21450
+ "15": "y",
21451
+ "16": "y",
21452
+ "17": "y",
21453
+ "18": "y"
21454
+ },
21455
+ "ios_saf": {
21456
+ "3.2": "a",
21457
+ "4.0-4.1": "y",
21458
+ "4.2-4.3": "y",
21459
+ "5.0-5.1": "y",
21460
+ "6.0-6.1": "y",
21461
+ "7.0": "y"
21462
+ },
21463
+ "op_mini": {
21464
+ "5.0-7.0": "y"
21465
+ },
21466
+ "android": {
21467
+ "2.1": "n",
21468
+ "2.2": "n",
21469
+ "2.3": "n",
21470
+ "3": "y",
21471
+ "4": "y",
21472
+ "4.1": "y",
21473
+ "4.2-4.3": "y",
21474
+ "4.4": "y"
21475
+ },
21476
+ "bb": {
21477
+ "7": "y",
21478
+ "10": "y"
21479
+ },
21480
+ "op_mob": {
21481
+ "10": "y",
21482
+ "11": "y",
21483
+ "11.1": "y",
21484
+ "11.5": "y",
21485
+ "12": "y",
21486
+ "12.1": "y",
21487
+ "0": "y"
21488
+ },
21489
+ "and_chr": {
21490
+ "0": "y"
21491
+ },
21492
+ "and_ff": {
21493
+ "0": "y"
21494
+ },
21495
+ "ie_mob": {
21496
+ "10": "y"
21497
+ }
21498
+ },
21499
+ "notes": "",
21500
+ "usage_perc_y": 83.65,
21501
+ "usage_perc_a": 0.01,
21502
+ "ucprefix": false,
21503
+ "parent": "",
21504
+ "keywords": "svg-as-img,svg-in-img"
21505
+ },
21506
+ "datalist": {
21507
+ "title": "Datalist element",
21508
+ "description": "Method of setting a list of options for a user to select in a text field, while leaving the ability to enter a custom value.",
21509
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-datalist-element",
21510
+ "status": "wd",
21511
+ "links": [{
21512
+ "url": "http://demo.agektmr.com/datalist/",
21513
+ "title": "Eiji Kitamura's options demos & tests"
21514
+ }, {
21515
+ "url": "http://docs.webplatform.org/wiki/html/elements/datalist",
21516
+ "title": "WebPlatform Docs"
21517
+ }, {
21518
+ "url": "https://developer.mozilla.org/en/HTML/Element/datalist",
21519
+ "title": "MDN reference"
21520
+ }, {
21521
+ "url": "http://afarkas.github.com/webshim/demos/",
21522
+ "title": "HTML5 Library including datalist support"
21523
+ }, {
21524
+ "url": "http://hacks.mozilla.org/2010/11/firefox-4-html5-forms/",
21525
+ "title": "Mozilla Hacks article"
21526
+ }],
21527
+ "categories": ["HTML5"],
21528
+ "stats": {
21529
+ "ie": {
21530
+ "5.5": "n",
21531
+ "6": "p",
21532
+ "7": "p",
21533
+ "8": "p",
21534
+ "9": "p",
21535
+ "10": "a",
21536
+ "11": "a"
21537
+ },
21538
+ "firefox": {
21539
+ "2": "p",
21540
+ "3": "p",
21541
+ "3.5": "p",
21542
+ "3.6": "p",
21543
+ "4": "y",
21544
+ "5": "y",
21545
+ "6": "y",
21546
+ "7": "y",
21547
+ "8": "y",
21548
+ "9": "y",
21549
+ "10": "y",
21550
+ "11": "y",
21551
+ "12": "y",
21552
+ "13": "y",
21553
+ "14": "y",
21554
+ "15": "y",
21555
+ "16": "y",
21556
+ "17": "y",
21557
+ "18": "y",
21558
+ "19": "y",
21559
+ "20": "y",
21560
+ "21": "y",
21561
+ "22": "y",
21562
+ "23": "y",
21563
+ "24": "y",
21564
+ "25": "y",
21565
+ "26": "y",
21566
+ "27": "y"
21567
+ },
21568
+ "chrome": {
21569
+ "4": "p",
21570
+ "5": "p",
21571
+ "6": "p",
21572
+ "7": "p",
21573
+ "8": "p",
21574
+ "9": "p",
21575
+ "10": "p",
21576
+ "11": "p",
21577
+ "12": "p",
21578
+ "13": "p",
21579
+ "14": "p",
21580
+ "15": "p",
21581
+ "16": "p",
21582
+ "17": "p",
21583
+ "18": "p",
21584
+ "19": "n",
21585
+ "20": "y",
21586
+ "21": "y",
21587
+ "22": "y",
21588
+ "23": "y",
21589
+ "24": "y",
21590
+ "25": "y",
21591
+ "26": "y",
21592
+ "27": "y",
21593
+ "28": "y",
21594
+ "29": "y",
21595
+ "30": "y",
21596
+ "31": "y",
21597
+ "32": "y"
21598
+ },
21599
+ "safari": {
21600
+ "3.1": "p",
21601
+ "3.2": "p",
21602
+ "4": "p",
21603
+ "5": "p",
21604
+ "5.1": "p",
21605
+ "6": "n",
21606
+ "6.1": "n",
21607
+ "7": "n"
21608
+ },
21609
+ "opera": {
21610
+ "9": "y",
21611
+ "9.5-9.6": "y",
21612
+ "10.0-10.1": "y",
21613
+ "10.5": "y",
21614
+ "10.6": "y",
21615
+ "11": "y",
21616
+ "11.1": "y",
21617
+ "11.5": "y",
21618
+ "11.6": "y",
21619
+ "12": "y",
21620
+ "12.1": "y",
21621
+ "15": "y",
21622
+ "16": "y",
21623
+ "17": "y",
21624
+ "18": "y"
21625
+ },
21626
+ "ios_saf": {
21627
+ "3.2": "p",
21628
+ "4.0-4.1": "p",
21629
+ "4.2-4.3": "p",
21630
+ "5.0-5.1": "p",
21631
+ "6.0-6.1": "p",
21632
+ "7.0": "p"
21633
+ },
21634
+ "op_mini": {
21635
+ "5.0-7.0": "n"
21636
+ },
21637
+ "android": {
21638
+ "2.1": "p",
21639
+ "2.2": "p",
21640
+ "2.3": "p",
21641
+ "3": "p",
21642
+ "4": "p",
21643
+ "4.1": "p",
21644
+ "4.2-4.3": "p",
21645
+ "4.4": "p"
21646
+ },
21647
+ "bb": {
21648
+ "7": "p",
21649
+ "10": "y"
21650
+ },
21651
+ "op_mob": {
21652
+ "10": "y",
21653
+ "11": "y",
21654
+ "11.1": "y",
21655
+ "11.5": "y",
21656
+ "12": "y",
21657
+ "12.1": "y",
21658
+ "0": "p"
21659
+ },
21660
+ "and_chr": {
21661
+ "0": "p"
21662
+ },
21663
+ "and_ff": {
21664
+ "0": "y"
21665
+ },
21666
+ "ie_mob": {
21667
+ "10": "p"
21668
+ }
21669
+ },
21670
+ "notes": "Partial support in IE10 refers to <a href=\"http://playground.onereason.eu/2013/04/ie10s-lousy-support-for-datalists/\">significantly buggy behavior</a>.",
21671
+ "usage_perc_y": 48.86,
21672
+ "usage_perc_a": 10.9,
21673
+ "ucprefix": false,
21674
+ "parent": "forms",
21675
+ "keywords": "list attribute"
21676
+ },
21677
+ "dataset": {
21678
+ "title": "dataset & data-* attributes",
21679
+ "description": "Method of applying and accessing custom data to elements.",
21680
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#embedding-custom-non-visible-data-with-the-data-*-attributes",
21681
+ "status": "wd",
21682
+ "links": [{
21683
+ "url": "http://www.orangesoda.net/jquery.dataset.html",
21684
+ "title": "jQuery polyfill for dataset support"
21685
+ }, {
21686
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/dom.js#dom-dataset",
21687
+ "title": "has.js test"
21688
+ }, {
21689
+ "url": "http://html5demos.com/dataset",
21690
+ "title": "Demo using dataset"
21691
+ }, {
21692
+ "url": "http://html5doctor.com/html5-custom-data-attributes/",
21693
+ "title": "HTML5 Doctor article"
21694
+ }, {
21695
+ "url": "http://docs.webplatform.org/wiki/html/attributes/data-*",
21696
+ "title": "WebPlatform Docs"
21697
+ }],
21698
+ "categories": ["HTML5"],
21699
+ "stats": {
21700
+ "ie": {
21701
+ "5.5": "a",
21702
+ "6": "a",
21703
+ "7": "a",
21704
+ "8": "a",
21705
+ "9": "a",
21706
+ "10": "a",
21707
+ "11": "y"
21708
+ },
21709
+ "firefox": {
21710
+ "2": "a",
21711
+ "3": "a",
21712
+ "3.5": "a",
21713
+ "3.6": "a",
21714
+ "4": "a",
21715
+ "5": "a",
21716
+ "6": "y",
21717
+ "7": "y",
21718
+ "8": "y",
21719
+ "9": "y",
21720
+ "10": "y",
21721
+ "11": "y",
21722
+ "12": "y",
21723
+ "13": "y",
21724
+ "14": "y",
21725
+ "15": "y",
21726
+ "16": "y",
21727
+ "17": "y",
21728
+ "18": "y",
21729
+ "19": "y",
21730
+ "20": "y",
21731
+ "21": "y",
21732
+ "22": "y",
21733
+ "23": "y",
21734
+ "24": "y",
21735
+ "25": "y",
21736
+ "26": "y",
21737
+ "27": "y"
21738
+ },
21739
+ "chrome": {
21740
+ "4": "a",
21741
+ "5": "a",
21742
+ "6": "a",
21743
+ "7": "y",
21744
+ "8": "y",
21745
+ "9": "y",
21746
+ "10": "y",
21747
+ "11": "y",
21748
+ "12": "y",
21749
+ "13": "y",
21750
+ "14": "y",
21751
+ "15": "y",
21752
+ "16": "y",
21753
+ "17": "y",
21754
+ "18": "y",
21755
+ "19": "y",
21756
+ "20": "y",
21757
+ "21": "y",
21758
+ "22": "y",
21759
+ "23": "y",
21760
+ "24": "y",
21761
+ "25": "y",
21762
+ "26": "y",
21763
+ "27": "y",
21764
+ "28": "y",
21765
+ "29": "y",
21766
+ "30": "y",
21767
+ "31": "y",
21768
+ "32": "y"
21769
+ },
21770
+ "safari": {
21771
+ "3.1": "a",
21772
+ "3.2": "a",
21773
+ "4": "a",
21774
+ "5": "a",
21775
+ "5.1": "y",
21776
+ "6": "y",
21777
+ "6.1": "y",
21778
+ "7": "y"
21779
+ },
21780
+ "opera": {
21781
+ "9": "a",
21782
+ "9.5-9.6": "a",
21783
+ "10.0-10.1": "a",
21784
+ "10.5": "a",
21785
+ "10.6": "a",
21786
+ "11": "a",
21787
+ "11.1": "y",
21788
+ "11.5": "y",
21789
+ "11.6": "y",
21790
+ "12": "y",
21791
+ "12.1": "y",
21792
+ "15": "y",
21793
+ "16": "y",
21794
+ "17": "y",
21795
+ "18": "y"
21796
+ },
21797
+ "ios_saf": {
21798
+ "3.2": "a",
21799
+ "4.0-4.1": "a",
21800
+ "4.2-4.3": "a",
21801
+ "5.0-5.1": "y",
21802
+ "6.0-6.1": "y",
21803
+ "7.0": "y"
21804
+ },
21805
+ "op_mini": {
21806
+ "5.0-7.0": "a"
21807
+ },
21808
+ "android": {
21809
+ "2.1": "a",
21810
+ "2.2": "a",
21811
+ "2.3": "a",
21812
+ "3": "y",
21813
+ "4": "y",
21814
+ "4.1": "y",
21815
+ "4.2-4.3": "y",
21816
+ "4.4": "y"
21817
+ },
21818
+ "bb": {
21819
+ "7": "y",
21820
+ "10": "y"
21821
+ },
21822
+ "op_mob": {
21823
+ "10": "a",
21824
+ "11": "a",
21825
+ "11.1": "y",
21826
+ "11.5": "y",
21827
+ "12": "y",
21828
+ "12.1": "y",
21829
+ "0": "y"
21830
+ },
21831
+ "and_chr": {
21832
+ "0": "y"
21833
+ },
21834
+ "and_ff": {
21835
+ "0": "y"
21836
+ },
21837
+ "ie_mob": {
21838
+ "10": "a"
21839
+ }
21840
+ },
21841
+ "notes": "All browsers can already use data-* attributes and access them using getAttribute. \"Supported\" refers to accessing the values using the dataset property. Current spec only refers to support on HTML elements, only some browsers also have support for SVG/MathML elements.",
21842
+ "usage_perc_y": 62.15,
21843
+ "usage_perc_a": 32.43,
21844
+ "ucprefix": false,
21845
+ "parent": "",
21846
+ "keywords": "DOMStringMap"
21847
+ },
21848
+ "css-grid": {
21849
+ "title": "CSS Grid Layout",
21850
+ "description": "Method of using a grid concept to lay out content, providing a mechanism for authors to divide available space for lay out into columns and rows using a set of predictable sizing behaviors",
21851
+ "spec": "http://www.w3.org/TR/css3-grid-layout/",
21852
+ "status": "wd",
21853
+ "links": [{
21854
+ "url": "https://bugzilla.mozilla.org/show_bug.cgi?id=616605",
21855
+ "title": "Mozilla (Firefox) feature request"
21856
+ }, {
21857
+ "url": "http://blogs.msdn.com/b/ie/archive/2011/04/14/ie10-platform-preview-and-css-features-for-adaptive-layouts.aspx",
21858
+ "title": "IE Blog post"
21859
+ }, {
21860
+ "url": "https://github.com/codler/Grid-Layout-Polyfill",
21861
+ "title": "Grid Layout Polyfill"
21862
+ }, {
21863
+ "url": "https://bugs.webkit.org/show_bug.cgi?id=60731",
21864
+ "title": "Webkit (Chrome, Safari, etc.) feature request"
21865
+ }],
21866
+ "categories": ["CSS"],
21867
+ "stats": {
21868
+ "ie": {
21869
+ "5.5": "n",
21870
+ "6": "n",
21871
+ "7": "n",
21872
+ "8": "n",
21873
+ "9": "p",
21874
+ "10": "y x",
21875
+ "11": "y x"
21876
+ },
21877
+ "firefox": {
21878
+ "2": "n",
21879
+ "3": "n",
21880
+ "3.5": "n",
21881
+ "3.6": "n",
21882
+ "4": "n",
21883
+ "5": "n",
21884
+ "6": "n",
21885
+ "7": "n",
21886
+ "8": "n",
21887
+ "9": "n",
21888
+ "10": "n",
21889
+ "11": "n",
21890
+ "12": "n",
21891
+ "13": "n",
21892
+ "14": "n",
21893
+ "15": "n",
21894
+ "16": "n",
21895
+ "17": "n",
21896
+ "18": "n",
21897
+ "19": "p",
21898
+ "20": "p",
21899
+ "21": "p",
21900
+ "22": "p",
21901
+ "23": "p",
21902
+ "24": "p",
21903
+ "25": "p",
21904
+ "26": "u",
21905
+ "27": "u"
21906
+ },
21907
+ "chrome": {
21908
+ "4": "n",
21909
+ "5": "n",
21910
+ "6": "n",
21911
+ "7": "n",
21912
+ "8": "n",
21913
+ "9": "n",
21914
+ "10": "n",
21915
+ "11": "n",
21916
+ "12": "n",
21917
+ "13": "n",
21918
+ "14": "n",
21919
+ "15": "n",
21920
+ "16": "n",
21921
+ "17": "n",
21922
+ "18": "n",
21923
+ "19": "n",
21924
+ "20": "n",
21925
+ "21": "n",
21926
+ "22": "n",
21927
+ "23": "n",
21928
+ "24": "n",
21929
+ "25": "p",
21930
+ "26": "p",
21931
+ "27": "p",
21932
+ "28": "p",
21933
+ "29": "p",
21934
+ "30": "p",
21935
+ "31": "u",
21936
+ "32": "u"
21937
+ },
21938
+ "safari": {
21939
+ "3.1": "n",
21940
+ "3.2": "n",
21941
+ "4": "n",
21942
+ "5": "n",
21943
+ "5.1": "n",
21944
+ "6": "p",
21945
+ "6.1": "p",
21946
+ "7": "p"
21947
+ },
21948
+ "opera": {
21949
+ "9": "n",
21950
+ "9.5-9.6": "n",
21951
+ "10.0-10.1": "n",
21952
+ "10.5": "n",
21953
+ "10.6": "n",
21954
+ "11": "n",
21955
+ "11.1": "n",
21956
+ "11.5": "n",
21957
+ "11.6": "n",
21958
+ "12": "n",
21959
+ "12.1": "n",
21960
+ "15": "n",
21961
+ "16": "n",
21962
+ "17": "n",
21963
+ "18": "n"
21964
+ },
21965
+ "ios_saf": {
21966
+ "3.2": "n",
21967
+ "4.0-4.1": "n",
21968
+ "4.2-4.3": "n",
21969
+ "5.0-5.1": "n",
21970
+ "6.0-6.1": "p",
21971
+ "7.0": "p"
21972
+ },
21973
+ "op_mini": {
21974
+ "5.0-7.0": "n"
21975
+ },
21976
+ "android": {
21977
+ "2.1": "n",
21978
+ "2.2": "n",
21979
+ "2.3": "n",
21980
+ "3": "n",
21981
+ "4": "n",
21982
+ "4.1": "n",
21983
+ "4.2-4.3": "p",
21984
+ "4.4": "p"
21985
+ },
21986
+ "bb": {
21987
+ "7": "n",
21988
+ "10": "n"
21989
+ },
21990
+ "op_mob": {
21991
+ "10": "n",
21992
+ "11": "n",
21993
+ "11.1": "n",
21994
+ "11.5": "n",
21995
+ "12": "n",
21996
+ "12.1": "n",
21997
+ "0": "p"
21998
+ },
21999
+ "and_chr": {
22000
+ "0": "p"
22001
+ },
22002
+ "and_ff": {
22003
+ "0": "n"
22004
+ },
22005
+ "ie_mob": {
22006
+ "10": "y x"
22007
+ }
22008
+ },
22009
+ "notes": "",
22010
+ "usage_perc_y": 11.11,
22011
+ "usage_perc_a": 0,
22012
+ "ucprefix": false,
22013
+ "parent": "",
22014
+ "keywords": "grids,grid-row,grid-column"
22015
+ },
22016
+ "menu": {
22017
+ "title": "Toolbar/context menu",
22018
+ "description": "Method of defining a toolbar menu, a context menu or a list of (interactive) options using the &lt;menu> element.",
22019
+ "spec": "http://www.w3.org/TR/html5/interactive-elements.html#context-menus",
22020
+ "status": "cr",
22021
+ "links": [{
22022
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/events.js#event-contextmenu",
22023
+ "title": "has.js test"
22024
+ }, {
22025
+ "url": "https://bug617528.bugzilla.mozilla.org/attachment.cgi?id=554309",
22026
+ "title": "Demo"
22027
+ }, {
22028
+ "url": "http://addyosmani.github.com/jQuery-contextMenu/",
22029
+ "title": "jQuery polyfill"
22030
+ }],
22031
+ "categories": ["HTML5"],
22032
+ "stats": {
22033
+ "ie": {
22034
+ "5.5": "n",
22035
+ "6": "n",
22036
+ "7": "n",
22037
+ "8": "n",
22038
+ "9": "n",
22039
+ "10": "n",
22040
+ "11": "n"
22041
+ },
22042
+ "firefox": {
22043
+ "2": "n",
22044
+ "3": "n",
22045
+ "3.5": "n",
22046
+ "3.6": "n",
22047
+ "4": "n",
22048
+ "5": "n",
22049
+ "6": "n",
22050
+ "7": "n",
22051
+ "8": "a",
22052
+ "9": "a",
22053
+ "10": "a",
22054
+ "11": "a",
22055
+ "12": "a",
22056
+ "13": "a",
22057
+ "14": "a",
22058
+ "15": "a",
22059
+ "16": "a",
22060
+ "17": "a",
22061
+ "18": "a",
22062
+ "19": "a",
22063
+ "20": "a",
22064
+ "21": "a",
22065
+ "22": "a",
22066
+ "23": "a",
22067
+ "24": "a",
22068
+ "25": "a",
22069
+ "26": "a",
22070
+ "27": "a"
22071
+ },
22072
+ "chrome": {
22073
+ "4": "n",
22074
+ "5": "n",
22075
+ "6": "n",
22076
+ "7": "n",
22077
+ "8": "n",
22078
+ "9": "n",
22079
+ "10": "n",
22080
+ "11": "n",
22081
+ "12": "n",
22082
+ "13": "n",
22083
+ "14": "n",
22084
+ "15": "n",
22085
+ "16": "n",
22086
+ "17": "n",
22087
+ "18": "n",
22088
+ "19": "n",
22089
+ "20": "n",
22090
+ "21": "n",
22091
+ "22": "n",
22092
+ "23": "n",
22093
+ "24": "n",
22094
+ "25": "n",
22095
+ "26": "n",
22096
+ "27": "n",
22097
+ "28": "n",
22098
+ "29": "n",
22099
+ "30": "n",
22100
+ "31": "u",
22101
+ "32": "u"
22102
+ },
22103
+ "safari": {
22104
+ "3.1": "n",
22105
+ "3.2": "n",
22106
+ "4": "n",
22107
+ "5": "n",
22108
+ "5.1": "n",
22109
+ "6": "n",
22110
+ "6.1": "u",
22111
+ "7": "u"
22112
+ },
22113
+ "opera": {
22114
+ "9": "n",
22115
+ "9.5-9.6": "n",
22116
+ "10.0-10.1": "n",
22117
+ "10.5": "n",
22118
+ "10.6": "n",
22119
+ "11": "n",
22120
+ "11.1": "n",
22121
+ "11.5": "n",
22122
+ "11.6": "n",
22123
+ "12": "n",
22124
+ "12.1": "n",
22125
+ "15": "n",
22126
+ "16": "n",
22127
+ "17": "n",
22128
+ "18": "n"
22129
+ },
22130
+ "ios_saf": {
22131
+ "3.2": "n",
22132
+ "4.0-4.1": "n",
22133
+ "4.2-4.3": "n",
22134
+ "5.0-5.1": "n",
22135
+ "6.0-6.1": "n",
22136
+ "7.0": "n"
22137
+ },
22138
+ "op_mini": {
22139
+ "5.0-7.0": "n"
22140
+ },
22141
+ "android": {
22142
+ "2.1": "n",
22143
+ "2.2": "n",
22144
+ "2.3": "n",
22145
+ "3": "n",
22146
+ "4": "n",
22147
+ "4.1": "n",
22148
+ "4.2-4.3": "n",
22149
+ "4.4": "n"
22150
+ },
22151
+ "bb": {
22152
+ "7": "n",
22153
+ "10": "n"
22154
+ },
22155
+ "op_mob": {
22156
+ "10": "n",
22157
+ "11": "n",
22158
+ "11.1": "n",
22159
+ "11.5": "n",
22160
+ "12": "n",
22161
+ "12.1": "n",
22162
+ "0": "n"
22163
+ },
22164
+ "and_chr": {
22165
+ "0": "n"
22166
+ },
22167
+ "and_ff": {
22168
+ "0": "n"
22169
+ },
22170
+ "ie_mob": {
22171
+ "10": "n"
22172
+ }
22173
+ },
22174
+ "notes": "Partial support in Firefox refers to using the non-standard \"menuitem\" child elements, where the current spec uses \"<a href=\"http://www.w3.org/TR/html5/interactive-elements.html#the-command-element\">command</a>\" child elements. It is also currently limited to context menus, not toolbar menus.",
22175
+ "usage_perc_y": 0,
22176
+ "usage_perc_a": 14.7,
22177
+ "ucprefix": false,
22178
+ "parent": "",
22179
+ "keywords": "contextmenu,menuitem,command"
22180
+ },
22181
+ "rem": {
22182
+ "title": "rem (root em) units",
22183
+ "description": "Type of unit similar to \"em\", but relative only to the root element, not any parent element. Thus compounding does not occur as it does with \"em\" units.",
22184
+ "spec": "http://www.w3.org/TR/css3-values/#font-relative-lengths",
22185
+ "status": "cr",
22186
+ "links": [{
22187
+ "url": "http://snook.ca/archives/html_and_css/font-size-with-rem",
22188
+ "title": "Article on usage"
22189
+ }],
22190
+ "categories": ["CSS3"],
22191
+ "stats": {
22192
+ "ie": {
22193
+ "5.5": "n",
22194
+ "6": "n",
22195
+ "7": "n",
22196
+ "8": "n",
22197
+ "9": "y",
22198
+ "10": "y",
22199
+ "11": "y"
22200
+ },
22201
+ "firefox": {
22202
+ "2": "n",
22203
+ "3": "n",
22204
+ "3.5": "n",
22205
+ "3.6": "y",
22206
+ "4": "y",
22207
+ "5": "y",
22208
+ "6": "y",
22209
+ "7": "y",
22210
+ "8": "y",
22211
+ "9": "y",
22212
+ "10": "y",
22213
+ "11": "y",
22214
+ "12": "y",
22215
+ "13": "y",
22216
+ "14": "y",
22217
+ "15": "y",
22218
+ "16": "y",
22219
+ "17": "y",
22220
+ "18": "y",
22221
+ "19": "y",
22222
+ "20": "y",
22223
+ "21": "y",
22224
+ "22": "y",
22225
+ "23": "y",
22226
+ "24": "y",
22227
+ "25": "y",
22228
+ "26": "y",
22229
+ "27": "y"
22230
+ },
22231
+ "chrome": {
22232
+ "4": "u",
22233
+ "5": "u",
22234
+ "6": "y",
22235
+ "7": "y",
22236
+ "8": "y",
22237
+ "9": "y",
22238
+ "10": "y",
22239
+ "11": "y",
22240
+ "12": "y",
22241
+ "13": "y",
22242
+ "14": "y",
22243
+ "15": "y",
22244
+ "16": "y",
22245
+ "17": "y",
22246
+ "18": "y",
22247
+ "19": "y",
22248
+ "20": "y",
22249
+ "21": "y",
22250
+ "22": "y",
22251
+ "23": "y",
22252
+ "24": "y",
22253
+ "25": "y",
22254
+ "26": "y",
22255
+ "27": "y",
22256
+ "28": "y",
22257
+ "29": "y",
22258
+ "30": "y",
22259
+ "31": "y",
22260
+ "32": "y"
22261
+ },
22262
+ "safari": {
22263
+ "3.1": "n",
22264
+ "3.2": "n",
22265
+ "4": "n",
22266
+ "5": "y",
22267
+ "5.1": "y",
22268
+ "6": "y",
22269
+ "6.1": "y",
22270
+ "7": "y"
22271
+ },
22272
+ "opera": {
22273
+ "9": "n",
22274
+ "9.5-9.6": "n",
22275
+ "10.0-10.1": "n",
22276
+ "10.5": "n",
22277
+ "10.6": "n",
22278
+ "11": "n",
22279
+ "11.1": "n",
22280
+ "11.5": "n",
22281
+ "11.6": "y",
22282
+ "12": "y",
22283
+ "12.1": "y",
22284
+ "15": "y",
22285
+ "16": "y",
22286
+ "17": "y",
22287
+ "18": "y"
22288
+ },
22289
+ "ios_saf": {
22290
+ "3.2": "n",
22291
+ "4.0-4.1": "y",
22292
+ "4.2-4.3": "y",
22293
+ "5.0-5.1": "y",
22294
+ "6.0-6.1": "y",
22295
+ "7.0": "y"
22296
+ },
22297
+ "op_mini": {
22298
+ "5.0-7.0": "n"
22299
+ },
22300
+ "android": {
22301
+ "2.1": "y",
22302
+ "2.2": "y",
22303
+ "2.3": "y",
22304
+ "3": "y",
22305
+ "4": "y",
22306
+ "4.1": "y",
22307
+ "4.2-4.3": "y",
22308
+ "4.4": "y"
22309
+ },
22310
+ "bb": {
22311
+ "7": "y",
22312
+ "10": "y"
22313
+ },
22314
+ "op_mob": {
22315
+ "10": "n",
22316
+ "11": "n",
22317
+ "11.1": "n",
22318
+ "11.5": "n",
22319
+ "12": "y",
22320
+ "12.1": "y",
22321
+ "0": "y"
22322
+ },
22323
+ "and_chr": {
22324
+ "0": "y"
22325
+ },
22326
+ "and_ff": {
22327
+ "0": "y"
22328
+ },
22329
+ "ie_mob": {
22330
+ "10": "y"
22331
+ }
22332
+ },
22333
+ "notes": "",
22334
+ "usage_perc_y": 80.56,
22335
+ "usage_perc_a": 0,
22336
+ "ucprefix": false,
22337
+ "parent": "",
22338
+ "keywords": ""
22339
+ },
22340
+ "ttf": {
22341
+ "title": "TTF/OTF - TrueType and OpenType font support",
22342
+ "description": "Support for the TrueType (.ttf)and OpenType (.otf) outline font formats in @font-face. ",
22343
+ "spec": "http://developer.apple.com/fonts/TTRefMan/index.html",
22344
+ "status": "other",
22345
+ "links": [{
22346
+ "url": "http://stackoverflow.com/questions/17694143/what-is-the-status-of-ttf-support-in-internet-explorer",
22347
+ "title": "What is the status of TTF support in Internet Explorer?"
22348
+ }],
22349
+ "categories": ["CSS3"],
22350
+ "stats": {
22351
+ "ie": {
22352
+ "5.5": "n",
22353
+ "6": "n",
22354
+ "7": "n",
22355
+ "8": "n",
22356
+ "9": "a",
22357
+ "10": "a",
22358
+ "11": "a"
22359
+ },
22360
+ "firefox": {
22361
+ "2": "n",
22362
+ "3": "n",
22363
+ "3.5": "y",
22364
+ "3.6": "y",
22365
+ "4": "y",
22366
+ "5": "y",
22367
+ "6": "y",
22368
+ "7": "y",
22369
+ "8": "y",
22370
+ "9": "y",
22371
+ "10": "y",
22372
+ "11": "y",
22373
+ "12": "y",
22374
+ "13": "y",
22375
+ "14": "y",
22376
+ "15": "y",
22377
+ "16": "y",
22378
+ "17": "y",
22379
+ "18": "y",
22380
+ "19": "y",
22381
+ "20": "y",
22382
+ "21": "y",
22383
+ "22": "y",
22384
+ "23": "y",
22385
+ "24": "y",
22386
+ "25": "y",
22387
+ "26": "y",
22388
+ "27": "y"
22389
+ },
22390
+ "chrome": {
22391
+ "4": "y",
22392
+ "5": "y",
22393
+ "6": "y",
22394
+ "7": "y",
22395
+ "8": "y",
22396
+ "9": "y",
22397
+ "10": "y",
22398
+ "11": "y",
22399
+ "12": "y",
22400
+ "13": "y",
22401
+ "14": "y",
22402
+ "15": "y",
22403
+ "16": "y",
22404
+ "17": "y",
22405
+ "18": "y",
22406
+ "19": "y",
22407
+ "20": "y",
22408
+ "21": "y",
22409
+ "22": "y",
22410
+ "23": "y",
22411
+ "24": "y",
22412
+ "25": "y",
22413
+ "26": "y",
22414
+ "27": "y",
22415
+ "28": "y",
22416
+ "29": "y",
22417
+ "30": "y",
22418
+ "31": "y",
22419
+ "32": "y"
22420
+ },
22421
+ "safari": {
22422
+ "3.1": "y",
22423
+ "3.2": "y",
22424
+ "4": "y",
22425
+ "5": "y",
22426
+ "5.1": "y",
22427
+ "6": "y",
22428
+ "6.1": "y",
22429
+ "7": "y"
22430
+ },
22431
+ "opera": {
22432
+ "9": "n",
22433
+ "9.5-9.6": "n",
22434
+ "10.0-10.1": "y",
22435
+ "10.5": "y",
22436
+ "10.6": "y",
22437
+ "11": "y",
22438
+ "11.1": "y",
22439
+ "11.5": "y",
22440
+ "11.6": "y",
22441
+ "12": "y",
22442
+ "12.1": "y",
22443
+ "15": "y",
22444
+ "16": "y",
22445
+ "17": "y",
22446
+ "18": "y"
22447
+ },
22448
+ "ios_saf": {
22449
+ "3.2": "n",
22450
+ "4.0-4.1": "n",
22451
+ "4.2-4.3": "y",
22452
+ "5.0-5.1": "y",
22453
+ "6.0-6.1": "y",
22454
+ "7.0": "y"
22455
+ },
22456
+ "op_mini": {
22457
+ "5.0-7.0": "n"
22458
+ },
22459
+ "android": {
22460
+ "2.1": "n",
22461
+ "2.2": "y",
22462
+ "2.3": "y",
22463
+ "3": "y",
22464
+ "4": "y",
22465
+ "4.1": "y",
22466
+ "4.2-4.3": "y",
22467
+ "4.4": "y"
22468
+ },
22469
+ "bb": {
22470
+ "7": "y",
22471
+ "10": "y"
22472
+ },
22473
+ "op_mob": {
22474
+ "10": "y",
22475
+ "11": "y",
22476
+ "11.1": "y",
22477
+ "11.5": "y",
22478
+ "12": "y",
22479
+ "12.1": "y",
22480
+ "0": "y"
22481
+ },
22482
+ "and_chr": {
22483
+ "0": "y"
22484
+ },
22485
+ "and_ff": {
22486
+ "0": "y"
22487
+ },
22488
+ "ie_mob": {
22489
+ "10": "u"
22490
+ }
22491
+ },
22492
+ "notes": "Partial support in IE9 refers to the fonts only working <a href=\"http://blogs.msdn.com/b/ie/archive/2010/07/15/the-css-corner-better-web-typography-for-better-design.aspx\">when set to be \"installable\"</a>.",
22493
+ "usage_perc_y": 64.48,
22494
+ "usage_perc_a": 16.11,
22495
+ "ucprefix": false,
22496
+ "parent": "fontface",
22497
+ "keywords": ""
22498
+ },
22499
+ "touch": {
22500
+ "title": "Touch events",
22501
+ "description": "Method of registering when, where and how the interface is touched, for devices with a touch screen. These DOM events are similar to mousedown, mousemove, etc.",
22502
+ "spec": "http://www.w3.org/TR/touch-events/",
22503
+ "status": "rec",
22504
+ "links": [{
22505
+ "url": "http://schepers.cc/getintouch",
22506
+ "title": "Information on the spec development"
22507
+ }, {
22508
+ "url": "http://www.quirksmode.org/mobile/tableTouch.html",
22509
+ "title": "Detailed support tables"
22510
+ }, {
22511
+ "url": "http://www.quirksmode.org/m/tests/drag2.html",
22512
+ "title": "Multi-touch demo"
22513
+ }, {
22514
+ "url": "http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx",
22515
+ "title": "Internet Explorer's gesture and touch implementation."
22516
+ }],
22517
+ "categories": ["DOM", "JS API"],
22518
+ "stats": {
22519
+ "ie": {
22520
+ "5.5": "n",
22521
+ "6": "n",
22522
+ "7": "n",
22523
+ "8": "n",
22524
+ "9": "n",
22525
+ "10": "p",
22526
+ "11": "p"
22527
+ },
22528
+ "firefox": {
22529
+ "2": "n",
22530
+ "3": "n",
22531
+ "3.5": "n",
22532
+ "3.6": "n",
22533
+ "4": "a",
22534
+ "5": "a",
22535
+ "6": "y",
22536
+ "7": "y",
22537
+ "8": "y",
22538
+ "9": "y",
22539
+ "10": "y",
22540
+ "11": "y",
22541
+ "12": "y",
22542
+ "13": "y",
22543
+ "14": "y",
22544
+ "15": "y",
22545
+ "16": "y",
22546
+ "17": "y",
22547
+ "18": "y",
22548
+ "19": "y",
22549
+ "20": "y",
22550
+ "21": "y",
22551
+ "22": "y",
22552
+ "23": "y",
22553
+ "24": "y",
22554
+ "25": "y",
22555
+ "26": "y",
22556
+ "27": "y"
22557
+ },
22558
+ "chrome": {
22559
+ "4": "n",
22560
+ "5": "n",
22561
+ "6": "n",
22562
+ "7": "n",
22563
+ "8": "n",
22564
+ "9": "n",
22565
+ "10": "n",
22566
+ "11": "n",
22567
+ "12": "n",
22568
+ "13": "n",
22569
+ "14": "n",
22570
+ "15": "n",
22571
+ "16": "n",
22572
+ "17": "n",
22573
+ "18": "n",
22574
+ "19": "n",
22575
+ "20": "n",
22576
+ "21": "n",
22577
+ "22": "y",
22578
+ "23": "y",
22579
+ "24": "y",
22580
+ "25": "y",
22581
+ "26": "y",
22582
+ "27": "y",
22583
+ "28": "y",
22584
+ "29": "y",
22585
+ "30": "y",
22586
+ "31": "y",
22587
+ "32": "y"
22588
+ },
22589
+ "safari": {
22590
+ "3.1": "n",
22591
+ "3.2": "n",
22592
+ "4": "n",
22593
+ "5": "n",
22594
+ "5.1": "n",
22595
+ "6": "n",
22596
+ "6.1": "u",
22597
+ "7": "u"
22598
+ },
22599
+ "opera": {
22600
+ "9": "n",
22601
+ "9.5-9.6": "n",
22602
+ "10.0-10.1": "n",
22603
+ "10.5": "n",
22604
+ "10.6": "n",
22605
+ "11": "n",
22606
+ "11.1": "n",
22607
+ "11.5": "n",
22608
+ "11.6": "n",
22609
+ "12": "n",
22610
+ "12.1": "n",
22611
+ "15": "y",
22612
+ "16": "y",
22613
+ "17": "y",
22614
+ "18": "y"
22615
+ },
22616
+ "ios_saf": {
22617
+ "3.2": "y",
22618
+ "4.0-4.1": "y",
22619
+ "4.2-4.3": "y",
22620
+ "5.0-5.1": "y",
22621
+ "6.0-6.1": "y",
22622
+ "7.0": "y"
22623
+ },
22624
+ "op_mini": {
22625
+ "5.0-7.0": "n"
22626
+ },
22627
+ "android": {
22628
+ "2.1": "y",
22629
+ "2.2": "y",
22630
+ "2.3": "y",
22631
+ "3": "y",
22632
+ "4": "y",
22633
+ "4.1": "y",
22634
+ "4.2-4.3": "y",
22635
+ "4.4": "y"
22636
+ },
22637
+ "bb": {
22638
+ "7": "y",
22639
+ "10": "y"
22640
+ },
22641
+ "op_mob": {
22642
+ "10": "n",
22643
+ "11": "y",
22644
+ "11.1": "y",
22645
+ "11.5": "y",
22646
+ "12": "y",
22647
+ "12.1": "y",
22648
+ "0": "y"
22649
+ },
22650
+ "and_chr": {
22651
+ "0": "y"
22652
+ },
22653
+ "and_ff": {
22654
+ "0": "y"
22655
+ },
22656
+ "ie_mob": {
22657
+ "10": "p"
22658
+ }
22659
+ },
22660
+ "notes": "Internet Explorer implements Pointer Events specification which supports more input devices than Touch Events one.",
22661
+ "usage_perc_y": 58.16,
22662
+ "usage_perc_a": 0.12,
22663
+ "ucprefix": false,
22664
+ "parent": "",
22665
+ "keywords": "touchstart,touchend,touchmove,touchenter,touchleave,touchcancel"
22666
+ },
22667
+ "matchesselector": {
22668
+ "title": "matches() DOM method",
22669
+ "description": "Method of testing whether or not a DOM element matches a given selector. Formerly known (and largely supported with prefix) as matchesSelector.",
22670
+ "spec": "http://www.w3.org/TR/selectors-api2/",
22671
+ "status": "wd",
22672
+ "links": [{
22673
+ "url": "https://developer.mozilla.org/en/DOM/Element.mozMatchesSelector",
22674
+ "title": "MDN article"
22675
+ }, {
22676
+ "url": "http://docs.webplatform.org/wiki/dom/methods/matchesSelector",
22677
+ "title": "WebPlatform Docs"
22678
+ }],
22679
+ "categories": ["DOM", "JS API"],
22680
+ "stats": {
22681
+ "ie": {
22682
+ "5.5": "n",
22683
+ "6": "n",
22684
+ "7": "n",
22685
+ "8": "n",
22686
+ "9": "a x",
22687
+ "10": "a x",
22688
+ "11": "a x"
22689
+ },
22690
+ "firefox": {
22691
+ "2": "n",
22692
+ "3": "n",
22693
+ "3.5": "n",
22694
+ "3.6": "a x",
22695
+ "4": "a x",
22696
+ "5": "a x",
22697
+ "6": "a x",
22698
+ "7": "a x",
22699
+ "8": "a x",
22700
+ "9": "a x",
22701
+ "10": "a x",
22702
+ "11": "a x",
22703
+ "12": "a x",
22704
+ "13": "a x",
22705
+ "14": "a x",
22706
+ "15": "a x",
22707
+ "16": "a x",
22708
+ "17": "a x",
22709
+ "18": "a x",
22710
+ "19": "a x",
22711
+ "20": "a x",
22712
+ "21": "a x",
22713
+ "22": "a x",
22714
+ "23": "a x",
22715
+ "24": "a x",
22716
+ "25": "a x",
22717
+ "26": "a x",
22718
+ "27": "a x"
22719
+ },
22720
+ "chrome": {
22721
+ "4": "a x",
22722
+ "5": "a x",
22723
+ "6": "a x",
22724
+ "7": "a x",
22725
+ "8": "a x",
22726
+ "9": "a x",
22727
+ "10": "a x",
22728
+ "11": "a x",
22729
+ "12": "a x",
22730
+ "13": "a x",
22731
+ "14": "a x",
22732
+ "15": "a x",
22733
+ "16": "a x",
22734
+ "17": "a x",
22735
+ "18": "a x",
22736
+ "19": "a x",
22737
+ "20": "a x",
22738
+ "21": "a x",
22739
+ "22": "a x",
22740
+ "23": "a x",
22741
+ "24": "a x",
22742
+ "25": "a x",
22743
+ "26": "a x",
22744
+ "27": "a x",
22745
+ "28": "a x",
22746
+ "29": "a x",
22747
+ "30": "a x",
22748
+ "31": "a x",
22749
+ "32": "a x"
22750
+ },
22751
+ "safari": {
22752
+ "3.1": "n",
22753
+ "3.2": "n",
22754
+ "4": "n",
22755
+ "5": "a x",
22756
+ "5.1": "a x",
22757
+ "6": "a x",
22758
+ "6.1": "a x",
22759
+ "7": "a x"
22760
+ },
22761
+ "opera": {
22762
+ "9": "n",
22763
+ "9.5-9.6": "n",
22764
+ "10.0-10.1": "n",
22765
+ "10.5": "n",
22766
+ "10.6": "n",
22767
+ "11": "n",
22768
+ "11.1": "n",
22769
+ "11.5": "a x",
22770
+ "11.6": "a x",
22771
+ "12": "a x",
22772
+ "12.1": "a x",
22773
+ "15": "a x",
22774
+ "16": "a x",
22775
+ "17": "a x",
22776
+ "18": "a x"
22777
+ },
22778
+ "ios_saf": {
22779
+ "3.2": "n",
22780
+ "4.0-4.1": "a x",
22781
+ "4.2-4.3": "a x",
22782
+ "5.0-5.1": "a x",
22783
+ "6.0-6.1": "a x",
22784
+ "7.0": "a x"
22785
+ },
22786
+ "op_mini": {
22787
+ "5.0-7.0": "n"
22788
+ },
22789
+ "android": {
22790
+ "2.1": "n",
22791
+ "2.2": "a x",
22792
+ "2.3": "a x",
22793
+ "3": "a x",
22794
+ "4": "a x",
22795
+ "4.1": "a x",
22796
+ "4.2-4.3": "a x",
22797
+ "4.4": "a x"
22798
+ },
22799
+ "bb": {
22800
+ "7": "a x",
22801
+ "10": "a x"
22802
+ },
22803
+ "op_mob": {
22804
+ "10": "n",
22805
+ "11": "n",
22806
+ "11.1": "a x",
22807
+ "11.5": "a x",
22808
+ "12": "a x",
22809
+ "12.1": "a x",
22810
+ "0": "a x"
22811
+ },
22812
+ "and_chr": {
22813
+ "0": "a x"
22814
+ },
22815
+ "and_ff": {
22816
+ "0": "a x"
22817
+ },
22818
+ "ie_mob": {
22819
+ "10": "a x"
22820
+ }
22821
+ },
22822
+ "notes": "Partial support refers to supporting the older specification's \"matchesSelector\" name rather than just \"matches\".",
22823
+ "usage_perc_y": 0,
22824
+ "usage_perc_a": 80.6,
22825
+ "ucprefix": false,
22826
+ "parent": "",
22827
+ "keywords": " matchesSelector"
22828
+ },
22829
+ "pointer-events": {
22830
+ "title": "CSS pointer-events (for HTML)",
22831
+ "description": "This CSS property, when set to \"none\" allows elements to not receive hover/click events, instead the event will occur on anything behind it. ",
22832
+ "spec": "http://wiki.csswg.org/spec/css4-ui#pointer-events",
22833
+ "status": "unoff",
22834
+ "links": [{
22835
+ "url": "http://robertnyman.com/2010/03/22/css-pointer-events-to-allow-clicks-on-underlying-elements/",
22836
+ "title": "Article & tutorial"
22837
+ }, {
22838
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/css.js#css-pointerevents",
22839
+ "title": "has.js test"
22840
+ }],
22841
+ "categories": ["CSS3"],
22842
+ "stats": {
22843
+ "ie": {
22844
+ "5.5": "n",
22845
+ "6": "n",
22846
+ "7": "n",
22847
+ "8": "n",
22848
+ "9": "n",
22849
+ "10": "n",
22850
+ "11": "y"
22851
+ },
22852
+ "firefox": {
22853
+ "2": "n",
22854
+ "3": "n",
22855
+ "3.5": "n",
22856
+ "3.6": "y",
22857
+ "4": "y",
22858
+ "5": "y",
22859
+ "6": "y",
22860
+ "7": "y",
22861
+ "8": "y",
22862
+ "9": "y",
22863
+ "10": "y",
22864
+ "11": "y",
22865
+ "12": "y",
22866
+ "13": "y",
22867
+ "14": "y",
22868
+ "15": "y",
22869
+ "16": "y",
22870
+ "17": "y",
22871
+ "18": "y",
22872
+ "19": "y",
22873
+ "20": "y",
22874
+ "21": "y",
22875
+ "22": "y",
22876
+ "23": "y",
22877
+ "24": "y",
22878
+ "25": "y",
22879
+ "26": "y",
22880
+ "27": "y"
22881
+ },
22882
+ "chrome": {
22883
+ "4": "y",
22884
+ "5": "y",
22885
+ "6": "y",
22886
+ "7": "y",
22887
+ "8": "y",
22888
+ "9": "y",
22889
+ "10": "y",
22890
+ "11": "y",
22891
+ "12": "y",
22892
+ "13": "y",
22893
+ "14": "y",
22894
+ "15": "y",
22895
+ "16": "y",
22896
+ "17": "y",
22897
+ "18": "y",
22898
+ "19": "y",
22899
+ "20": "y",
22900
+ "21": "y",
22901
+ "22": "y",
22902
+ "23": "y",
22903
+ "24": "y",
22904
+ "25": "y",
22905
+ "26": "y",
22906
+ "27": "y",
22907
+ "28": "y",
22908
+ "29": "y",
22909
+ "30": "y",
22910
+ "31": "y",
22911
+ "32": "y"
22912
+ },
22913
+ "safari": {
22914
+ "3.1": "n",
22915
+ "3.2": "n",
22916
+ "4": "y",
22917
+ "5": "y",
22918
+ "5.1": "y",
22919
+ "6": "y",
22920
+ "6.1": "y",
22921
+ "7": "y"
22922
+ },
22923
+ "opera": {
22924
+ "9": "n",
22925
+ "9.5-9.6": "n",
22926
+ "10.0-10.1": "n",
22927
+ "10.5": "n",
22928
+ "10.6": "n",
22929
+ "11": "n",
22930
+ "11.1": "n",
22931
+ "11.5": "n",
22932
+ "11.6": "n",
22933
+ "12": "n",
22934
+ "12.1": "n",
22935
+ "15": "y",
22936
+ "16": "y",
22937
+ "17": "y",
22938
+ "18": "y"
22939
+ },
22940
+ "ios_saf": {
22941
+ "3.2": "y",
22942
+ "4.0-4.1": "y",
22943
+ "4.2-4.3": "y",
22944
+ "5.0-5.1": "y",
22945
+ "6.0-6.1": "y",
22946
+ "7.0": "y"
22947
+ },
22948
+ "op_mini": {
22949
+ "5.0-7.0": "n"
22950
+ },
22951
+ "android": {
22952
+ "2.1": "y",
22953
+ "2.2": "y",
22954
+ "2.3": "y",
22955
+ "3": "y",
22956
+ "4": "y",
22957
+ "4.1": "y",
22958
+ "4.2-4.3": "y",
22959
+ "4.4": "y"
22960
+ },
22961
+ "bb": {
22962
+ "7": "y",
22963
+ "10": "y"
22964
+ },
22965
+ "op_mob": {
22966
+ "10": "n",
22967
+ "11": "n",
22968
+ "11.1": "n",
22969
+ "11.5": "n",
22970
+ "12": "n",
22971
+ "12.1": "n",
22972
+ "0": "y"
22973
+ },
22974
+ "and_chr": {
22975
+ "0": "y"
22976
+ },
22977
+ "and_ff": {
22978
+ "0": "y"
22979
+ },
22980
+ "ie_mob": {
22981
+ "10": "n"
22982
+ }
22983
+ },
22984
+ "notes": "Already part of the SVG specification, and all SVG-supporting browsers appear to support the property on SVG elements.",
22985
+ "usage_perc_y": 63.82,
22986
+ "usage_perc_a": 0,
22987
+ "ucprefix": false,
22988
+ "parent": "",
22989
+ "keywords": "pointerevents"
22990
+ },
22991
+ "blobbuilder": {
22992
+ "title": "Blob constructing",
22993
+ "description": "Construct Blobs (binary large objects) either using the BlobBuilder API (deprecated) or the Blob constructor.",
22994
+ "spec": "http://www.w3.org/TR/file-writer-api/#the-blobbuilder-interface",
22995
+ "status": "wd",
22996
+ "links": [{
22997
+ "url": "https://developer.mozilla.org/en/DOM/BlobBuilder",
22998
+ "title": "MDN article on BlobBuilder"
22999
+ }, {
23000
+ "url": "https://developer.mozilla.org/en-US/docs/DOM/Blob",
23001
+ "title": "MDN article on Blobs"
23002
+ }],
23003
+ "categories": ["JS API"],
23004
+ "stats": {
23005
+ "ie": {
23006
+ "5.5": "n",
23007
+ "6": "n",
23008
+ "7": "n",
23009
+ "8": "n",
23010
+ "9": "n",
23011
+ "10": "y",
23012
+ "11": "y"
23013
+ },
23014
+ "firefox": {
23015
+ "2": "n",
23016
+ "3": "n",
23017
+ "3.5": "n",
23018
+ "3.6": "n",
23019
+ "4": "n",
23020
+ "5": "n",
23021
+ "6": "a x",
23022
+ "7": "a x",
23023
+ "8": "a x",
23024
+ "9": "a x",
23025
+ "10": "a x",
23026
+ "11": "a x",
23027
+ "12": "a x",
23028
+ "13": "y",
23029
+ "14": "y",
23030
+ "15": "y",
23031
+ "16": "y",
23032
+ "17": "y",
23033
+ "18": "y",
23034
+ "19": "y",
23035
+ "20": "y",
23036
+ "21": "y",
23037
+ "22": "y",
23038
+ "23": "y",
23039
+ "24": "y",
23040
+ "25": "y",
23041
+ "26": "y",
23042
+ "27": "y"
23043
+ },
23044
+ "chrome": {
23045
+ "4": "n",
23046
+ "5": "n",
23047
+ "6": "n",
23048
+ "7": "n",
23049
+ "8": "a x",
23050
+ "9": "a x",
23051
+ "10": "a x",
23052
+ "11": "a x",
23053
+ "12": "a x",
23054
+ "13": "a x",
23055
+ "14": "a x",
23056
+ "15": "a x",
23057
+ "16": "a x",
23058
+ "17": "a x",
23059
+ "18": "a x",
23060
+ "19": "a x",
23061
+ "20": "y",
23062
+ "21": "y",
23063
+ "22": "y",
23064
+ "23": "y",
23065
+ "24": "y",
23066
+ "25": "y",
23067
+ "26": "y",
23068
+ "27": "y",
23069
+ "28": "y",
23070
+ "29": "y",
23071
+ "30": "y",
23072
+ "31": "y",
23073
+ "32": "y"
23074
+ },
23075
+ "safari": {
23076
+ "3.1": "n",
23077
+ "3.2": "n",
23078
+ "4": "n",
23079
+ "5": "n",
23080
+ "5.1": "n",
23081
+ "6": "y",
23082
+ "6.1": "y",
23083
+ "7": "y"
23084
+ },
23085
+ "opera": {
23086
+ "9": "n",
23087
+ "9.5-9.6": "n",
23088
+ "10.0-10.1": "n",
23089
+ "10.5": "n",
23090
+ "10.6": "n",
23091
+ "11": "n",
23092
+ "11.1": "n",
23093
+ "11.5": "n",
23094
+ "11.6": "n",
23095
+ "12": "n",
23096
+ "12.1": "y",
23097
+ "15": "y",
23098
+ "16": "y",
23099
+ "17": "y",
23100
+ "18": "y"
23101
+ },
23102
+ "ios_saf": {
23103
+ "3.2": "n",
23104
+ "4.0-4.1": "n",
23105
+ "4.2-4.3": "n",
23106
+ "5.0-5.1": "n",
23107
+ "6.0-6.1": "y",
23108
+ "7.0": "y"
23109
+ },
23110
+ "op_mini": {
23111
+ "5.0-7.0": "n"
23112
+ },
23113
+ "android": {
23114
+ "2.1": "n",
23115
+ "2.2": "n",
23116
+ "2.3": "n",
23117
+ "3": "a x",
23118
+ "4": "a x",
23119
+ "4.1": "a x",
23120
+ "4.2-4.3": "a x",
23121
+ "4.4": "a x"
23122
+ },
23123
+ "bb": {
23124
+ "7": "n",
23125
+ "10": "y"
23126
+ },
23127
+ "op_mob": {
23128
+ "10": "n",
23129
+ "11": "n",
23130
+ "11.1": "n",
23131
+ "11.5": "n",
23132
+ "12": "n",
23133
+ "12.1": "y",
23134
+ "0": "y"
23135
+ },
23136
+ "and_chr": {
23137
+ "0": "a x"
23138
+ },
23139
+ "and_ff": {
23140
+ "0": "y"
23141
+ },
23142
+ "ie_mob": {
23143
+ "10": "y"
23144
+ }
23145
+ },
23146
+ "notes": "Partial support refers to only supporting the now deprecated BlobBuilder to create blobs.",
23147
+ "usage_perc_y": 64.97,
23148
+ "usage_perc_a": 6.3,
23149
+ "ucprefix": true,
23150
+ "parent": "fileapi",
23151
+ "keywords": ""
23152
+ },
23153
+ "filereader": {
23154
+ "title": "FileReader API",
23155
+ "description": "Method of reading the contents of a File or Blob object into memory",
23156
+ "spec": "http://www.w3.org/TR/FileAPI/#dfn-filereader",
23157
+ "status": "wd",
23158
+ "links": [{
23159
+ "url": "http://docs.webplatform.org/wiki/apis/file/FileReader",
23160
+ "title": "WebPlatform Docs"
23161
+ }, {
23162
+ "url": "https://developer.mozilla.org/en/DOM/FileReader",
23163
+ "title": "FileReader API"
23164
+ }],
23165
+ "categories": ["JS API"],
23166
+ "stats": {
23167
+ "ie": {
23168
+ "5.5": "n",
23169
+ "6": "n",
23170
+ "7": "n",
23171
+ "8": "n",
23172
+ "9": "n",
23173
+ "10": "y",
23174
+ "11": "y"
23175
+ },
23176
+ "firefox": {
23177
+ "2": "n",
23178
+ "3": "n",
23179
+ "3.5": "n",
23180
+ "3.6": "y",
23181
+ "4": "y",
23182
+ "5": "y",
23183
+ "6": "y",
23184
+ "7": "y",
23185
+ "8": "y",
23186
+ "9": "y",
23187
+ "10": "y",
23188
+ "11": "y",
23189
+ "12": "y",
23190
+ "13": "y",
23191
+ "14": "y",
23192
+ "15": "y",
23193
+ "16": "y",
23194
+ "17": "y",
23195
+ "18": "y",
23196
+ "19": "y",
23197
+ "20": "y",
23198
+ "21": "y",
23199
+ "22": "y",
23200
+ "23": "y",
23201
+ "24": "y",
23202
+ "25": "y",
23203
+ "26": "y",
23204
+ "27": "y"
23205
+ },
23206
+ "chrome": {
23207
+ "4": "n",
23208
+ "5": "n",
23209
+ "6": "y",
23210
+ "7": "y",
23211
+ "8": "y",
23212
+ "9": "y",
23213
+ "10": "y",
23214
+ "11": "y",
23215
+ "12": "y",
23216
+ "13": "y",
23217
+ "14": "y",
23218
+ "15": "y",
23219
+ "16": "y",
23220
+ "17": "y",
23221
+ "18": "y",
23222
+ "19": "y",
23223
+ "20": "y",
23224
+ "21": "y",
23225
+ "22": "y",
23226
+ "23": "y",
23227
+ "24": "y",
23228
+ "25": "y",
23229
+ "26": "y",
23230
+ "27": "y",
23231
+ "28": "y",
23232
+ "29": "y",
23233
+ "30": "y",
23234
+ "31": "y",
23235
+ "32": "y"
23236
+ },
23237
+ "safari": {
23238
+ "3.1": "n",
23239
+ "3.2": "n",
23240
+ "4": "n",
23241
+ "5": "n",
23242
+ "5.1": "n",
23243
+ "6": "y",
23244
+ "6.1": "y",
23245
+ "7": "y"
23246
+ },
23247
+ "opera": {
23248
+ "9": "n",
23249
+ "9.5-9.6": "n",
23250
+ "10.0-10.1": "n",
23251
+ "10.5": "n",
23252
+ "10.6": "n",
23253
+ "11": "n",
23254
+ "11.1": "y",
23255
+ "11.5": "y",
23256
+ "11.6": "y",
23257
+ "12": "y",
23258
+ "12.1": "y",
23259
+ "15": "y",
23260
+ "16": "y",
23261
+ "17": "y",
23262
+ "18": "y"
23263
+ },
23264
+ "ios_saf": {
23265
+ "3.2": "n",
23266
+ "4.0-4.1": "n",
23267
+ "4.2-4.3": "n",
23268
+ "5.0-5.1": "n",
23269
+ "6.0-6.1": "y",
23270
+ "7.0": "y"
23271
+ },
23272
+ "op_mini": {
23273
+ "5.0-7.0": "n"
23274
+ },
23275
+ "android": {
23276
+ "2.1": "n",
23277
+ "2.2": "n",
23278
+ "2.3": "n",
23279
+ "3": "y",
23280
+ "4": "y",
23281
+ "4.1": "y",
23282
+ "4.2-4.3": "y",
23283
+ "4.4": "y"
23284
+ },
23285
+ "bb": {
23286
+ "7": "n",
23287
+ "10": "y"
23288
+ },
23289
+ "op_mob": {
23290
+ "10": "n",
23291
+ "11": "n",
23292
+ "11.1": "y",
23293
+ "11.5": "y",
23294
+ "12": "y",
23295
+ "12.1": "y",
23296
+ "0": "y"
23297
+ },
23298
+ "and_chr": {
23299
+ "0": "y"
23300
+ },
23301
+ "and_ff": {
23302
+ "0": "y"
23303
+ },
23304
+ "ie_mob": {
23305
+ "10": "y"
23306
+ }
23307
+ },
23308
+ "notes": "",
23309
+ "usage_perc_y": 71.89,
23310
+ "usage_perc_a": 0,
23311
+ "ucprefix": false,
23312
+ "parent": "fileapi",
23313
+ "keywords": ""
23314
+ },
23315
+ "filesystem": {
23316
+ "title": "Filesystem & FileWriter API",
23317
+ "description": "Method of reading and writing files to a sandboxed file system.\r\n",
23318
+ "spec": "http://www.w3.org/TR/file-system-api/",
23319
+ "status": "wd",
23320
+ "links": [{
23321
+ "url": "http://docs.webplatform.org/wiki/apis/filesystem",
23322
+ "title": "WebPlatform Docs"
23323
+ }, {
23324
+ "url": "http://www.html5rocks.com/en/tutorials/file/filesystem/",
23325
+ "title": "HTML5 Rocks tutorial"
23326
+ }],
23327
+ "categories": ["JS API"],
23328
+ "stats": {
23329
+ "ie": {
23330
+ "5.5": "n",
23331
+ "6": "n",
23332
+ "7": "n",
23333
+ "8": "n",
23334
+ "9": "n",
23335
+ "10": "n",
23336
+ "11": "n"
23337
+ },
23338
+ "firefox": {
23339
+ "2": "n",
23340
+ "3": "n",
23341
+ "3.5": "n",
23342
+ "3.6": "n",
23343
+ "4": "n",
23344
+ "5": "n",
23345
+ "6": "n",
23346
+ "7": "n",
23347
+ "8": "n",
23348
+ "9": "n",
23349
+ "10": "n",
23350
+ "11": "n",
23351
+ "12": "n",
23352
+ "13": "n",
23353
+ "14": "n",
23354
+ "15": "n",
23355
+ "16": "n",
23356
+ "17": "n",
23357
+ "18": "n",
23358
+ "19": "n",
23359
+ "20": "n",
23360
+ "21": "n",
23361
+ "22": "n",
23362
+ "23": "n",
23363
+ "24": "n",
23364
+ "25": "n",
23365
+ "26": "n",
23366
+ "27": "n"
23367
+ },
23368
+ "chrome": {
23369
+ "4": "n",
23370
+ "5": "n",
23371
+ "6": "n",
23372
+ "7": "n",
23373
+ "8": "a x",
23374
+ "9": "a x",
23375
+ "10": "a x",
23376
+ "11": "a x",
23377
+ "12": "a x",
23378
+ "13": "y x",
23379
+ "14": "y x",
23380
+ "15": "y x",
23381
+ "16": "y x",
23382
+ "17": "y x",
23383
+ "18": "y x",
23384
+ "19": "y x",
23385
+ "20": "y x",
23386
+ "21": "y x",
23387
+ "22": "y x",
23388
+ "23": "y x",
23389
+ "24": "y x",
23390
+ "25": "y x",
23391
+ "26": "y x",
23392
+ "27": "y x",
23393
+ "28": "y x",
23394
+ "29": "y x",
23395
+ "30": "y x",
23396
+ "31": "y x",
23397
+ "32": "y x"
23398
+ },
23399
+ "safari": {
23400
+ "3.1": "n",
23401
+ "3.2": "n",
23402
+ "4": "n",
23403
+ "5": "n",
23404
+ "5.1": "n",
23405
+ "6": "n",
23406
+ "6.1": "u",
23407
+ "7": "u"
23408
+ },
23409
+ "opera": {
23410
+ "9": "n",
23411
+ "9.5-9.6": "n",
23412
+ "10.0-10.1": "n",
23413
+ "10.5": "n",
23414
+ "10.6": "n",
23415
+ "11": "n",
23416
+ "11.1": "n",
23417
+ "11.5": "n",
23418
+ "11.6": "n",
23419
+ "12": "n",
23420
+ "12.1": "n",
23421
+ "15": "y x",
23422
+ "16": "y x",
23423
+ "17": "y x",
23424
+ "18": "y x"
23425
+ },
23426
+ "ios_saf": {
23427
+ "3.2": "n",
23428
+ "4.0-4.1": "n",
23429
+ "4.2-4.3": "n",
23430
+ "5.0-5.1": "n",
23431
+ "6.0-6.1": "n",
23432
+ "7.0": "n"
23433
+ },
23434
+ "op_mini": {
23435
+ "5.0-7.0": "n"
23436
+ },
23437
+ "android": {
23438
+ "2.1": "n",
23439
+ "2.2": "n",
23440
+ "2.3": "n",
23441
+ "3": "n",
23442
+ "4": "n",
23443
+ "4.1": "n",
23444
+ "4.2-4.3": "n",
23445
+ "4.4": "y x"
23446
+ },
23447
+ "bb": {
23448
+ "7": "n",
23449
+ "10": "y x"
23450
+ },
23451
+ "op_mob": {
23452
+ "10": "n",
23453
+ "11": "n",
23454
+ "11.1": "n",
23455
+ "11.5": "n",
23456
+ "12": "n",
23457
+ "12.1": "n",
23458
+ "0": "y x"
23459
+ },
23460
+ "and_chr": {
23461
+ "0": "y x"
23462
+ },
23463
+ "and_ff": {
23464
+ "0": "n"
23465
+ },
23466
+ "ie_mob": {
23467
+ "10": "n"
23468
+ }
23469
+ },
23470
+ "notes": "",
23471
+ "usage_perc_y": 34.87,
23472
+ "usage_perc_a": 0.28,
23473
+ "ucprefix": false,
23474
+ "parent": "",
23475
+ "keywords": "filewriter"
23476
+ },
23477
+ "bloburls": {
23478
+ "title": "Blob URLs",
23479
+ "description": "Method of creating URL handles to the specified File or Blob object.",
23480
+ "spec": "http://www.w3.org/TR/FileAPI/#url",
23481
+ "status": "wd",
23482
+ "links": [{
23483
+ "url": "https://developer.mozilla.org/en/DOM/window.URL.createObjectURL",
23484
+ "title": "MDN article"
23485
+ }],
23486
+ "categories": ["JS API"],
23487
+ "stats": {
23488
+ "ie": {
23489
+ "5.5": "n",
23490
+ "6": "n",
23491
+ "7": "n",
23492
+ "8": "n",
23493
+ "9": "n",
23494
+ "10": "y",
23495
+ "11": "y"
23496
+ },
23497
+ "firefox": {
23498
+ "2": "n",
23499
+ "3": "n",
23500
+ "3.5": "n",
23501
+ "3.6": "n",
23502
+ "4": "y",
23503
+ "5": "y",
23504
+ "6": "y",
23505
+ "7": "y",
23506
+ "8": "y",
23507
+ "9": "y",
23508
+ "10": "y",
23509
+ "11": "y",
23510
+ "12": "y",
23511
+ "13": "y",
23512
+ "14": "y",
23513
+ "15": "y",
23514
+ "16": "y",
23515
+ "17": "y",
23516
+ "18": "y",
23517
+ "19": "y",
23518
+ "20": "y",
23519
+ "21": "y",
23520
+ "22": "y",
23521
+ "23": "y",
23522
+ "24": "y",
23523
+ "25": "y",
23524
+ "26": "y",
23525
+ "27": "y"
23526
+ },
23527
+ "chrome": {
23528
+ "4": "n",
23529
+ "5": "n",
23530
+ "6": "n",
23531
+ "7": "n",
23532
+ "8": "y x",
23533
+ "9": "y x",
23534
+ "10": "y x",
23535
+ "11": "y x",
23536
+ "12": "y x",
23537
+ "13": "y x",
23538
+ "14": "y x",
23539
+ "15": "y x",
23540
+ "16": "y x",
23541
+ "17": "y x",
23542
+ "18": "y x",
23543
+ "19": "y x",
23544
+ "20": "y x",
23545
+ "21": "y x",
23546
+ "22": "y x",
23547
+ "23": "y",
23548
+ "24": "y",
23549
+ "25": "y",
23550
+ "26": "y",
23551
+ "27": "y",
23552
+ "28": "y",
23553
+ "29": "y",
23554
+ "30": "y",
23555
+ "31": "y",
23556
+ "32": "y"
23557
+ },
23558
+ "safari": {
23559
+ "3.1": "n",
23560
+ "3.2": "n",
23561
+ "4": "n",
23562
+ "5": "n",
23563
+ "5.1": "n",
23564
+ "6": "y x",
23565
+ "6.1": "y",
23566
+ "7": "y"
23567
+ },
23568
+ "opera": {
23569
+ "9": "n",
23570
+ "9.5-9.6": "n",
23571
+ "10.0-10.1": "n",
23572
+ "10.5": "n",
23573
+ "10.6": "n",
23574
+ "11": "n",
23575
+ "11.1": "n",
23576
+ "11.5": "n",
23577
+ "11.6": "n",
23578
+ "12": "n",
23579
+ "12.1": "n",
23580
+ "15": "y",
23581
+ "16": "y",
23582
+ "17": "y",
23583
+ "18": "y"
23584
+ },
23585
+ "ios_saf": {
23586
+ "3.2": "n",
23587
+ "4.0-4.1": "n",
23588
+ "4.2-4.3": "n",
23589
+ "5.0-5.1": "n",
23590
+ "6.0-6.1": "y x",
23591
+ "7.0": "y"
23592
+ },
23593
+ "op_mini": {
23594
+ "5.0-7.0": "n"
23595
+ },
23596
+ "android": {
23597
+ "2.1": "n",
23598
+ "2.2": "n",
23599
+ "2.3": "n",
23600
+ "3": "n",
23601
+ "4": "y x",
23602
+ "4.1": "y x",
23603
+ "4.2-4.3": "y x",
23604
+ "4.4": "y"
23605
+ },
23606
+ "bb": {
23607
+ "7": "n",
23608
+ "10": "y x"
23609
+ },
23610
+ "op_mob": {
23611
+ "10": "n",
23612
+ "11": "n",
23613
+ "11.1": "n",
23614
+ "11.5": "n",
23615
+ "12": "n",
23616
+ "12.1": "n",
23617
+ "0": "y x"
23618
+ },
23619
+ "and_chr": {
23620
+ "0": "y"
23621
+ },
23622
+ "and_ff": {
23623
+ "0": "y"
23624
+ },
23625
+ "ie_mob": {
23626
+ "10": "n"
23627
+ }
23628
+ },
23629
+ "notes": "",
23630
+ "usage_perc_y": 70.6,
23631
+ "usage_perc_a": 0,
23632
+ "ucprefix": false,
23633
+ "parent": "fileapi",
23634
+ "keywords": "createobjecturl"
23635
+ },
23636
+ "typedarrays": {
23637
+ "title": "Typed Arrays",
23638
+ "description": "JavaScript typed arrays provide a mechanism for accessing raw binary data much more efficiently.\r\n",
23639
+ "spec": "http://www.khronos.org/registry/typedarray/specs/latest/",
23640
+ "status": "other",
23641
+ "links": [{
23642
+ "url": "https://developer.mozilla.org/en/javascript_typed_arrays",
23643
+ "title": "MDN article"
23644
+ }],
23645
+ "categories": ["JS API"],
23646
+ "stats": {
23647
+ "ie": {
23648
+ "5.5": "n",
23649
+ "6": "n",
23650
+ "7": "n",
23651
+ "8": "n",
23652
+ "9": "n",
23653
+ "10": "y",
23654
+ "11": "y"
23655
+ },
23656
+ "firefox": {
23657
+ "2": "n",
23658
+ "3": "n",
23659
+ "3.5": "n",
23660
+ "3.6": "n",
23661
+ "4": "y",
23662
+ "5": "y",
23663
+ "6": "y",
23664
+ "7": "y",
23665
+ "8": "y",
23666
+ "9": "y",
23667
+ "10": "y",
23668
+ "11": "y",
23669
+ "12": "y",
23670
+ "13": "y",
23671
+ "14": "y",
23672
+ "15": "y",
23673
+ "16": "y",
23674
+ "17": "y",
23675
+ "18": "y",
23676
+ "19": "y",
23677
+ "20": "y",
23678
+ "21": "y",
23679
+ "22": "y",
23680
+ "23": "y",
23681
+ "24": "y",
23682
+ "25": "y",
23683
+ "26": "y",
23684
+ "27": "y"
23685
+ },
23686
+ "chrome": {
23687
+ "4": "n",
23688
+ "5": "n",
23689
+ "6": "n",
23690
+ "7": "y",
23691
+ "8": "y",
23692
+ "9": "y",
23693
+ "10": "y",
23694
+ "11": "y",
23695
+ "12": "y",
23696
+ "13": "y",
23697
+ "14": "y",
23698
+ "15": "y",
23699
+ "16": "y",
23700
+ "17": "y",
23701
+ "18": "y",
23702
+ "19": "y",
23703
+ "20": "y",
23704
+ "21": "y",
23705
+ "22": "y",
23706
+ "23": "y",
23707
+ "24": "y",
23708
+ "25": "y",
23709
+ "26": "y",
23710
+ "27": "y",
23711
+ "28": "y",
23712
+ "29": "y",
23713
+ "30": "y",
23714
+ "31": "y",
23715
+ "32": "y"
23716
+ },
23717
+ "safari": {
23718
+ "3.1": "n",
23719
+ "3.2": "n",
23720
+ "4": "n",
23721
+ "5": "n",
23722
+ "5.1": "y",
23723
+ "6": "y",
23724
+ "6.1": "y",
23725
+ "7": "y"
23726
+ },
23727
+ "opera": {
23728
+ "9": "n",
23729
+ "9.5-9.6": "n",
23730
+ "10.0-10.1": "n",
23731
+ "10.5": "n",
23732
+ "10.6": "n",
23733
+ "11": "n",
23734
+ "11.1": "n",
23735
+ "11.5": "n",
23736
+ "11.6": "y",
23737
+ "12": "y",
23738
+ "12.1": "y",
23739
+ "15": "y",
23740
+ "16": "y",
23741
+ "17": "y",
23742
+ "18": "y"
23743
+ },
23744
+ "ios_saf": {
23745
+ "3.2": "n",
23746
+ "4.0-4.1": "n",
23747
+ "4.2-4.3": "y",
23748
+ "5.0-5.1": "y",
23749
+ "6.0-6.1": "y",
23750
+ "7.0": "y"
23751
+ },
23752
+ "op_mini": {
23753
+ "5.0-7.0": "n"
23754
+ },
23755
+ "android": {
23756
+ "2.1": "n",
23757
+ "2.2": "n",
23758
+ "2.3": "n",
23759
+ "3": "n",
23760
+ "4": "y",
23761
+ "4.1": "y",
23762
+ "4.2-4.3": "y",
23763
+ "4.4": "y"
23764
+ },
23765
+ "bb": {
23766
+ "7": "n",
23767
+ "10": "y"
23768
+ },
23769
+ "op_mob": {
23770
+ "10": "n",
23771
+ "11": "n",
23772
+ "11.1": "n",
23773
+ "11.5": "n",
23774
+ "12": "y",
23775
+ "12.1": "y",
23776
+ "0": "y"
23777
+ },
23778
+ "and_chr": {
23779
+ "0": "y"
23780
+ },
23781
+ "and_ff": {
23782
+ "0": "y"
23783
+ },
23784
+ "ie_mob": {
23785
+ "10": "y"
23786
+ }
23787
+ },
23788
+ "notes": "",
23789
+ "usage_perc_y": 73.11,
23790
+ "usage_perc_a": 0,
23791
+ "ucprefix": false,
23792
+ "parent": "",
23793
+ "keywords": "float64array,dataview,uint8array"
23794
+ },
23795
+ "deviceorientation": {
23796
+ "title": "DeviceOrientation events",
23797
+ "description": "API for detecting orientation and motion events from the device running the browser.",
23798
+ "spec": "http://www.w3.org/TR/orientation-event/",
23799
+ "status": "wd",
23800
+ "links": [{
23801
+ "url": "http://html5labs.interoperabilitybridges.com/prototypes/device-orientation-events/device-orientation-events/info",
23802
+ "title": "DeviceOrientation implementation prototype for IE10"
23803
+ }, {
23804
+ "url": "http://www.html5rocks.com/en/tutorials/device/orientation/",
23805
+ "title": "HTML5 Rocks tutorial"
23806
+ }, {
23807
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/features.js#native-orientation",
23808
+ "title": "has.js test"
23809
+ }],
23810
+ "categories": ["JS API"],
23811
+ "stats": {
23812
+ "ie": {
23813
+ "5.5": "n",
23814
+ "6": "n",
23815
+ "7": "n",
23816
+ "8": "n",
23817
+ "9": "n",
23818
+ "10": "n",
23819
+ "11": "a"
23820
+ },
23821
+ "firefox": {
23822
+ "2": "n",
23823
+ "3": "n",
23824
+ "3.5": "n",
23825
+ "3.6": "p",
23826
+ "4": "p",
23827
+ "5": "p",
23828
+ "6": "a",
23829
+ "7": "a",
23830
+ "8": "a",
23831
+ "9": "a",
23832
+ "10": "a",
23833
+ "11": "a",
23834
+ "12": "a",
23835
+ "13": "a",
23836
+ "14": "a",
23837
+ "15": "a",
23838
+ "16": "a",
23839
+ "17": "a",
23840
+ "18": "a",
23841
+ "19": "a",
23842
+ "20": "a",
23843
+ "21": "a",
23844
+ "22": "a",
23845
+ "23": "a",
23846
+ "24": "a",
23847
+ "25": "a",
23848
+ "26": "a",
23849
+ "27": "a"
23850
+ },
23851
+ "chrome": {
23852
+ "4": "n",
23853
+ "5": "n",
23854
+ "6": "n",
23855
+ "7": "a",
23856
+ "8": "a",
23857
+ "9": "a",
23858
+ "10": "a",
23859
+ "11": "a",
23860
+ "12": "a",
23861
+ "13": "a",
23862
+ "14": "a",
23863
+ "15": "a",
23864
+ "16": "a",
23865
+ "17": "a",
23866
+ "18": "a",
23867
+ "19": "a",
23868
+ "20": "a",
23869
+ "21": "a",
23870
+ "22": "a",
23871
+ "23": "a",
23872
+ "24": "a",
23873
+ "25": "a",
23874
+ "26": "a",
23875
+ "27": "a",
23876
+ "28": "a",
23877
+ "29": "a",
23878
+ "30": "a",
23879
+ "31": "a",
23880
+ "32": "a"
23881
+ },
23882
+ "safari": {
23883
+ "3.1": "n",
23884
+ "3.2": "n",
23885
+ "4": "n",
23886
+ "5": "n",
23887
+ "5.1": "n",
23888
+ "6": "n",
23889
+ "6.1": "u",
23890
+ "7": "u"
23891
+ },
23892
+ "opera": {
23893
+ "9": "n",
23894
+ "9.5-9.6": "n",
23895
+ "10.0-10.1": "n",
23896
+ "10.5": "n",
23897
+ "10.6": "n",
23898
+ "11": "n",
23899
+ "11.1": "n",
23900
+ "11.5": "n",
23901
+ "11.6": "n",
23902
+ "12": "n",
23903
+ "12.1": "n",
23904
+ "15": "a",
23905
+ "16": "a",
23906
+ "17": "a",
23907
+ "18": "a"
23908
+ },
23909
+ "ios_saf": {
23910
+ "3.2": "n",
23911
+ "4.0-4.1": "n",
23912
+ "4.2-4.3": "a",
23913
+ "5.0-5.1": "a",
23914
+ "6.0-6.1": "a",
23915
+ "7.0": "a"
23916
+ },
23917
+ "op_mini": {
23918
+ "5.0-7.0": "n"
23919
+ },
23920
+ "android": {
23921
+ "2.1": "n",
23922
+ "2.2": "n",
23923
+ "2.3": "n",
23924
+ "3": "a",
23925
+ "4": "a",
23926
+ "4.1": "a",
23927
+ "4.2-4.3": "a",
23928
+ "4.4": "a"
23929
+ },
23930
+ "bb": {
23931
+ "7": "n",
23932
+ "10": "a"
23933
+ },
23934
+ "op_mob": {
23935
+ "10": "n",
23936
+ "11": "n",
23937
+ "11.1": "n",
23938
+ "11.5": "n",
23939
+ "12": "y",
23940
+ "12.1": "y",
23941
+ "0": "a"
23942
+ },
23943
+ "and_chr": {
23944
+ "0": "a"
23945
+ },
23946
+ "and_ff": {
23947
+ "0": "a"
23948
+ },
23949
+ "ie_mob": {
23950
+ "10": "n"
23951
+ }
23952
+ },
23953
+ "notes": "Partial support refers to the lack of compassneedscalibration event. Partial support also refers to the lack of devicemotion event support for Chrome 30- and Opera. Opera Mobile 14 lost the ondevicemotion event support. Firefox 3.6, 4 and 5 support the non-standard <a href=\"https://developer.mozilla.org/en/DOM/MozOrientation\">MozOrientation</a> event.",
23954
+ "usage_perc_y": 0.14,
23955
+ "usage_perc_a": 57.76,
23956
+ "ucprefix": false,
23957
+ "parent": "",
23958
+ "keywords": ""
23959
+ },
23960
+ "script-defer": {
23961
+ "title": "defer attribute for external scripts",
23962
+ "description": "The boolean defer attribute on script elements allows the external JavaScript file to run when the DOM is loaded, without delaying page load first.",
23963
+ "spec": "http://www.w3.org/TR/html5/the-script-element.html#attr-script-defer",
23964
+ "status": "cr",
23965
+ "links": [{
23966
+ "url": "https://developer.mozilla.org/en/HTML/Element/script#Attributes",
23967
+ "title": "MDN article"
23968
+ }, {
23969
+ "url": "http://docs.webplatform.org/wiki/html/attributes/defer",
23970
+ "title": "WebPlatform Docs"
23971
+ }, {
23972
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/script.js#script-defer",
23973
+ "title": "has.js test"
23974
+ }],
23975
+ "categories": ["DOM", "HTML5"],
23976
+ "stats": {
23977
+ "ie": {
23978
+ "5.5": "a",
23979
+ "6": "a",
23980
+ "7": "a",
23981
+ "8": "a",
23982
+ "9": "a",
23983
+ "10": "y",
23984
+ "11": "y"
23985
+ },
23986
+ "firefox": {
23987
+ "2": "n",
23988
+ "3": "n",
23989
+ "3.5": "y",
23990
+ "3.6": "y",
23991
+ "4": "y",
23992
+ "5": "y",
23993
+ "6": "y",
23994
+ "7": "y",
23995
+ "8": "y",
23996
+ "9": "y",
23997
+ "10": "y",
23998
+ "11": "y",
23999
+ "12": "y",
24000
+ "13": "y",
24001
+ "14": "y",
24002
+ "15": "y",
24003
+ "16": "y",
24004
+ "17": "y",
24005
+ "18": "y",
24006
+ "19": "y",
24007
+ "20": "y",
24008
+ "21": "y",
24009
+ "22": "y",
24010
+ "23": "y",
24011
+ "24": "y",
24012
+ "25": "y",
24013
+ "26": "y",
24014
+ "27": "y"
24015
+ },
24016
+ "chrome": {
24017
+ "4": "n",
24018
+ "5": "n",
24019
+ "6": "n",
24020
+ "7": "n",
24021
+ "8": "y",
24022
+ "9": "y",
24023
+ "10": "y",
24024
+ "11": "y",
24025
+ "12": "y",
24026
+ "13": "y",
24027
+ "14": "y",
24028
+ "15": "y",
24029
+ "16": "y",
24030
+ "17": "y",
24031
+ "18": "y",
24032
+ "19": "y",
24033
+ "20": "y",
24034
+ "21": "y",
24035
+ "22": "y",
24036
+ "23": "y",
24037
+ "24": "y",
24038
+ "25": "y",
24039
+ "26": "y",
24040
+ "27": "y",
24041
+ "28": "y",
24042
+ "29": "y",
24043
+ "30": "y",
24044
+ "31": "y",
24045
+ "32": "y"
24046
+ },
24047
+ "safari": {
24048
+ "3.1": "n",
24049
+ "3.2": "n",
24050
+ "4": "n",
24051
+ "5": "y",
24052
+ "5.1": "y",
24053
+ "6": "y",
24054
+ "6.1": "y",
24055
+ "7": "y"
24056
+ },
24057
+ "opera": {
24058
+ "9": "n",
24059
+ "9.5-9.6": "n",
24060
+ "10.0-10.1": "n",
24061
+ "10.5": "n",
24062
+ "10.6": "n",
24063
+ "11": "n",
24064
+ "11.1": "n",
24065
+ "11.5": "n",
24066
+ "11.6": "n",
24067
+ "12": "n",
24068
+ "12.1": "n",
24069
+ "15": "y",
24070
+ "16": "y",
24071
+ "17": "y",
24072
+ "18": "y"
24073
+ },
24074
+ "ios_saf": {
24075
+ "3.2": "n",
24076
+ "4.0-4.1": "n",
24077
+ "4.2-4.3": "n",
24078
+ "5.0-5.1": "y",
24079
+ "6.0-6.1": "y",
24080
+ "7.0": "y"
24081
+ },
24082
+ "op_mini": {
24083
+ "5.0-7.0": "n"
24084
+ },
24085
+ "android": {
24086
+ "2.1": "n",
24087
+ "2.2": "n",
24088
+ "2.3": "n",
24089
+ "3": "y",
24090
+ "4": "y",
24091
+ "4.1": "y",
24092
+ "4.2-4.3": "y",
24093
+ "4.4": "y"
24094
+ },
24095
+ "bb": {
24096
+ "7": "y",
24097
+ "10": "y"
24098
+ },
24099
+ "op_mob": {
24100
+ "10": "n",
24101
+ "11": "n",
24102
+ "11.1": "n",
24103
+ "11.5": "n",
24104
+ "12": "n",
24105
+ "12.1": "n",
24106
+ "0": "y"
24107
+ },
24108
+ "and_chr": {
24109
+ "0": "y"
24110
+ },
24111
+ "and_ff": {
24112
+ "0": "y"
24113
+ },
24114
+ "ie_mob": {
24115
+ "10": "y"
24116
+ }
24117
+ },
24118
+ "notes": "Partial support refers to a buggy implementation in IE<10",
24119
+ "usage_perc_y": 73.17,
24120
+ "usage_perc_a": 14.25,
24121
+ "ucprefix": false,
24122
+ "parent": "",
24123
+ "keywords": ""
24124
+ },
24125
+ "nav-timing": {
24126
+ "title": "Navigation Timing API",
24127
+ "description": "API for accessing timing information related to navigation and elements.",
24128
+ "spec": "http://www.w3.org/TR/navigation-timing/",
24129
+ "status": "cr",
24130
+ "links": [{
24131
+ "url": "https://developer.mozilla.org/en/API/navigationTiming",
24132
+ "title": "MDN article"
24133
+ }, {
24134
+ "url": "http://www.html5rocks.com/en/tutorials/webperformance/basics/",
24135
+ "title": "HTML5 Rocks tutorial"
24136
+ }, {
24137
+ "url": "http://docs.webplatform.org/wiki/apis/navigation_timing",
24138
+ "title": "WebPlatform Docs"
24139
+ }],
24140
+ "categories": ["DOM", "JS API"],
24141
+ "stats": {
24142
+ "ie": {
24143
+ "5.5": "n",
24144
+ "6": "n",
24145
+ "7": "n",
24146
+ "8": "n",
24147
+ "9": "y",
24148
+ "10": "y",
24149
+ "11": "y"
24150
+ },
24151
+ "firefox": {
24152
+ "2": "n",
24153
+ "3": "n",
24154
+ "3.5": "n",
24155
+ "3.6": "n",
24156
+ "4": "n",
24157
+ "5": "n",
24158
+ "6": "n",
24159
+ "7": "y",
24160
+ "8": "y",
24161
+ "9": "y",
24162
+ "10": "y",
24163
+ "11": "y",
24164
+ "12": "y",
24165
+ "13": "y",
24166
+ "14": "y",
24167
+ "15": "y",
24168
+ "16": "y",
24169
+ "17": "y",
24170
+ "18": "y",
24171
+ "19": "y",
24172
+ "20": "y",
24173
+ "21": "y",
24174
+ "22": "y",
24175
+ "23": "y",
24176
+ "24": "y",
24177
+ "25": "y",
24178
+ "26": "y",
24179
+ "27": "y"
24180
+ },
24181
+ "chrome": {
24182
+ "4": "n",
24183
+ "5": "n",
24184
+ "6": "y x",
24185
+ "7": "y x",
24186
+ "8": "y x",
24187
+ "9": "y x",
24188
+ "10": "y x",
24189
+ "11": "y x",
24190
+ "12": "y x",
24191
+ "13": "y",
24192
+ "14": "y",
24193
+ "15": "y",
24194
+ "16": "y",
24195
+ "17": "y",
24196
+ "18": "y",
24197
+ "19": "y",
24198
+ "20": "y",
24199
+ "21": "y",
24200
+ "22": "y",
24201
+ "23": "y",
24202
+ "24": "y",
24203
+ "25": "y",
24204
+ "26": "y",
24205
+ "27": "y",
24206
+ "28": "y",
24207
+ "29": "y",
24208
+ "30": "y",
24209
+ "31": "y",
24210
+ "32": "y"
24211
+ },
24212
+ "safari": {
24213
+ "3.1": "n",
24214
+ "3.2": "n",
24215
+ "4": "n",
24216
+ "5": "n",
24217
+ "5.1": "n",
24218
+ "6": "n",
24219
+ "6.1": "n",
24220
+ "7": "n"
24221
+ },
24222
+ "opera": {
24223
+ "9": "n",
24224
+ "9.5-9.6": "n",
24225
+ "10.0-10.1": "n",
24226
+ "10.5": "n",
24227
+ "10.6": "n",
24228
+ "11": "n",
24229
+ "11.1": "n",
24230
+ "11.5": "n",
24231
+ "11.6": "n",
24232
+ "12": "n",
24233
+ "12.1": "n",
24234
+ "15": "y",
24235
+ "16": "y",
24236
+ "17": "y",
24237
+ "18": "y"
24238
+ },
24239
+ "ios_saf": {
24240
+ "3.2": "n",
24241
+ "4.0-4.1": "n",
24242
+ "4.2-4.3": "n",
24243
+ "5.0-5.1": "n",
24244
+ "6.0-6.1": "n",
24245
+ "7.0": "n"
24246
+ },
24247
+ "op_mini": {
24248
+ "5.0-7.0": "n"
24249
+ },
24250
+ "android": {
24251
+ "2.1": "n",
24252
+ "2.2": "n",
24253
+ "2.3": "n",
24254
+ "3": "n",
24255
+ "4": "y",
24256
+ "4.1": "y",
24257
+ "4.2-4.3": "y",
24258
+ "4.4": "y"
24259
+ },
24260
+ "bb": {
24261
+ "7": "n",
24262
+ "10": "y"
24263
+ },
24264
+ "op_mob": {
24265
+ "10": "n",
24266
+ "11": "n",
24267
+ "11.1": "n",
24268
+ "11.5": "n",
24269
+ "12": "n",
24270
+ "12.1": "n",
24271
+ "0": "y"
24272
+ },
24273
+ "and_chr": {
24274
+ "0": "y"
24275
+ },
24276
+ "and_ff": {
24277
+ "0": "y"
24278
+ },
24279
+ "ie_mob": {
24280
+ "10": "y"
24281
+ }
24282
+ },
24283
+ "notes": "",
24284
+ "usage_perc_y": 69.95,
24285
+ "usage_perc_a": 0,
24286
+ "ucprefix": false,
24287
+ "parent": "",
24288
+ "keywords": "performance,performance.timing"
24289
+ },
24290
+ "audio-api": {
24291
+ "title": "Web Audio API",
24292
+ "description": "High-level JavaScript API for processing and synthesizing audio",
24293
+ "spec": "http://www.w3.org/TR/webaudio/",
24294
+ "status": "wd",
24295
+ "links": [{
24296
+ "url": "http://www.doboism.com/projects/webaudio-compatibility/",
24297
+ "title": "Additional browser compatibility tests for specific features"
24298
+ }, {
24299
+ "url": "http://docs.webplatform.org/wiki/apis/webaudio",
24300
+ "title": "WebPlatform Docs"
24301
+ }, {
24302
+ "url": "https://github.com/corbanbrook/audionode.js",
24303
+ "title": "Polyfill to support Web Audio API in Firefox"
24304
+ }, {
24305
+ "url": "https://github.com/g200kg/WAAPISim",
24306
+ "title": "Polyfill to enable Web Audio API through Firefox Audio Data api or flash"
24307
+ }],
24308
+ "categories": ["JS API"],
24309
+ "stats": {
24310
+ "ie": {
24311
+ "5.5": "n",
24312
+ "6": "n",
24313
+ "7": "n",
24314
+ "8": "n",
24315
+ "9": "n",
24316
+ "10": "n",
24317
+ "11": "n"
24318
+ },
24319
+ "firefox": {
24320
+ "2": "n",
24321
+ "3": "n",
24322
+ "3.5": "n",
24323
+ "3.6": "n",
24324
+ "4": "n",
24325
+ "5": "n",
24326
+ "6": "n",
24327
+ "7": "n",
24328
+ "8": "n",
24329
+ "9": "n",
24330
+ "10": "n",
24331
+ "11": "n",
24332
+ "12": "n",
24333
+ "13": "n",
24334
+ "14": "n",
24335
+ "15": "n",
24336
+ "16": "n",
24337
+ "17": "n",
24338
+ "18": "n",
24339
+ "19": "n",
24340
+ "20": "n",
24341
+ "21": "n",
24342
+ "22": "n",
24343
+ "23": "n",
24344
+ "24": "n",
24345
+ "25": "y",
24346
+ "26": "y",
24347
+ "27": "y"
24348
+ },
24349
+ "chrome": {
24350
+ "4": "n",
24351
+ "5": "n",
24352
+ "6": "n",
24353
+ "7": "n",
24354
+ "8": "n",
24355
+ "9": "n",
24356
+ "10": "y x",
24357
+ "11": "y x",
24358
+ "12": "y x",
24359
+ "13": "y x",
24360
+ "14": "y x",
24361
+ "15": "y x",
24362
+ "16": "y x",
24363
+ "17": "y x",
24364
+ "18": "y x",
24365
+ "19": "y x",
24366
+ "20": "y x",
24367
+ "21": "y x",
24368
+ "22": "y x",
24369
+ "23": "y x",
24370
+ "24": "y x",
24371
+ "25": "y x",
24372
+ "26": "y x",
24373
+ "27": "y x",
24374
+ "28": "y x",
24375
+ "29": "y x",
24376
+ "30": "y x",
24377
+ "31": "y x",
24378
+ "32": "y x"
24379
+ },
24380
+ "safari": {
24381
+ "3.1": "n",
24382
+ "3.2": "n",
24383
+ "4": "n",
24384
+ "5": "n",
24385
+ "5.1": "n",
24386
+ "6": "y x",
24387
+ "6.1": "y x",
24388
+ "7": "y x"
24389
+ },
24390
+ "opera": {
24391
+ "9": "n",
24392
+ "9.5-9.6": "n",
24393
+ "10.0-10.1": "n",
24394
+ "10.5": "n",
24395
+ "10.6": "n",
24396
+ "11": "n",
24397
+ "11.1": "n",
24398
+ "11.5": "n",
24399
+ "11.6": "n",
24400
+ "12": "n",
24401
+ "12.1": "n",
24402
+ "15": "y x",
24403
+ "16": "y x",
24404
+ "17": "y x",
24405
+ "18": "y x"
24406
+ },
24407
+ "ios_saf": {
24408
+ "3.2": "n",
24409
+ "4.0-4.1": "n",
24410
+ "4.2-4.3": "n",
24411
+ "5.0-5.1": "n",
24412
+ "6.0-6.1": "y x",
24413
+ "7.0": "y x"
24414
+ },
24415
+ "op_mini": {
24416
+ "5.0-7.0": "n"
24417
+ },
24418
+ "android": {
24419
+ "2.1": "n",
24420
+ "2.2": "n",
24421
+ "2.3": "n",
24422
+ "3": "n",
24423
+ "4": "n",
24424
+ "4.1": "n",
24425
+ "4.2-4.3": "n",
24426
+ "4.4": "n"
24427
+ },
24428
+ "bb": {
24429
+ "7": "n",
24430
+ "10": "n"
24431
+ },
24432
+ "op_mob": {
24433
+ "10": "n",
24434
+ "11": "n",
24435
+ "11.1": "n",
24436
+ "11.5": "n",
24437
+ "12": "n",
24438
+ "12.1": "n",
24439
+ "0": "n"
24440
+ },
24441
+ "and_chr": {
24442
+ "0": "y x"
24443
+ },
24444
+ "and_ff": {
24445
+ "0": "y"
24446
+ },
24447
+ "ie_mob": {
24448
+ "10": "n"
24449
+ }
24450
+ },
24451
+ "notes": "Firefox versions < 25 support an alternative, deprecated audio API.",
24452
+ "usage_perc_y": 41.68,
24453
+ "usage_perc_a": 0,
24454
+ "ucprefix": false,
24455
+ "parent": "",
24456
+ "keywords": "web-audio"
24457
+ },
24458
+ "css-regions": {
24459
+ "title": "CSS Regions",
24460
+ "description": "Method of flowing content into multiple elements.",
24461
+ "spec": "http://www.w3.org/TR/css3-regions/",
24462
+ "status": "wd",
24463
+ "links": [{
24464
+ "url": "http://msdn.microsoft.com/en-us/ie/hh272902#_CSSConnected",
24465
+ "title": "IE10 developer guide info"
24466
+ }, {
24467
+ "url": "http://html.adobe.com/webstandards/cssregions/",
24468
+ "title": "Adobe demos and samples"
24469
+ }, {
24470
+ "url": "http://docs.webplatform.org/wiki/css/atrules/@region",
24471
+ "title": "WebPlatform Docs"
24472
+ }],
24473
+ "categories": ["CSS3"],
24474
+ "stats": {
24475
+ "ie": {
24476
+ "5.5": "n",
24477
+ "6": "n",
24478
+ "7": "n",
24479
+ "8": "n",
24480
+ "9": "n",
24481
+ "10": "a x",
24482
+ "11": "a x"
24483
+ },
24484
+ "firefox": {
24485
+ "2": "n",
24486
+ "3": "n",
24487
+ "3.5": "n",
24488
+ "3.6": "n",
24489
+ "4": "n",
24490
+ "5": "n",
24491
+ "6": "n",
24492
+ "7": "n",
24493
+ "8": "n",
24494
+ "9": "n",
24495
+ "10": "n",
24496
+ "11": "n",
24497
+ "12": "n",
24498
+ "13": "n",
24499
+ "14": "n",
24500
+ "15": "n",
24501
+ "16": "n",
24502
+ "17": "n",
24503
+ "18": "n",
24504
+ "19": "n",
24505
+ "20": "n",
24506
+ "21": "n",
24507
+ "22": "n",
24508
+ "23": "n",
24509
+ "24": "n",
24510
+ "25": "n",
24511
+ "26": "n",
24512
+ "27": "n"
24513
+ },
24514
+ "chrome": {
24515
+ "4": "n",
24516
+ "5": "n",
24517
+ "6": "n",
24518
+ "7": "n",
24519
+ "8": "n",
24520
+ "9": "n",
24521
+ "10": "n",
24522
+ "11": "n",
24523
+ "12": "n",
24524
+ "13": "n",
24525
+ "14": "n",
24526
+ "15": "a x",
24527
+ "16": "a x",
24528
+ "17": "a x",
24529
+ "18": "a x",
24530
+ "19": "n",
24531
+ "20": "n",
24532
+ "21": "n",
24533
+ "22": "n",
24534
+ "23": "n",
24535
+ "24": "n",
24536
+ "25": "n",
24537
+ "26": "n",
24538
+ "27": "n",
24539
+ "28": "n",
24540
+ "29": "n",
24541
+ "30": "n",
24542
+ "31": "n",
24543
+ "32": "n"
24544
+ },
24545
+ "safari": {
24546
+ "3.1": "n",
24547
+ "3.2": "n",
24548
+ "4": "n",
24549
+ "5": "n",
24550
+ "5.1": "n",
24551
+ "6": "n",
24552
+ "6.1": "y x",
24553
+ "7": "y x"
24554
+ },
24555
+ "opera": {
24556
+ "9": "n",
24557
+ "9.5-9.6": "n",
24558
+ "10.0-10.1": "n",
24559
+ "10.5": "n",
24560
+ "10.6": "n",
24561
+ "11": "n",
24562
+ "11.1": "n",
24563
+ "11.5": "n",
24564
+ "11.6": "n",
24565
+ "12": "n",
24566
+ "12.1": "n",
24567
+ "15": "n",
24568
+ "16": "n",
24569
+ "17": "n",
24570
+ "18": "n"
24571
+ },
24572
+ "ios_saf": {
24573
+ "3.2": "n",
24574
+ "4.0-4.1": "n",
24575
+ "4.2-4.3": "n",
24576
+ "5.0-5.1": "n",
24577
+ "6.0-6.1": "n",
24578
+ "7.0": "y x"
24579
+ },
24580
+ "op_mini": {
24581
+ "5.0-7.0": "n"
24582
+ },
24583
+ "android": {
24584
+ "2.1": "n",
24585
+ "2.2": "n",
24586
+ "2.3": "n",
24587
+ "3": "n",
24588
+ "4": "n",
24589
+ "4.1": "n",
24590
+ "4.2-4.3": "n",
24591
+ "4.4": "n"
24592
+ },
24593
+ "bb": {
24594
+ "7": "n",
24595
+ "10": "n"
24596
+ },
24597
+ "op_mob": {
24598
+ "10": "n",
24599
+ "11": "n",
24600
+ "11.1": "n",
24601
+ "11.5": "n",
24602
+ "12": "n",
24603
+ "12.1": "n",
24604
+ "0": "n"
24605
+ },
24606
+ "and_chr": {
24607
+ "0": "n"
24608
+ },
24609
+ "and_ff": {
24610
+ "0": "n"
24611
+ },
24612
+ "ie_mob": {
24613
+ "10": "a x"
24614
+ }
24615
+ },
24616
+ "notes": "Currently supported in WebKit Nightly using <code>-webkit-flow-into: flow_name;</code> and <code>-webkit-from-flow: flow_name;</code>. Support in Chrome 19+ is disabled by default and can be enabled using a runtime flag (see <code>about:flags</code>) or a command line flag (see <a href=\"http://peter.sh/experiments/chromium-command-line-switches/#enable-css-regions\">this list</a>). For Chrome 19-22 the flag is named \"Enable CSS Regions\" / <code>--enable-css-regions</code>, while for Chrome 23+ the flag is named \"Enable experimental WebKit features\" / <code>--enable-experimental-webkit-features</code>. Support in IE10 is limited to using an iframe as a content source with the <code>-ms-flow-into: flow_name;</code> and <code>-ms-flow-from: flow_name;</code> syntax. Support for Safari 6.1&7 is <a href=\"http://www.broken-links.com/2013/07/10/web-platform-technologies-in-safari-6-1-and-7/\">likely</a> but not official.",
24617
+ "usage_perc_y": 2.75,
24618
+ "usage_perc_a": 11.35,
24619
+ "ucprefix": false,
24620
+ "parent": "",
24621
+ "keywords": ""
24622
+ },
24623
+ "fullscreen": {
24624
+ "title": "Full Screen API",
24625
+ "description": "API for allowing content (like a video or canvas element) to take up the entire screen.",
24626
+ "spec": "http://www.w3.org/TR/fullscreen/",
24627
+ "status": "wd",
24628
+ "links": [{
24629
+ "url": "https://developer.mozilla.org/en/DOM/Using_full-screen_mode",
24630
+ "title": "MDN article"
24631
+ }, {
24632
+ "url": "http://jlongster.com/2011/11/21/canvas.html",
24633
+ "title": "Blog post"
24634
+ }, {
24635
+ "url": "http://hacks.mozilla.org/2012/01/using-the-fullscreen-api-in-web-browsers/",
24636
+ "title": "Mozilla hacks article"
24637
+ }, {
24638
+ "url": "http://docs.webplatform.org/wiki/dom/methods/requestFullscreen",
24639
+ "title": "WebPlatform Docs"
24640
+ }],
24641
+ "categories": ["JS API"],
24642
+ "stats": {
24643
+ "ie": {
24644
+ "5.5": "n",
24645
+ "6": "n",
24646
+ "7": "n",
24647
+ "8": "n",
24648
+ "9": "n",
24649
+ "10": "n",
24650
+ "11": "y x"
24651
+ },
24652
+ "firefox": {
24653
+ "2": "n",
24654
+ "3": "n",
24655
+ "3.5": "n",
24656
+ "3.6": "n",
24657
+ "4": "n",
24658
+ "5": "n",
24659
+ "6": "n",
24660
+ "7": "n",
24661
+ "8": "n",
24662
+ "9": "n",
24663
+ "10": "a x",
24664
+ "11": "a x",
24665
+ "12": "a x",
24666
+ "13": "a x",
24667
+ "14": "a x",
24668
+ "15": "a x",
24669
+ "16": "a x",
24670
+ "17": "a x",
24671
+ "18": "a x",
24672
+ "19": "a x",
24673
+ "20": "a x",
24674
+ "21": "a x",
24675
+ "22": "a x",
24676
+ "23": "a x",
24677
+ "24": "a x",
24678
+ "25": "a x",
24679
+ "26": "a x",
24680
+ "27": "a x"
24681
+ },
24682
+ "chrome": {
24683
+ "4": "n",
24684
+ "5": "n",
24685
+ "6": "n",
24686
+ "7": "n",
24687
+ "8": "n",
24688
+ "9": "n",
24689
+ "10": "n",
24690
+ "11": "n",
24691
+ "12": "n",
24692
+ "13": "n",
24693
+ "14": "n",
24694
+ "15": "a x",
24695
+ "16": "a x",
24696
+ "17": "a x",
24697
+ "18": "a x",
24698
+ "19": "a x",
24699
+ "20": "y x",
24700
+ "21": "y x",
24701
+ "22": "y x",
24702
+ "23": "y x",
24703
+ "24": "y x",
24704
+ "25": "y x",
24705
+ "26": "y x",
24706
+ "27": "y x",
24707
+ "28": "y x",
24708
+ "29": "y x",
24709
+ "30": "y x",
24710
+ "31": "y x",
24711
+ "32": "y x"
24712
+ },
24713
+ "safari": {
24714
+ "3.1": "n",
24715
+ "3.2": "n",
24716
+ "4": "n",
24717
+ "5": "n",
24718
+ "5.1": "a x",
24719
+ "6": "y x",
24720
+ "6.1": "y x",
24721
+ "7": "y x"
24722
+ },
24723
+ "opera": {
24724
+ "9": "n",
24725
+ "9.5-9.6": "n",
24726
+ "10.0-10.1": "n",
24727
+ "10.5": "n",
24728
+ "10.6": "n",
24729
+ "11": "n",
24730
+ "11.1": "n",
24731
+ "11.5": "n",
24732
+ "11.6": "n",
24733
+ "12": "n",
24734
+ "12.1": "y",
24735
+ "15": "y x",
24736
+ "16": "y x",
24737
+ "17": "y x",
24738
+ "18": "y x"
24739
+ },
24740
+ "ios_saf": {
24741
+ "3.2": "n",
24742
+ "4.0-4.1": "n",
24743
+ "4.2-4.3": "n",
24744
+ "5.0-5.1": "n",
24745
+ "6.0-6.1": "n",
24746
+ "7.0": "n"
24747
+ },
24748
+ "op_mini": {
24749
+ "5.0-7.0": "n"
24750
+ },
24751
+ "android": {
24752
+ "2.1": "n",
24753
+ "2.2": "n",
24754
+ "2.3": "n",
24755
+ "3": "n",
24756
+ "4": "n",
24757
+ "4.1": "n",
24758
+ "4.2-4.3": "n",
24759
+ "4.4": "n"
24760
+ },
24761
+ "bb": {
24762
+ "7": "n",
24763
+ "10": "a"
24764
+ },
24765
+ "op_mob": {
24766
+ "10": "n",
24767
+ "11": "n",
24768
+ "11.1": "n",
24769
+ "11.5": "n",
24770
+ "12": "n",
24771
+ "12.1": "n",
24772
+ "0": "y x"
24773
+ },
24774
+ "and_chr": {
24775
+ "0": "y x"
24776
+ },
24777
+ "and_ff": {
24778
+ "0": "a x"
24779
+ },
24780
+ "ie_mob": {
24781
+ "10": "n"
24782
+ }
24783
+ },
24784
+ "notes": "Partial support refers to supporting an earlier draft of the spec.",
24785
+ "usage_perc_y": 37.35,
24786
+ "usage_perc_a": 16.21,
24787
+ "ucprefix": false,
24788
+ "parent": "",
24789
+ "keywords": "full-screen"
24790
+ },
24791
+ "requestanimationframe": {
24792
+ "title": "requestAnimationFrame",
24793
+ "description": "API allowing a more efficient way of running script-based animation, compared to traditional methods using timeouts.",
24794
+ "spec": "http://www.w3.org/TR/animation-timing/#requestAnimationFrame",
24795
+ "status": "wd",
24796
+ "links": [{
24797
+ "url": "http://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/",
24798
+ "title": "Mozilla Hacks article"
24799
+ }, {
24800
+ "url": "http://paulirish.com/2011/requestanimationframe-for-smart-animating/",
24801
+ "title": "Blog post"
24802
+ }, {
24803
+ "url": "http://docs.webplatform.org/wiki/apis/timing/methods/requestAnimationFrame",
24804
+ "title": "WebPlatform Docs"
24805
+ }],
24806
+ "categories": ["JS API"],
24807
+ "stats": {
24808
+ "ie": {
24809
+ "5.5": "n",
24810
+ "6": "n",
24811
+ "7": "n",
24812
+ "8": "n",
24813
+ "9": "n",
24814
+ "10": "y",
24815
+ "11": "y"
24816
+ },
24817
+ "firefox": {
24818
+ "2": "n",
24819
+ "3": "n",
24820
+ "3.5": "n",
24821
+ "3.6": "n",
24822
+ "4": "y x",
24823
+ "5": "y x",
24824
+ "6": "y x",
24825
+ "7": "y x",
24826
+ "8": "y x",
24827
+ "9": "y x",
24828
+ "10": "y x",
24829
+ "11": "y x",
24830
+ "12": "y x",
24831
+ "13": "y x",
24832
+ "14": "y x",
24833
+ "15": "y x",
24834
+ "16": "y x",
24835
+ "17": "y x",
24836
+ "18": "y x",
24837
+ "19": "y x",
24838
+ "20": "y x",
24839
+ "21": "y x",
24840
+ "22": "y x",
24841
+ "23": "y",
24842
+ "24": "y",
24843
+ "25": "y",
24844
+ "26": "y",
24845
+ "27": "y"
24846
+ },
24847
+ "chrome": {
24848
+ "4": "n",
24849
+ "5": "n",
24850
+ "6": "n",
24851
+ "7": "n",
24852
+ "8": "n",
24853
+ "9": "n",
24854
+ "10": "y x",
24855
+ "11": "y x",
24856
+ "12": "y x",
24857
+ "13": "y x",
24858
+ "14": "y x",
24859
+ "15": "y x",
24860
+ "16": "y x",
24861
+ "17": "y x",
24862
+ "18": "y x",
24863
+ "19": "y x",
24864
+ "20": "y x",
24865
+ "21": "y x",
24866
+ "22": "y x",
24867
+ "23": "y x",
24868
+ "24": "y",
24869
+ "25": "y",
24870
+ "26": "y",
24871
+ "27": "y",
24872
+ "28": "y",
24873
+ "29": "y",
24874
+ "30": "y",
24875
+ "31": "y",
24876
+ "32": "y"
24877
+ },
24878
+ "safari": {
24879
+ "3.1": "n",
24880
+ "3.2": "n",
24881
+ "4": "n",
24882
+ "5": "n",
24883
+ "5.1": "n",
24884
+ "6": "y x",
24885
+ "6.1": "y",
24886
+ "7": "y"
24887
+ },
24888
+ "opera": {
24889
+ "9": "n",
24890
+ "9.5-9.6": "n",
24891
+ "10.0-10.1": "n",
24892
+ "10.5": "n",
24893
+ "10.6": "n",
24894
+ "11": "n",
24895
+ "11.1": "n",
24896
+ "11.5": "n",
24897
+ "11.6": "n",
24898
+ "12": "n",
24899
+ "12.1": "n",
24900
+ "15": "y",
24901
+ "16": "y",
24902
+ "17": "y",
24903
+ "18": "y"
24904
+ },
24905
+ "ios_saf": {
24906
+ "3.2": "n",
24907
+ "4.0-4.1": "n",
24908
+ "4.2-4.3": "n",
24909
+ "5.0-5.1": "n",
24910
+ "6.0-6.1": "y x",
24911
+ "7.0": "y"
24912
+ },
24913
+ "op_mini": {
24914
+ "5.0-7.0": "n"
24915
+ },
24916
+ "android": {
24917
+ "2.1": "n",
24918
+ "2.2": "n",
24919
+ "2.3": "n",
24920
+ "3": "n",
24921
+ "4": "n",
24922
+ "4.1": "n",
24923
+ "4.2-4.3": "n",
24924
+ "4.4": "y"
24925
+ },
24926
+ "bb": {
24927
+ "7": "n",
24928
+ "10": "y x"
24929
+ },
24930
+ "op_mob": {
24931
+ "10": "n",
24932
+ "11": "n",
24933
+ "11.1": "n",
24934
+ "11.5": "n",
24935
+ "12": "n",
24936
+ "12.1": "n",
24937
+ "0": "y"
24938
+ },
24939
+ "and_chr": {
24940
+ "0": "y"
24941
+ },
24942
+ "and_ff": {
24943
+ "0": "y x"
24944
+ },
24945
+ "ie_mob": {
24946
+ "10": "y"
24947
+ }
24948
+ },
24949
+ "notes": "",
24950
+ "usage_perc_y": 67.13,
24951
+ "usage_perc_a": 0,
24952
+ "ucprefix": false,
24953
+ "parent": "",
24954
+ "keywords": ""
24955
+ },
24956
+ "input-range": {
24957
+ "title": "Range input type",
24958
+ "description": "Form field type that allows the user to select a value using a slider widget.",
24959
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#range-state-(type=range)",
24960
+ "status": "wd",
24961
+ "links": [{
24962
+ "url": "https://github.com/fryn/html5slider",
24963
+ "title": "Polyfill for Firefox"
24964
+ }, {
24965
+ "url": "http://docs.webplatform.org/wiki/html/elements/input/type/range",
24966
+ "title": "WebPlatform Docs"
24967
+ }, {
24968
+ "url": "http://tutorialzine.com/2011/12/what-you-need-to-know-html5-range-input/",
24969
+ "title": "Tutorial"
24970
+ }, {
24971
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/form.js#input-type-range",
24972
+ "title": "has.js test"
24973
+ }, {
24974
+ "url": "https://github.com/freqdec/fd-slider",
24975
+ "title": "Cross-browser polyfill"
24976
+ }],
24977
+ "categories": ["HTML5"],
24978
+ "stats": {
24979
+ "ie": {
24980
+ "5.5": "n",
24981
+ "6": "n",
24982
+ "7": "n",
24983
+ "8": "n",
24984
+ "9": "n",
24985
+ "10": "y",
24986
+ "11": "y"
24987
+ },
24988
+ "firefox": {
24989
+ "2": "n",
24990
+ "3": "n",
24991
+ "3.5": "n",
24992
+ "3.6": "n",
24993
+ "4": "n",
24994
+ "5": "n",
24995
+ "6": "n",
24996
+ "7": "n",
24997
+ "8": "n",
24998
+ "9": "n",
24999
+ "10": "n",
25000
+ "11": "n",
25001
+ "12": "n",
25002
+ "13": "n",
25003
+ "14": "n",
25004
+ "15": "n",
25005
+ "16": "n",
25006
+ "17": "n",
25007
+ "18": "n",
25008
+ "19": "n",
25009
+ "20": "n",
25010
+ "21": "n",
25011
+ "22": "n",
25012
+ "23": "y",
25013
+ "24": "y",
25014
+ "25": "y",
25015
+ "26": "y",
25016
+ "27": "y"
25017
+ },
25018
+ "chrome": {
25019
+ "4": "u",
25020
+ "5": "y",
25021
+ "6": "y",
25022
+ "7": "y",
25023
+ "8": "y",
25024
+ "9": "y",
25025
+ "10": "y",
25026
+ "11": "y",
25027
+ "12": "y",
25028
+ "13": "y",
25029
+ "14": "y",
25030
+ "15": "y",
25031
+ "16": "y",
25032
+ "17": "y",
25033
+ "18": "y",
25034
+ "19": "y",
25035
+ "20": "y",
25036
+ "21": "y",
25037
+ "22": "y",
25038
+ "23": "y",
25039
+ "24": "y",
25040
+ "25": "y",
25041
+ "26": "y",
25042
+ "27": "y",
25043
+ "28": "y",
25044
+ "29": "y",
25045
+ "30": "y",
25046
+ "31": "y",
25047
+ "32": "y"
25048
+ },
25049
+ "safari": {
25050
+ "3.1": "y",
25051
+ "3.2": "y",
25052
+ "4": "y",
25053
+ "5": "y",
25054
+ "5.1": "y",
25055
+ "6": "y",
25056
+ "6.1": "y",
25057
+ "7": "y"
25058
+ },
25059
+ "opera": {
25060
+ "9": "y",
25061
+ "9.5-9.6": "y",
25062
+ "10.0-10.1": "y",
25063
+ "10.5": "y",
25064
+ "10.6": "y",
25065
+ "11": "y",
25066
+ "11.1": "y",
25067
+ "11.5": "y",
25068
+ "11.6": "y",
25069
+ "12": "y",
25070
+ "12.1": "y",
25071
+ "15": "y",
25072
+ "16": "y",
25073
+ "17": "y",
25074
+ "18": "y"
25075
+ },
25076
+ "ios_saf": {
25077
+ "3.2": "n",
25078
+ "4.0-4.1": "n",
25079
+ "4.2-4.3": "n",
25080
+ "5.0-5.1": "y",
25081
+ "6.0-6.1": "y",
25082
+ "7.0": "y"
25083
+ },
25084
+ "op_mini": {
25085
+ "5.0-7.0": "n"
25086
+ },
25087
+ "android": {
25088
+ "2.1": "a",
25089
+ "2.2": "a",
25090
+ "2.3": "a",
25091
+ "3": "a",
25092
+ "4": "a",
25093
+ "4.1": "a",
25094
+ "4.2-4.3": "y",
25095
+ "4.4": "y"
25096
+ },
25097
+ "bb": {
25098
+ "7": "y",
25099
+ "10": "y"
25100
+ },
25101
+ "op_mob": {
25102
+ "10": "y",
25103
+ "11": "y",
25104
+ "11.1": "y",
25105
+ "11.5": "y",
25106
+ "12": "y",
25107
+ "12.1": "y",
25108
+ "0": "y"
25109
+ },
25110
+ "and_chr": {
25111
+ "0": "y"
25112
+ },
25113
+ "and_ff": {
25114
+ "0": "y"
25115
+ },
25116
+ "ie_mob": {
25117
+ "10": "y"
25118
+ }
25119
+ },
25120
+ "notes": "Currently all Android browsers with partial support hide the slider input field by default. However, the element <a href=\"http://tiffanybbrown.com/2012/02/07/input-typerange-and-androids-stock-browser/\">can be styled</a> to be made visible and usable.",
25121
+ "usage_perc_y": 68.52,
25122
+ "usage_perc_a": 4.31,
25123
+ "ucprefix": false,
25124
+ "parent": "forms",
25125
+ "keywords": ""
25126
+ },
25127
+ "matchmedia": {
25128
+ "title": "matchMedia",
25129
+ "description": "API for finding out whether or not a media query applies to the document.",
25130
+ "spec": "http://www.w3.org/TR/cssom-view/#dom-window-matchmedia",
25131
+ "status": "wd",
25132
+ "links": [{
25133
+ "url": "http://docs.webplatform.org/wiki/css/media_queries/apis/matchMedia",
25134
+ "title": "WebPlatform Docs"
25135
+ }, {
25136
+ "url": "https://github.com/paulirish/matchMedia.js/",
25137
+ "title": "matchMedia.js polyfill"
25138
+ }, {
25139
+ "url": "https://developer.mozilla.org/en/DOM/window.matchMedia",
25140
+ "title": "MDN article"
25141
+ }, {
25142
+ "url": "https://developer.mozilla.org/en/CSS/Using_media_queries_from_code",
25143
+ "title": "MDN tutorial"
25144
+ }],
25145
+ "categories": ["JS API", "DOM"],
25146
+ "stats": {
25147
+ "ie": {
25148
+ "5.5": "n",
25149
+ "6": "n",
25150
+ "7": "n",
25151
+ "8": "n",
25152
+ "9": "n",
25153
+ "10": "y",
25154
+ "11": "y"
25155
+ },
25156
+ "firefox": {
25157
+ "2": "n",
25158
+ "3": "n",
25159
+ "3.5": "n",
25160
+ "3.6": "n",
25161
+ "4": "n",
25162
+ "5": "n",
25163
+ "6": "y",
25164
+ "7": "y",
25165
+ "8": "y",
25166
+ "9": "y",
25167
+ "10": "y",
25168
+ "11": "y",
25169
+ "12": "y",
25170
+ "13": "y",
25171
+ "14": "y",
25172
+ "15": "y",
25173
+ "16": "y",
25174
+ "17": "y",
25175
+ "18": "y",
25176
+ "19": "y",
25177
+ "20": "y",
25178
+ "21": "y",
25179
+ "22": "y",
25180
+ "23": "y",
25181
+ "24": "y",
25182
+ "25": "y",
25183
+ "26": "y",
25184
+ "27": "y"
25185
+ },
25186
+ "chrome": {
25187
+ "4": "n",
25188
+ "5": "n",
25189
+ "6": "n",
25190
+ "7": "n",
25191
+ "8": "n",
25192
+ "9": "y",
25193
+ "10": "y",
25194
+ "11": "y",
25195
+ "12": "y",
25196
+ "13": "y",
25197
+ "14": "y",
25198
+ "15": "y",
25199
+ "16": "y",
25200
+ "17": "y",
25201
+ "18": "y",
25202
+ "19": "y",
25203
+ "20": "y",
25204
+ "21": "y",
25205
+ "22": "y",
25206
+ "23": "y",
25207
+ "24": "y",
25208
+ "25": "y",
25209
+ "26": "y",
25210
+ "27": "y",
25211
+ "28": "y",
25212
+ "29": "y",
25213
+ "30": "y",
25214
+ "31": "y",
25215
+ "32": "y"
25216
+ },
25217
+ "safari": {
25218
+ "3.1": "n",
25219
+ "3.2": "n",
25220
+ "4": "n",
25221
+ "5": "n",
25222
+ "5.1": "y",
25223
+ "6": "y",
25224
+ "6.1": "y",
25225
+ "7": "y"
25226
+ },
25227
+ "opera": {
25228
+ "9": "n",
25229
+ "9.5-9.6": "n",
25230
+ "10.0-10.1": "n",
25231
+ "10.5": "n",
25232
+ "10.6": "n",
25233
+ "11": "n",
25234
+ "11.1": "n",
25235
+ "11.5": "n",
25236
+ "11.6": "n",
25237
+ "12": "n",
25238
+ "12.1": "y",
25239
+ "15": "y",
25240
+ "16": "y",
25241
+ "17": "y",
25242
+ "18": "y"
25243
+ },
25244
+ "ios_saf": {
25245
+ "3.2": "n",
25246
+ "4.0-4.1": "n",
25247
+ "4.2-4.3": "n",
25248
+ "5.0-5.1": "y",
25249
+ "6.0-6.1": "y",
25250
+ "7.0": "y"
25251
+ },
25252
+ "op_mini": {
25253
+ "5.0-7.0": "n"
25254
+ },
25255
+ "android": {
25256
+ "2.1": "n",
25257
+ "2.2": "n",
25258
+ "2.3": "n",
25259
+ "3": "y",
25260
+ "4": "y",
25261
+ "4.1": "y",
25262
+ "4.2-4.3": "y",
25263
+ "4.4": "y"
25264
+ },
25265
+ "bb": {
25266
+ "7": "n",
25267
+ "10": "y"
25268
+ },
25269
+ "op_mob": {
25270
+ "10": "n",
25271
+ "11": "n",
25272
+ "11.1": "n",
25273
+ "11.5": "n",
25274
+ "12": "n",
25275
+ "12.1": "y",
25276
+ "0": "y"
25277
+ },
25278
+ "and_chr": {
25279
+ "0": "y"
25280
+ },
25281
+ "and_ff": {
25282
+ "0": "y"
25283
+ },
25284
+ "ie_mob": {
25285
+ "10": "y"
25286
+ }
25287
+ },
25288
+ "notes": "",
25289
+ "usage_perc_y": 72.81,
25290
+ "usage_perc_a": 0,
25291
+ "ucprefix": false,
25292
+ "parent": "",
25293
+ "keywords": "mediaquerylist"
25294
+ },
25295
+ "input-datetime": {
25296
+ "title": "Date/time input types",
25297
+ "description": "Form field widget to easily allow users to enter dates and/or times, generally by using a calendar widget.",
25298
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#date-state-(type=date)",
25299
+ "status": "wd",
25300
+ "links": [{
25301
+ "url": "http://docs.webplatform.org/wiki/html/elements/input/type/date",
25302
+ "title": "WebPlatform Docs"
25303
+ }, {
25304
+ "url": "http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-browser-datepickers-within-minutes/",
25305
+ "title": "Datepicker tutorial w/polyfill"
25306
+ }, {
25307
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/form.js#input-type-datetime;input-type-datetime-local",
25308
+ "title": "has.js test"
25309
+ }, {
25310
+ "url": "https://github.com/zoltan-dulac/html5Forms.js",
25311
+ "title": "Polyfill for HTML5 forms"
25312
+ }],
25313
+ "categories": ["HTML5"],
25314
+ "stats": {
25315
+ "ie": {
25316
+ "5.5": "n",
25317
+ "6": "n",
25318
+ "7": "n",
25319
+ "8": "n",
25320
+ "9": "n",
25321
+ "10": "n",
25322
+ "11": "n"
25323
+ },
25324
+ "firefox": {
25325
+ "2": "n",
25326
+ "3": "n",
25327
+ "3.5": "n",
25328
+ "3.6": "n",
25329
+ "4": "n",
25330
+ "5": "n",
25331
+ "6": "n",
25332
+ "7": "n",
25333
+ "8": "n",
25334
+ "9": "n",
25335
+ "10": "n",
25336
+ "11": "n",
25337
+ "12": "n",
25338
+ "13": "n",
25339
+ "14": "n",
25340
+ "15": "n",
25341
+ "16": "n",
25342
+ "17": "n",
25343
+ "18": "n",
25344
+ "19": "n",
25345
+ "20": "n",
25346
+ "21": "n",
25347
+ "22": "n",
25348
+ "23": "n",
25349
+ "24": "n",
25350
+ "25": "n",
25351
+ "26": "n",
25352
+ "27": "n"
25353
+ },
25354
+ "chrome": {
25355
+ "4": "n",
25356
+ "5": "n",
25357
+ "6": "n",
25358
+ "7": "n",
25359
+ "8": "n",
25360
+ "9": "n",
25361
+ "10": "n",
25362
+ "11": "n",
25363
+ "12": "n",
25364
+ "13": "n",
25365
+ "14": "n",
25366
+ "15": "n",
25367
+ "16": "n",
25368
+ "17": "n",
25369
+ "18": "n",
25370
+ "19": "n",
25371
+ "20": "a",
25372
+ "21": "a",
25373
+ "22": "a",
25374
+ "23": "a",
25375
+ "24": "a",
25376
+ "25": "a",
25377
+ "26": "a",
25378
+ "27": "a",
25379
+ "28": "a",
25380
+ "29": "a",
25381
+ "30": "a",
25382
+ "31": "a",
25383
+ "32": "a"
25384
+ },
25385
+ "safari": {
25386
+ "3.1": "n",
25387
+ "3.2": "n",
25388
+ "4": "n",
25389
+ "5": "n",
25390
+ "5.1": "n",
25391
+ "6": "n",
25392
+ "6.1": "u",
25393
+ "7": "u"
25394
+ },
25395
+ "opera": {
25396
+ "9": "y",
25397
+ "9.5-9.6": "y",
25398
+ "10.0-10.1": "y",
25399
+ "10.5": "y",
25400
+ "10.6": "y",
25401
+ "11": "y",
25402
+ "11.1": "y",
25403
+ "11.5": "y",
25404
+ "11.6": "y",
25405
+ "12": "y",
25406
+ "12.1": "y",
25407
+ "15": "a",
25408
+ "16": "a",
25409
+ "17": "a",
25410
+ "18": "a"
25411
+ },
25412
+ "ios_saf": {
25413
+ "3.2": "n",
25414
+ "4.0-4.1": "n",
25415
+ "4.2-4.3": "n",
25416
+ "5.0-5.1": "y",
25417
+ "6.0-6.1": "y",
25418
+ "7.0": "y"
25419
+ },
25420
+ "op_mini": {
25421
+ "5.0-7.0": "n"
25422
+ },
25423
+ "android": {
25424
+ "2.1": "n",
25425
+ "2.2": "n",
25426
+ "2.3": "n",
25427
+ "3": "n",
25428
+ "4": "n",
25429
+ "4.1": "n",
25430
+ "4.2-4.3": "n",
25431
+ "4.4": "y"
25432
+ },
25433
+ "bb": {
25434
+ "7": "n",
25435
+ "10": "y"
25436
+ },
25437
+ "op_mob": {
25438
+ "10": "y",
25439
+ "11": "y",
25440
+ "11.1": "y",
25441
+ "11.5": "y",
25442
+ "12": "y",
25443
+ "12.1": "y",
25444
+ "0": "a"
25445
+ },
25446
+ "and_chr": {
25447
+ "0": "y"
25448
+ },
25449
+ "and_ff": {
25450
+ "0": "n"
25451
+ },
25452
+ "ie_mob": {
25453
+ "10": "n"
25454
+ }
25455
+ },
25456
+ "notes": "Safari provides date-formatted text fields, but no real calendar widget. Partial support in Chrome refers to a missing calendar widget for the \"datetime\" type (and other types in older versions). Some modified versions of the Android 4.x browser do have support for date/time fields. ",
25457
+ "usage_perc_y": 6.13,
25458
+ "usage_perc_a": 33.1,
25459
+ "ucprefix": false,
25460
+ "parent": "forms",
25461
+ "keywords": "datepicker,timepicker"
25462
+ },
25463
+ "input-color": {
25464
+ "title": "Color input type",
25465
+ "description": "Form field allowing the user to select a color.",
25466
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#color-state-(type=color)",
25467
+ "status": "wd",
25468
+ "links": [{
25469
+ "url": "http://docs.webplatform.org/wiki/html/elements/input/type/color",
25470
+ "title": "WebPlatform Docs"
25471
+ }, {
25472
+ "url": "http://www.html5tutorial.info/html5-color.php",
25473
+ "title": "Tutorial"
25474
+ }, {
25475
+ "url": "https://github.com/jonstipe/color-polyfill",
25476
+ "title": "Polyfill"
25477
+ }],
25478
+ "categories": ["HTML5"],
25479
+ "stats": {
25480
+ "ie": {
25481
+ "5.5": "n",
25482
+ "6": "n",
25483
+ "7": "n",
25484
+ "8": "n",
25485
+ "9": "n",
25486
+ "10": "n",
25487
+ "11": "n"
25488
+ },
25489
+ "firefox": {
25490
+ "2": "n",
25491
+ "3": "n",
25492
+ "3.5": "n",
25493
+ "3.6": "n",
25494
+ "4": "n",
25495
+ "5": "n",
25496
+ "6": "n",
25497
+ "7": "n",
25498
+ "8": "n",
25499
+ "9": "n",
25500
+ "10": "n",
25501
+ "11": "n",
25502
+ "12": "n",
25503
+ "13": "n",
25504
+ "14": "n",
25505
+ "15": "n",
25506
+ "16": "n",
25507
+ "17": "n",
25508
+ "18": "n",
25509
+ "19": "n",
25510
+ "20": "n",
25511
+ "21": "n",
25512
+ "22": "n",
25513
+ "23": "n",
25514
+ "24": "n",
25515
+ "25": "n",
25516
+ "26": "n",
25517
+ "27": "n"
25518
+ },
25519
+ "chrome": {
25520
+ "4": "n",
25521
+ "5": "n",
25522
+ "6": "n",
25523
+ "7": "n",
25524
+ "8": "n",
25525
+ "9": "n",
25526
+ "10": "n",
25527
+ "11": "n",
25528
+ "12": "n",
25529
+ "13": "n",
25530
+ "14": "n",
25531
+ "15": "n",
25532
+ "16": "n",
25533
+ "17": "n",
25534
+ "18": "n",
25535
+ "19": "n",
25536
+ "20": "y",
25537
+ "21": "y",
25538
+ "22": "y",
25539
+ "23": "y",
25540
+ "24": "y",
25541
+ "25": "y",
25542
+ "26": "y",
25543
+ "27": "y",
25544
+ "28": "y",
25545
+ "29": "y",
25546
+ "30": "y",
25547
+ "31": "y",
25548
+ "32": "y"
25549
+ },
25550
+ "safari": {
25551
+ "3.1": "n",
25552
+ "3.2": "n",
25553
+ "4": "n",
25554
+ "5": "n",
25555
+ "5.1": "n",
25556
+ "6": "n",
25557
+ "6.1": "n",
25558
+ "7": "n"
25559
+ },
25560
+ "opera": {
25561
+ "9": "n",
25562
+ "9.5-9.6": "n",
25563
+ "10.0-10.1": "n",
25564
+ "10.5": "n",
25565
+ "10.6": "n",
25566
+ "11": "y",
25567
+ "11.1": "y",
25568
+ "11.5": "y",
25569
+ "11.6": "y",
25570
+ "12": "y",
25571
+ "12.1": "y",
25572
+ "15": "n",
25573
+ "16": "n",
25574
+ "17": "y",
25575
+ "18": "y"
25576
+ },
25577
+ "ios_saf": {
25578
+ "3.2": "n",
25579
+ "4.0-4.1": "n",
25580
+ "4.2-4.3": "n",
25581
+ "5.0-5.1": "n",
25582
+ "6.0-6.1": "n",
25583
+ "7.0": "n"
25584
+ },
25585
+ "op_mini": {
25586
+ "5.0-7.0": "n"
25587
+ },
25588
+ "android": {
25589
+ "2.1": "n",
25590
+ "2.2": "n",
25591
+ "2.3": "n",
25592
+ "3": "n",
25593
+ "4": "n",
25594
+ "4.1": "n",
25595
+ "4.2-4.3": "n",
25596
+ "4.4": "y"
25597
+ },
25598
+ "bb": {
25599
+ "7": "y",
25600
+ "10": "y"
25601
+ },
25602
+ "op_mob": {
25603
+ "10": "y",
25604
+ "11": "y",
25605
+ "11.1": "y",
25606
+ "11.5": "y",
25607
+ "12": "y",
25608
+ "12.1": "y",
25609
+ "0": "y"
25610
+ },
25611
+ "and_chr": {
25612
+ "0": "y"
25613
+ },
25614
+ "and_ff": {
25615
+ "0": "n"
25616
+ },
25617
+ "ie_mob": {
25618
+ "10": "n"
25619
+ }
25620
+ },
25621
+ "notes": "",
25622
+ "usage_perc_y": 35.22,
25623
+ "usage_perc_a": 0,
25624
+ "ucprefix": false,
25625
+ "parent": "forms",
25626
+ "keywords": "colour"
25627
+ },
25628
+ "input-number": {
25629
+ "title": "Number input type",
25630
+ "description": "Form field type for numbers.",
25631
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#number-state-(type=number)",
25632
+ "status": "wd",
25633
+ "links": [{
25634
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/form.js#input-type-number",
25635
+ "title": "has.js test"
25636
+ }, {
25637
+ "url": "http://www.html5tutorial.info/html5-number.php",
25638
+ "title": "Tutorial"
25639
+ }, {
25640
+ "url": "https://github.com/jonstipe/number-polyfill",
25641
+ "title": "Polyfill"
25642
+ }, {
25643
+ "url": "http://docs.webplatform.org/wiki/html/elements/input/type/number",
25644
+ "title": "WebPlatform Docs"
25645
+ }],
25646
+ "categories": ["HTML5"],
25647
+ "stats": {
25648
+ "ie": {
25649
+ "5.5": "n",
25650
+ "6": "n",
25651
+ "7": "n",
25652
+ "8": "n",
25653
+ "9": "n",
25654
+ "10": "a",
25655
+ "11": "a"
25656
+ },
25657
+ "firefox": {
25658
+ "2": "n",
25659
+ "3": "n",
25660
+ "3.5": "n",
25661
+ "3.6": "n",
25662
+ "4": "n",
25663
+ "5": "n",
25664
+ "6": "n",
25665
+ "7": "n",
25666
+ "8": "n",
25667
+ "9": "n",
25668
+ "10": "n",
25669
+ "11": "n",
25670
+ "12": "n",
25671
+ "13": "n",
25672
+ "14": "n",
25673
+ "15": "n",
25674
+ "16": "n",
25675
+ "17": "n",
25676
+ "18": "n",
25677
+ "19": "n",
25678
+ "20": "n",
25679
+ "21": "n",
25680
+ "22": "n",
25681
+ "23": "n",
25682
+ "24": "n",
25683
+ "25": "n",
25684
+ "26": "n",
25685
+ "27": "n"
25686
+ },
25687
+ "chrome": {
25688
+ "4": "n",
25689
+ "5": "n",
25690
+ "6": "u",
25691
+ "7": "y",
25692
+ "8": "y",
25693
+ "9": "y",
25694
+ "10": "y",
25695
+ "11": "y",
25696
+ "12": "y",
25697
+ "13": "y",
25698
+ "14": "y",
25699
+ "15": "y",
25700
+ "16": "y",
25701
+ "17": "y",
25702
+ "18": "y",
25703
+ "19": "y",
25704
+ "20": "y",
25705
+ "21": "y",
25706
+ "22": "y",
25707
+ "23": "y",
25708
+ "24": "y",
25709
+ "25": "y",
25710
+ "26": "y",
25711
+ "27": "y",
25712
+ "28": "y",
25713
+ "29": "y",
25714
+ "30": "y",
25715
+ "31": "y",
25716
+ "32": "y"
25717
+ },
25718
+ "safari": {
25719
+ "3.1": "n",
25720
+ "3.2": "n",
25721
+ "4": "n",
25722
+ "5": "y",
25723
+ "5.1": "y",
25724
+ "6": "y",
25725
+ "6.1": "y",
25726
+ "7": "y"
25727
+ },
25728
+ "opera": {
25729
+ "9": "y",
25730
+ "9.5-9.6": "y",
25731
+ "10.0-10.1": "y",
25732
+ "10.5": "y",
25733
+ "10.6": "y",
25734
+ "11": "y",
25735
+ "11.1": "y",
25736
+ "11.5": "y",
25737
+ "11.6": "y",
25738
+ "12": "y",
25739
+ "12.1": "y",
25740
+ "15": "y",
25741
+ "16": "y",
25742
+ "17": "y",
25743
+ "18": "y"
25744
+ },
25745
+ "ios_saf": {
25746
+ "3.2": "a",
25747
+ "4.0-4.1": "a",
25748
+ "4.2-4.3": "a",
25749
+ "5.0-5.1": "a",
25750
+ "6.0-6.1": "a",
25751
+ "7.0": "a"
25752
+ },
25753
+ "op_mini": {
25754
+ "5.0-7.0": "n"
25755
+ },
25756
+ "android": {
25757
+ "2.1": "n",
25758
+ "2.2": "n",
25759
+ "2.3": "n",
25760
+ "3": "n",
25761
+ "4": "a",
25762
+ "4.1": "a",
25763
+ "4.2-4.3": "a",
25764
+ "4.4": "a"
25765
+ },
25766
+ "bb": {
25767
+ "7": "n",
25768
+ "10": "a"
25769
+ },
25770
+ "op_mob": {
25771
+ "10": "y",
25772
+ "11": "y",
25773
+ "11.1": "y",
25774
+ "11.5": "y",
25775
+ "12": "y",
25776
+ "12.1": "y",
25777
+ "0": "a"
25778
+ },
25779
+ "and_chr": {
25780
+ "0": "a"
25781
+ },
25782
+ "and_ff": {
25783
+ "0": "n"
25784
+ },
25785
+ "ie_mob": {
25786
+ "10": "a"
25787
+ }
25788
+ },
25789
+ "notes": "iOS Safari, Android 4 and Chrome for Android show number input, but do not use \"step\", \"min\" or \"max\" attributes or show increment/decrement buttons. Internet Explorer 10 does not show increment/decrement buttons.",
25790
+ "usage_perc_y": 38.44,
25791
+ "usage_perc_a": 20.1,
25792
+ "ucprefix": false,
25793
+ "parent": "forms",
25794
+ "keywords": "spinner"
25795
+ },
25796
+ "iframe-sandbox": {
25797
+ "title": "sandbox attribute for iframes",
25798
+ "description": "Method of running external site pages with reduced privileges (e.g. no JavaScript) in iframes",
25799
+ "spec": "http://www.w3.org/TR/html5/the-iframe-element.html#attr-iframe-sandbox",
25800
+ "status": "cr",
25801
+ "links": [{
25802
+ "url": "http://msdn.microsoft.com/en-us/hh563496",
25803
+ "title": "MSDN article"
25804
+ }, {
25805
+ "url": "http://blog.chromium.org/2010/05/security-in-depth-html5s-sandbox.html",
25806
+ "title": "Chromium blog article"
25807
+ }, {
25808
+ "url": "http://docs.webplatform.org/wiki/html/attributes/sandbox",
25809
+ "title": "WebPlatform Docs"
25810
+ }],
25811
+ "categories": ["HTML5"],
25812
+ "stats": {
25813
+ "ie": {
25814
+ "5.5": "n",
25815
+ "6": "n",
25816
+ "7": "n",
25817
+ "8": "n",
25818
+ "9": "n",
25819
+ "10": "y",
25820
+ "11": "y"
25821
+ },
25822
+ "firefox": {
25823
+ "2": "n",
25824
+ "3": "n",
25825
+ "3.5": "n",
25826
+ "3.6": "n",
25827
+ "4": "n",
25828
+ "5": "n",
25829
+ "6": "n",
25830
+ "7": "n",
25831
+ "8": "n",
25832
+ "9": "n",
25833
+ "10": "n",
25834
+ "11": "n",
25835
+ "12": "n",
25836
+ "13": "n",
25837
+ "14": "n",
25838
+ "15": "n",
25839
+ "16": "n",
25840
+ "17": "a",
25841
+ "18": "a",
25842
+ "19": "a",
25843
+ "20": "a",
25844
+ "21": "a",
25845
+ "22": "a",
25846
+ "23": "a",
25847
+ "24": "a",
25848
+ "25": "a",
25849
+ "26": "a",
25850
+ "27": "a"
25851
+ },
25852
+ "chrome": {
25853
+ "4": "y",
25854
+ "5": "y",
25855
+ "6": "y",
25856
+ "7": "y",
25857
+ "8": "y",
25858
+ "9": "y",
25859
+ "10": "y",
25860
+ "11": "y",
25861
+ "12": "y",
25862
+ "13": "y",
25863
+ "14": "y",
25864
+ "15": "y",
25865
+ "16": "y",
25866
+ "17": "y",
25867
+ "18": "y",
25868
+ "19": "y",
25869
+ "20": "y",
25870
+ "21": "y",
25871
+ "22": "y",
25872
+ "23": "y",
25873
+ "24": "y",
25874
+ "25": "y",
25875
+ "26": "y",
25876
+ "27": "y",
25877
+ "28": "y",
25878
+ "29": "y",
25879
+ "30": "y",
25880
+ "31": "y",
25881
+ "32": "y"
25882
+ },
25883
+ "safari": {
25884
+ "3.1": "n",
25885
+ "3.2": "n",
25886
+ "4": "n",
25887
+ "5": "y",
25888
+ "5.1": "y",
25889
+ "6": "y",
25890
+ "6.1": "y",
25891
+ "7": "y"
25892
+ },
25893
+ "opera": {
25894
+ "9": "n",
25895
+ "9.5-9.6": "n",
25896
+ "10.0-10.1": "n",
25897
+ "10.5": "n",
25898
+ "10.6": "n",
25899
+ "11": "n",
25900
+ "11.1": "n",
25901
+ "11.5": "n",
25902
+ "11.6": "n",
25903
+ "12": "n",
25904
+ "12.1": "n",
25905
+ "15": "y",
25906
+ "16": "y",
25907
+ "17": "y",
25908
+ "18": "y"
25909
+ },
25910
+ "ios_saf": {
25911
+ "3.2": "n",
25912
+ "4.0-4.1": "n",
25913
+ "4.2-4.3": "y",
25914
+ "5.0-5.1": "y",
25915
+ "6.0-6.1": "y",
25916
+ "7.0": "y"
25917
+ },
25918
+ "op_mini": {
25919
+ "5.0-7.0": "n"
25920
+ },
25921
+ "android": {
25922
+ "2.1": "n",
25923
+ "2.2": "y",
25924
+ "2.3": "y",
25925
+ "3": "y",
25926
+ "4": "y",
25927
+ "4.1": "y",
25928
+ "4.2-4.3": "y",
25929
+ "4.4": "y"
25930
+ },
25931
+ "bb": {
25932
+ "7": "y",
25933
+ "10": "y"
25934
+ },
25935
+ "op_mob": {
25936
+ "10": "n",
25937
+ "11": "n",
25938
+ "11.1": "n",
25939
+ "11.5": "n",
25940
+ "12": "n",
25941
+ "12.1": "n",
25942
+ "0": "y"
25943
+ },
25944
+ "and_chr": {
25945
+ "0": "y"
25946
+ },
25947
+ "and_ff": {
25948
+ "0": "y"
25949
+ },
25950
+ "ie_mob": {
25951
+ "10": "y"
25952
+ }
25953
+ },
25954
+ "notes": "",
25955
+ "usage_perc_y": 59.45,
25956
+ "usage_perc_a": 13.57,
25957
+ "ucprefix": false,
25958
+ "parent": "",
25959
+ "keywords": ""
25960
+ },
25961
+ "css-counters": {
25962
+ "title": "CSS Counters",
25963
+ "description": "Method of controlling number values in generated content, using the counter-reset and counter-increment properties.",
25964
+ "spec": "http://www.w3.org/TR/CSS21/generate.html#counters",
25965
+ "status": "wd",
25966
+ "links": [{
25967
+ "url": "http://onwebdev.blogspot.com/2012/02/css-counters-tutorial.html",
25968
+ "title": "Tutorial and information"
25969
+ }, {
25970
+ "url": "http://docs.webplatform.org/wiki/css/properties/counter-reset",
25971
+ "title": "WebPlatform Docs"
25972
+ }, {
25973
+ "url": "https://developer.mozilla.org/en/CSS_Counters",
25974
+ "title": "MDN article"
25975
+ }],
25976
+ "categories": ["CSS2"],
25977
+ "stats": {
25978
+ "ie": {
25979
+ "5.5": "n",
25980
+ "6": "n",
25981
+ "7": "n",
25982
+ "8": "y",
25983
+ "9": "y",
25984
+ "10": "y",
25985
+ "11": "y"
25986
+ },
25987
+ "firefox": {
25988
+ "2": "y",
25989
+ "3": "y",
25990
+ "3.5": "y",
25991
+ "3.6": "y",
25992
+ "4": "y",
25993
+ "5": "y",
25994
+ "6": "y",
25995
+ "7": "y",
25996
+ "8": "y",
25997
+ "9": "y",
25998
+ "10": "y",
25999
+ "11": "y",
26000
+ "12": "y",
26001
+ "13": "y",
26002
+ "14": "y",
26003
+ "15": "y",
26004
+ "16": "y",
26005
+ "17": "y",
26006
+ "18": "y",
26007
+ "19": "y",
26008
+ "20": "y",
26009
+ "21": "y",
26010
+ "22": "y",
26011
+ "23": "y",
26012
+ "24": "y",
26013
+ "25": "y",
26014
+ "26": "y",
26015
+ "27": "y"
26016
+ },
26017
+ "chrome": {
26018
+ "4": "y",
26019
+ "5": "y",
26020
+ "6": "y",
26021
+ "7": "y",
26022
+ "8": "y",
26023
+ "9": "y",
26024
+ "10": "y",
26025
+ "11": "y",
26026
+ "12": "y",
26027
+ "13": "y",
26028
+ "14": "y",
26029
+ "15": "y",
26030
+ "16": "y",
26031
+ "17": "y",
26032
+ "18": "y",
26033
+ "19": "y",
26034
+ "20": "y",
26035
+ "21": "y",
26036
+ "22": "y",
26037
+ "23": "y",
26038
+ "24": "y",
26039
+ "25": "y",
26040
+ "26": "y",
26041
+ "27": "y",
26042
+ "28": "y",
26043
+ "29": "y",
26044
+ "30": "y",
26045
+ "31": "y",
26046
+ "32": "y"
26047
+ },
26048
+ "safari": {
26049
+ "3.1": "y",
26050
+ "3.2": "y",
26051
+ "4": "y",
26052
+ "5": "y",
26053
+ "5.1": "y",
26054
+ "6": "y",
26055
+ "6.1": "y",
26056
+ "7": "y"
26057
+ },
26058
+ "opera": {
26059
+ "9": "y",
26060
+ "9.5-9.6": "y",
26061
+ "10.0-10.1": "y",
26062
+ "10.5": "y",
26063
+ "10.6": "y",
26064
+ "11": "y",
26065
+ "11.1": "y",
26066
+ "11.5": "y",
26067
+ "11.6": "y",
26068
+ "12": "y",
26069
+ "12.1": "y",
26070
+ "15": "y",
26071
+ "16": "y",
26072
+ "17": "y",
26073
+ "18": "y"
26074
+ },
26075
+ "ios_saf": {
26076
+ "3.2": "y",
26077
+ "4.0-4.1": "y",
26078
+ "4.2-4.3": "y",
26079
+ "5.0-5.1": "y",
26080
+ "6.0-6.1": "y",
26081
+ "7.0": "y"
26082
+ },
26083
+ "op_mini": {
26084
+ "5.0-7.0": "y"
26085
+ },
26086
+ "android": {
26087
+ "2.1": "y",
26088
+ "2.2": "y",
26089
+ "2.3": "y",
26090
+ "3": "y",
26091
+ "4": "y",
26092
+ "4.1": "y",
26093
+ "4.2-4.3": "y",
26094
+ "4.4": "y"
26095
+ },
26096
+ "bb": {
26097
+ "7": "y",
26098
+ "10": "y"
26099
+ },
26100
+ "op_mob": {
26101
+ "10": "y",
26102
+ "11": "y",
26103
+ "11.1": "y",
26104
+ "11.5": "y",
26105
+ "12": "y",
26106
+ "12.1": "y",
26107
+ "0": "y"
26108
+ },
26109
+ "and_chr": {
26110
+ "0": "y"
26111
+ },
26112
+ "and_ff": {
26113
+ "0": "y"
26114
+ },
26115
+ "ie_mob": {
26116
+ "10": "y"
26117
+ }
26118
+ },
26119
+ "notes": "",
26120
+ "usage_perc_y": 93.86,
26121
+ "usage_perc_a": 0,
26122
+ "ucprefix": false,
26123
+ "parent": "",
26124
+ "keywords": ""
26125
+ },
26126
+ "css-resize": {
26127
+ "title": "CSS resize property",
26128
+ "description": "Method of allowing an element to be resized by the user, with options to limit to a given direction. ",
26129
+ "spec": "http://www.w3.org/TR/css3-ui/#resize",
26130
+ "status": "wd",
26131
+ "links": [{
26132
+ "url": "http://css-tricks.com/almanac/properties/r/resize/",
26133
+ "title": "CSS Tricks info"
26134
+ }, {
26135
+ "url": "http://davidwalsh.name/textarea-resize",
26136
+ "title": "On textarea resizing"
26137
+ }],
26138
+ "categories": ["CSS3"],
26139
+ "stats": {
26140
+ "ie": {
26141
+ "5.5": "n",
26142
+ "6": "n",
26143
+ "7": "n",
26144
+ "8": "n",
26145
+ "9": "n",
26146
+ "10": "n",
26147
+ "11": "n"
26148
+ },
26149
+ "firefox": {
26150
+ "2": "n",
26151
+ "3": "n",
26152
+ "3.5": "n",
26153
+ "3.6": "n",
26154
+ "4": "y x",
26155
+ "5": "y",
26156
+ "6": "y",
26157
+ "7": "y",
26158
+ "8": "y",
26159
+ "9": "y",
26160
+ "10": "y",
26161
+ "11": "y",
26162
+ "12": "y",
26163
+ "13": "y",
26164
+ "14": "y",
26165
+ "15": "y",
26166
+ "16": "y",
26167
+ "17": "y",
26168
+ "18": "y",
26169
+ "19": "y",
26170
+ "20": "y",
26171
+ "21": "y",
26172
+ "22": "y",
26173
+ "23": "y",
26174
+ "24": "y",
26175
+ "25": "y",
26176
+ "26": "y",
26177
+ "27": "y"
26178
+ },
26179
+ "chrome": {
26180
+ "4": "y",
26181
+ "5": "y",
26182
+ "6": "y",
26183
+ "7": "y",
26184
+ "8": "y",
26185
+ "9": "y",
26186
+ "10": "y",
26187
+ "11": "y",
26188
+ "12": "y",
26189
+ "13": "y",
26190
+ "14": "y",
26191
+ "15": "y",
26192
+ "16": "y",
26193
+ "17": "y",
26194
+ "18": "y",
26195
+ "19": "y",
26196
+ "20": "y",
26197
+ "21": "y",
26198
+ "22": "y",
26199
+ "23": "y",
26200
+ "24": "y",
26201
+ "25": "y",
26202
+ "26": "y",
26203
+ "27": "y",
26204
+ "28": "y",
26205
+ "29": "y",
26206
+ "30": "y",
26207
+ "31": "y",
26208
+ "32": "y"
26209
+ },
26210
+ "safari": {
26211
+ "3.1": "n",
26212
+ "3.2": "n",
26213
+ "4": "y",
26214
+ "5": "y",
26215
+ "5.1": "y",
26216
+ "6": "y",
26217
+ "6.1": "y",
26218
+ "7": "y"
26219
+ },
26220
+ "opera": {
26221
+ "9": "n",
26222
+ "9.5-9.6": "n",
26223
+ "10.0-10.1": "n",
26224
+ "10.5": "n",
26225
+ "10.6": "n",
26226
+ "11": "n",
26227
+ "11.1": "n",
26228
+ "11.5": "n",
26229
+ "11.6": "n",
26230
+ "12": "n",
26231
+ "12.1": "a",
26232
+ "15": "y",
26233
+ "16": "y",
26234
+ "17": "y",
26235
+ "18": "y"
26236
+ },
26237
+ "ios_saf": {
26238
+ "3.2": "n",
26239
+ "4.0-4.1": "n",
26240
+ "4.2-4.3": "n",
26241
+ "5.0-5.1": "n",
26242
+ "6.0-6.1": "n",
26243
+ "7.0": "n"
26244
+ },
26245
+ "op_mini": {
26246
+ "5.0-7.0": "n"
26247
+ },
26248
+ "android": {
26249
+ "2.1": "n",
26250
+ "2.2": "n",
26251
+ "2.3": "n",
26252
+ "3": "n",
26253
+ "4": "n",
26254
+ "4.1": "n",
26255
+ "4.2-4.3": "n",
26256
+ "4.4": "n"
26257
+ },
26258
+ "bb": {
26259
+ "7": "n",
26260
+ "10": "n"
26261
+ },
26262
+ "op_mob": {
26263
+ "10": "n",
26264
+ "11": "n",
26265
+ "11.1": "n",
26266
+ "11.5": "n",
26267
+ "12": "n",
26268
+ "12.1": "n",
26269
+ "0": "n"
26270
+ },
26271
+ "and_chr": {
26272
+ "0": "n"
26273
+ },
26274
+ "and_ff": {
26275
+ "0": "y"
26276
+ },
26277
+ "ie_mob": {
26278
+ "10": "n"
26279
+ }
26280
+ },
26281
+ "notes": "Opera 12.10+ currently only supports the resize property for textarea elements.",
26282
+ "usage_perc_y": 52.82,
26283
+ "usage_perc_a": 0.48,
26284
+ "ucprefix": false,
26285
+ "parent": "",
26286
+ "keywords": "horizontal,vertical"
26287
+ },
26288
+ "input-placeholder": {
26289
+ "title": "input placeholder attribute",
26290
+ "description": "Method of setting placeholder text for text-like input fields, to suggest the expected inserted information.",
26291
+ "spec": "http://dev.w3.org/html5/spec/Overview.html#attr-input-placeholder",
26292
+ "status": "cr",
26293
+ "links": [{
26294
+ "url": "http://docs.webplatform.org/wiki/html/attributes/placeholder",
26295
+ "title": "WebPlatform Docs"
26296
+ }, {
26297
+ "url": "https://raw.github.com/phiggins42/has.js/master/detect/form.js#input-attr-placeholder",
26298
+ "title": "has.js test"
26299
+ }, {
26300
+ "url": "http://www.zachleat.com/web/placeholder/",
26301
+ "title": "Article on usage"
26302
+ }, {
26303
+ "url": "https://github.com/mathiasbynens/jquery-placeholder",
26304
+ "title": "Polyfill"
26305
+ }],
26306
+ "categories": ["HTML5"],
26307
+ "stats": {
26308
+ "ie": {
26309
+ "5.5": "n",
26310
+ "6": "n",
26311
+ "7": "n",
26312
+ "8": "n",
26313
+ "9": "n",
26314
+ "10": "y",
26315
+ "11": "y"
26316
+ },
26317
+ "firefox": {
26318
+ "2": "n",
26319
+ "3": "n",
26320
+ "3.5": "n",
26321
+ "3.6": "n",
26322
+ "4": "y",
26323
+ "5": "y",
26324
+ "6": "y",
26325
+ "7": "y",
26326
+ "8": "y",
26327
+ "9": "y",
26328
+ "10": "y",
26329
+ "11": "y",
26330
+ "12": "y",
26331
+ "13": "y",
26332
+ "14": "y",
26333
+ "15": "y",
26334
+ "16": "y",
26335
+ "17": "y",
26336
+ "18": "y",
26337
+ "19": "y",
26338
+ "20": "y",
26339
+ "21": "y",
26340
+ "22": "y",
26341
+ "23": "y",
26342
+ "24": "y",
26343
+ "25": "y",
26344
+ "26": "y",
26345
+ "27": "y"
26346
+ },
26347
+ "chrome": {
26348
+ "4": "y",
26349
+ "5": "y",
26350
+ "6": "y",
26351
+ "7": "y",
26352
+ "8": "y",
26353
+ "9": "y",
26354
+ "10": "y",
26355
+ "11": "y",
26356
+ "12": "y",
26357
+ "13": "y",
26358
+ "14": "y",
26359
+ "15": "y",
26360
+ "16": "y",
26361
+ "17": "y",
26362
+ "18": "y",
26363
+ "19": "y",
26364
+ "20": "y",
26365
+ "21": "y",
26366
+ "22": "y",
26367
+ "23": "y",
26368
+ "24": "y",
26369
+ "25": "y",
26370
+ "26": "y",
26371
+ "27": "y",
26372
+ "28": "y",
26373
+ "29": "y",
26374
+ "30": "y",
26375
+ "31": "y",
26376
+ "32": "y"
26377
+ },
26378
+ "safari": {
26379
+ "3.1": "a",
26380
+ "3.2": "a",
26381
+ "4": "a",
26382
+ "5": "y",
26383
+ "5.1": "y",
26384
+ "6": "y",
26385
+ "6.1": "y",
26386
+ "7": "y"
26387
+ },
26388
+ "opera": {
26389
+ "9": "n",
26390
+ "9.5-9.6": "n",
26391
+ "10.0-10.1": "n",
26392
+ "10.5": "n",
26393
+ "10.6": "n",
26394
+ "11": "a",
26395
+ "11.1": "a",
26396
+ "11.5": "a",
26397
+ "11.6": "y",
26398
+ "12": "y",
26399
+ "12.1": "y",
26400
+ "15": "y",
26401
+ "16": "y",
26402
+ "17": "y",
26403
+ "18": "y"
26404
+ },
26405
+ "ios_saf": {
26406
+ "3.2": "y",
26407
+ "4.0-4.1": "y",
26408
+ "4.2-4.3": "y",
26409
+ "5.0-5.1": "y",
26410
+ "6.0-6.1": "y",
26411
+ "7.0": "y"
26412
+ },
26413
+ "op_mini": {
26414
+ "5.0-7.0": "n"
26415
+ },
26416
+ "android": {
26417
+ "2.1": "y",
26418
+ "2.2": "y",
26419
+ "2.3": "y",
26420
+ "3": "y",
26421
+ "4": "y",
26422
+ "4.1": "y",
26423
+ "4.2-4.3": "y",
26424
+ "4.4": "y"
26425
+ },
26426
+ "bb": {
26427
+ "7": "y",
26428
+ "10": "y"
26429
+ },
26430
+ "op_mob": {
26431
+ "10": "n",
26432
+ "11": "y",
26433
+ "11.1": "y",
26434
+ "11.5": "y",
26435
+ "12": "y",
26436
+ "12.1": "y",
26437
+ "0": "y"
26438
+ },
26439
+ "and_chr": {
26440
+ "0": "y"
26441
+ },
26442
+ "and_ff": {
26443
+ "0": "y"
26444
+ },
26445
+ "ie_mob": {
26446
+ "10": "y"
26447
+ }
26448
+ },
26449
+ "notes": "Partial support in older Safari and Opera versions refers to lacking placeholder support on textarea elements. ",
26450
+ "usage_perc_y": 75.1,
26451
+ "usage_perc_a": 0.15,
26452
+ "ucprefix": false,
26453
+ "parent": "forms",
26454
+ "keywords": ""
26455
+ },
26456
+ "spdy": {
26457
+ "title": "SPDY networking protocol",
26458
+ "description": "Networking protocol for low-latency transport of content over the web.",
26459
+ "spec": "http://tools.ietf.org/html/draft-mbelshe-httpbis-spdy-00",
26460
+ "status": "unoff",
26461
+ "links": [{
26462
+ "url": "http://en.wikipedia.org/wiki/SPDY",
26463
+ "title": "Wikipedia"
26464
+ }, {
26465
+ "url": "http://dev.chromium.org/spdy/spdy-whitepaper",
26466
+ "title": "SPDY whitepaper"
26467
+ }],
26468
+ "categories": ["Other"],
26469
+ "stats": {
26470
+ "ie": {
26471
+ "5.5": "n",
26472
+ "6": "n",
26473
+ "7": "n",
26474
+ "8": "n",
26475
+ "9": "n",
26476
+ "10": "n",
26477
+ "11": "a"
26478
+ },
26479
+ "firefox": {
26480
+ "2": "n",
26481
+ "3": "n",
26482
+ "3.5": "n",
26483
+ "3.6": "n",
26484
+ "4": "n",
26485
+ "5": "n",
26486
+ "6": "n",
26487
+ "7": "n",
26488
+ "8": "n",
26489
+ "9": "n",
26490
+ "10": "n",
26491
+ "11": "n",
26492
+ "12": "n",
26493
+ "13": "y",
26494
+ "14": "y",
26495
+ "15": "y",
26496
+ "16": "y",
26497
+ "17": "y",
26498
+ "18": "y",
26499
+ "19": "y",
26500
+ "20": "y",
26501
+ "21": "y",
26502
+ "22": "y",
26503
+ "23": "y",
26504
+ "24": "y",
26505
+ "25": "y",
26506
+ "26": "y",
26507
+ "27": "y"
26508
+ },
26509
+ "chrome": {
26510
+ "4": "y",
26511
+ "5": "y",
26512
+ "6": "y",
26513
+ "7": "y",
26514
+ "8": "y",
26515
+ "9": "y",
26516
+ "10": "y",
26517
+ "11": "y",
26518
+ "12": "y",
26519
+ "13": "y",
26520
+ "14": "y",
26521
+ "15": "y",
26522
+ "16": "y",
26523
+ "17": "y",
26524
+ "18": "y",
26525
+ "19": "y",
26526
+ "20": "y",
26527
+ "21": "y",
26528
+ "22": "y",
26529
+ "23": "y",
26530
+ "24": "y",
26531
+ "25": "y",
26532
+ "26": "y",
26533
+ "27": "y",
26534
+ "28": "y",
26535
+ "29": "y",
26536
+ "30": "y",
26537
+ "31": "y",
26538
+ "32": "y"
26539
+ },
26540
+ "safari": {
26541
+ "3.1": "n",
26542
+ "3.2": "n",
26543
+ "4": "n",
26544
+ "5": "n",
26545
+ "5.1": "n",
26546
+ "6": "n",
26547
+ "6.1": "u",
26548
+ "7": "u"
26549
+ },
26550
+ "opera": {
26551
+ "9": "n",
26552
+ "9.5-9.6": "n",
26553
+ "10.0-10.1": "n",
26554
+ "10.5": "n",
26555
+ "10.6": "n",
26556
+ "11": "n",
26557
+ "11.1": "n",
26558
+ "11.5": "n",
26559
+ "11.6": "n",
26560
+ "12": "n",
26561
+ "12.1": "y",
26562
+ "15": "y",
26563
+ "16": "y",
26564
+ "17": "y",
26565
+ "18": "y"
26566
+ },
26567
+ "ios_saf": {
26568
+ "3.2": "n",
26569
+ "4.0-4.1": "n",
26570
+ "4.2-4.3": "n",
26571
+ "5.0-5.1": "n",
26572
+ "6.0-6.1": "n",
26573
+ "7.0": "n"
26574
+ },
26575
+ "op_mini": {
26576
+ "5.0-7.0": "n"
26577
+ },
26578
+ "android": {
26579
+ "2.1": "n",
26580
+ "2.2": "n",
26581
+ "2.3": "n",
26582
+ "3": "y",
26583
+ "4": "y",
26584
+ "4.1": "y",
26585
+ "4.2-4.3": "y",
26586
+ "4.4": "y"
26587
+ },
26588
+ "bb": {
26589
+ "7": "n",
26590
+ "10": "u"
26591
+ },
26592
+ "op_mob": {
26593
+ "10": "n",
26594
+ "11": "n",
26595
+ "11.1": "n",
26596
+ "11.5": "n",
26597
+ "12": "n",
26598
+ "12.1": "y",
26599
+ "0": "y"
26600
+ },
26601
+ "and_chr": {
26602
+ "0": "y"
26603
+ },
26604
+ "and_ff": {
26605
+ "0": "y"
26606
+ },
26607
+ "ie_mob": {
26608
+ "10": "n"
26609
+ }
26610
+ },
26611
+ "notes": "",
26612
+ "usage_perc_y": 53.69,
26613
+ "usage_perc_a": 0.11,
26614
+ "ucprefix": false,
26615
+ "parent": "",
26616
+ "keywords": ""
26617
+ },
26618
+ "css-repeating-gradients": {
26619
+ "title": "CSS Repeating Gradients",
26620
+ "description": "Method of defining a repeating linear or radial color gradient as a CSS image.",
26621
+ "spec": "http://www.w3.org/TR/css3-images/#repeating-gradients",
26622
+ "status": "cr",
26623
+ "links": [{
26624
+ "url": "http://docs.webplatform.org/wiki/css/repeating-linear-gradient",
26625
+ "title": "WebPlatform Docs"
26626
+ }, {
26627
+ "url": "https://developer.mozilla.org/en/CSS/repeating-linear-gradient",
26628
+ "title": "MDN article"
26629
+ }, {
26630
+ "url": "http://www.css3files.com/gradient/#repeatinglineargradient",
26631
+ "title": "Information page"
26632
+ }],
26633
+ "categories": ["CSS3"],
26634
+ "stats": {
26635
+ "ie": {
26636
+ "5.5": "n",
26637
+ "6": "n",
26638
+ "7": "n",
26639
+ "8": "n",
26640
+ "9": "n",
26641
+ "10": "y",
26642
+ "11": "y"
26643
+ },
26644
+ "firefox": {
26645
+ "2": "n",
26646
+ "3": "n",
26647
+ "3.5": "n",
26648
+ "3.6": "y x",
26649
+ "4": "y x",
26650
+ "5": "y x",
26651
+ "6": "y x",
26652
+ "7": "y x",
26653
+ "8": "y x",
26654
+ "9": "y x",
26655
+ "10": "y x",
26656
+ "11": "y x",
26657
+ "12": "y x",
26658
+ "13": "y x",
26659
+ "14": "y x",
26660
+ "15": "y x",
26661
+ "16": "y",
26662
+ "17": "y",
26663
+ "18": "y",
26664
+ "19": "y",
26665
+ "20": "y",
26666
+ "21": "y",
26667
+ "22": "y",
26668
+ "23": "y",
26669
+ "24": "y",
26670
+ "25": "y",
26671
+ "26": "y",
26672
+ "27": "y"
26673
+ },
26674
+ "chrome": {
26675
+ "4": "n",
26676
+ "5": "n",
26677
+ "6": "n",
26678
+ "7": "n",
26679
+ "8": "n",
26680
+ "9": "n",
26681
+ "10": "y x",
26682
+ "11": "y x",
26683
+ "12": "y x",
26684
+ "13": "y x",
26685
+ "14": "y x",
26686
+ "15": "y x",
26687
+ "16": "y x",
26688
+ "17": "y x",
26689
+ "18": "y x",
26690
+ "19": "y x",
26691
+ "20": "y x",
26692
+ "21": "y x",
26693
+ "22": "y x",
26694
+ "23": "y x",
26695
+ "24": "y x",
26696
+ "25": "y x",
26697
+ "26": "y",
26698
+ "27": "y",
26699
+ "28": "y",
26700
+ "29": "y",
26701
+ "30": "y",
26702
+ "31": "y",
26703
+ "32": "y"
26704
+ },
26705
+ "safari": {
26706
+ "3.1": "n",
26707
+ "3.2": "n",
26708
+ "4": "n",
26709
+ "5": "n",
26710
+ "5.1": "y x",
26711
+ "6": "y x",
26712
+ "6.1": "y",
26713
+ "7": "y"
26714
+ },
26715
+ "opera": {
26716
+ "9": "n",
26717
+ "9.5-9.6": "n",
26718
+ "10.0-10.1": "n",
26719
+ "10.5": "n",
26720
+ "10.6": "n",
26721
+ "11": "n",
26722
+ "11.1": "a x",
26723
+ "11.5": "a x",
26724
+ "11.6": "y x",
26725
+ "12": "y x",
26726
+ "12.1": "y",
26727
+ "15": "y",
26728
+ "16": "y",
26729
+ "17": "y",
26730
+ "18": "y"
26731
+ },
26732
+ "ios_saf": {
26733
+ "3.2": "n",
26734
+ "4.0-4.1": "n",
26735
+ "4.2-4.3": "n",
26736
+ "5.0-5.1": "y x",
26737
+ "6.0-6.1": "y x",
26738
+ "7.0": "y"
26739
+ },
26740
+ "op_mini": {
26741
+ "5.0-7.0": "n"
26742
+ },
26743
+ "android": {
26744
+ "2.1": "n",
26745
+ "2.2": "n",
26746
+ "2.3": "n",
26747
+ "3": "n",
26748
+ "4": "y x",
26749
+ "4.1": "y x",
26750
+ "4.2-4.3": "y x",
26751
+ "4.4": "y"
26752
+ },
26753
+ "bb": {
26754
+ "7": "n",
26755
+ "10": "y x"
26756
+ },
26757
+ "op_mob": {
26758
+ "10": "n",
26759
+ "11": "n",
26760
+ "11.1": "a x",
26761
+ "11.5": "a x",
26762
+ "12": "y x",
26763
+ "12.1": "y",
26764
+ "0": "y"
26765
+ },
26766
+ "and_chr": {
26767
+ "0": "y"
26768
+ },
26769
+ "and_ff": {
26770
+ "0": "y x"
26771
+ },
26772
+ "ie_mob": {
26773
+ "10": "y"
26774
+ }
26775
+ },
26776
+ "notes": "Firefox 10+, Chrome 26+ and Opera 11.6+ also support the new \"to (side)\" syntax.",
26777
+ "usage_perc_y": 73.31,
26778
+ "usage_perc_a": 0.03,
26779
+ "ucprefix": false,
26780
+ "parent": "css-gradients",
26781
+ "keywords": ""
26782
+ },
26783
+ "css-filters": {
26784
+ "title": "CSS Filter Effects",
26785
+ "description": "Method of applying filter effects (like blur, grayscale, brightness, contrast and hue) to elements, previously only possible by using SVG.",
26786
+ "spec": "http://www.w3.org/TR/filter-effects/",
26787
+ "status": "wd",
26788
+ "links": [{
26789
+ "url": "http://dl.dropbox.com/u/3260327/angular/CSS3ImageManipulation.html",
26790
+ "title": "Filter editor"
26791
+ }, {
26792
+ "url": "http://bennettfeely.com/filters/",
26793
+ "title": "Filter Playground"
26794
+ }, {
26795
+ "url": "http://html5-demos.appspot.com/static/css/filters/index.html",
26796
+ "title": "Demo file for WebKit browsers"
26797
+ }, {
26798
+ "url": "http://www.html5rocks.com/en/tutorials/filters/understanding-css/",
26799
+ "title": "Mozilla hacks article"
26800
+ }],
26801
+ "categories": ["CSS3", "CSS"],
26802
+ "stats": {
26803
+ "ie": {
26804
+ "5.5": "n",
26805
+ "6": "n",
26806
+ "7": "n",
26807
+ "8": "n",
26808
+ "9": "n",
26809
+ "10": "n",
26810
+ "11": "n"
26811
+ },
26812
+ "firefox": {
26813
+ "2": "n",
26814
+ "3": "n",
26815
+ "3.5": "n",
26816
+ "3.6": "n",
26817
+ "4": "n",
26818
+ "5": "n",
26819
+ "6": "n",
26820
+ "7": "n",
26821
+ "8": "n",
26822
+ "9": "n",
26823
+ "10": "n",
26824
+ "11": "n",
26825
+ "12": "n",
26826
+ "13": "n",
26827
+ "14": "n",
26828
+ "15": "n",
26829
+ "16": "n",
26830
+ "17": "n",
26831
+ "18": "n",
26832
+ "19": "n",
26833
+ "20": "n",
26834
+ "21": "n",
26835
+ "22": "n",
26836
+ "23": "n",
26837
+ "24": "n",
26838
+ "25": "n",
26839
+ "26": "u",
26840
+ "27": "u"
26841
+ },
26842
+ "chrome": {
26843
+ "4": "n",
26844
+ "5": "n",
26845
+ "6": "n",
26846
+ "7": "n",
26847
+ "8": "n",
26848
+ "9": "n",
26849
+ "10": "n",
26850
+ "11": "n",
26851
+ "12": "n",
26852
+ "13": "n",
26853
+ "14": "n",
26854
+ "15": "n",
26855
+ "16": "n",
26856
+ "17": "n",
26857
+ "18": "y x",
26858
+ "19": "y x",
26859
+ "20": "y x",
26860
+ "21": "y x",
26861
+ "22": "y x",
26862
+ "23": "y x",
26863
+ "24": "y x",
26864
+ "25": "y x",
26865
+ "26": "y x",
26866
+ "27": "y x",
26867
+ "28": "y x",
26868
+ "29": "y x",
26869
+ "30": "y x",
26870
+ "31": "y x",
26871
+ "32": "y x"
26872
+ },
26873
+ "safari": {
26874
+ "3.1": "n",
26875
+ "3.2": "n",
26876
+ "4": "n",
26877
+ "5": "n",
26878
+ "5.1": "n",
26879
+ "6": "y x",
26880
+ "6.1": "y x",
26881
+ "7": "y x"
26882
+ },
26883
+ "opera": {
26884
+ "9": "n",
26885
+ "9.5-9.6": "n",
26886
+ "10.0-10.1": "n",
26887
+ "10.5": "n",
26888
+ "10.6": "n",
26889
+ "11": "n",
26890
+ "11.1": "n",
26891
+ "11.5": "n",
26892
+ "11.6": "n",
26893
+ "12": "n",
26894
+ "12.1": "n",
26895
+ "15": "y x",
26896
+ "16": "y x",
26897
+ "17": "y x",
26898
+ "18": "y x"
26899
+ },
26900
+ "ios_saf": {
26901
+ "3.2": "n",
26902
+ "4.0-4.1": "n",
26903
+ "4.2-4.3": "n",
26904
+ "5.0-5.1": "n",
26905
+ "6.0-6.1": "y x",
26906
+ "7.0": "y x"
26907
+ },
26908
+ "op_mini": {
26909
+ "5.0-7.0": "n"
26910
+ },
26911
+ "android": {
26912
+ "2.1": "n",
26913
+ "2.2": "n",
26914
+ "2.3": "n",
26915
+ "3": "n",
26916
+ "4": "n",
26917
+ "4.1": "n",
26918
+ "4.2-4.3": "n",
26919
+ "4.4": "y x"
26920
+ },
26921
+ "bb": {
26922
+ "7": "n",
26923
+ "10": "y x"
26924
+ },
26925
+ "op_mob": {
26926
+ "10": "n",
26927
+ "11": "n",
26928
+ "11.1": "n",
26929
+ "11.5": "n",
26930
+ "12": "n",
26931
+ "12.1": "n",
26932
+ "0": "y x"
26933
+ },
26934
+ "and_chr": {
26935
+ "0": "y x"
26936
+ },
26937
+ "and_ff": {
26938
+ "0": "n"
26939
+ },
26940
+ "ie_mob": {
26941
+ "10": "n"
26942
+ }
26943
+ },
26944
+ "notes": "Note that this property is significantly different from and incompatible with Microsoft's <a href=\"http://msdn.microsoft.com/en-us/library/ie/ms530752%28v=vs.85%29.aspx\">older \"filter\" property</a>.",
26945
+ "usage_perc_y": 40.55,
26946
+ "usage_perc_a": 0,
26947
+ "ucprefix": false,
26948
+ "parent": "",
26949
+ "keywords": "sepia,hue-rotate,invert,saturate"
26950
+ },
26951
+ "getcomputedstyle": {
26952
+ "title": "getComputedStyle",
26953
+ "description": "API to get the current computed CSS styles applied to an element. This may be the current value applied by an animation or as set by a stylesheet.",
26954
+ "spec": "http://www.w3.org/TR/cssom/#dom-window-getcomputedstyle",
26955
+ "status": "rec",
26956
+ "links": [{
26957
+ "url": "http://ie.microsoft.com/testdrive/HTML5/getComputedStyle/",
26958
+ "title": "Demo"
26959
+ }, {
26960
+ "url": "http://snipplr.com/view/13523/",
26961
+ "title": "Polyfill for IE"
26962
+ }, {
26963
+ "url": "https://developer.mozilla.org/en/DOM/window.getComputedStyle",
26964
+ "title": "MDN article"
26965
+ }, {
26966
+ "url": "http://docs.webplatform.org/wiki/css/cssom/methods/getComputedStyle",
26967
+ "title": "WebPlatform Docs"
26968
+ }],
26969
+ "categories": ["JS API", "CSS3", "DOM"],
26970
+ "stats": {
26971
+ "ie": {
26972
+ "5.5": "n",
26973
+ "6": "n",
26974
+ "7": "n",
26975
+ "8": "n",
26976
+ "9": "y",
26977
+ "10": "y",
26978
+ "11": "y"
26979
+ },
26980
+ "firefox": {
26981
+ "2": "n",
26982
+ "3": "a",
26983
+ "3.5": "a",
26984
+ "3.6": "a",
26985
+ "4": "y",
26986
+ "5": "y",
26987
+ "6": "y",
26988
+ "7": "y",
26989
+ "8": "y",
26990
+ "9": "y",
26991
+ "10": "y",
26992
+ "11": "y",
26993
+ "12": "y",
26994
+ "13": "y",
26995
+ "14": "y",
26996
+ "15": "y",
26997
+ "16": "y",
26998
+ "17": "y",
26999
+ "18": "y",
27000
+ "19": "y",
27001
+ "20": "y",
27002
+ "21": "y",
27003
+ "22": "y",
27004
+ "23": "y",
27005
+ "24": "y",
27006
+ "25": "y",
27007
+ "26": "y",
27008
+ "27": "y"
27009
+ },
27010
+ "chrome": {
27011
+ "4": "a",
27012
+ "5": "a",
27013
+ "6": "a",
27014
+ "7": "a",
27015
+ "8": "a",
27016
+ "9": "a",
27017
+ "10": "a",
27018
+ "11": "y",
27019
+ "12": "y",
27020
+ "13": "y",
27021
+ "14": "y",
27022
+ "15": "y",
27023
+ "16": "y",
27024
+ "17": "y",
27025
+ "18": "y",
27026
+ "19": "y",
27027
+ "20": "y",
27028
+ "21": "y",
27029
+ "22": "y",
27030
+ "23": "y",
27031
+ "24": "y",
27032
+ "25": "y",
27033
+ "26": "y",
27034
+ "27": "y",
27035
+ "28": "y",
27036
+ "29": "y",
27037
+ "30": "y",
27038
+ "31": "y",
27039
+ "32": "y"
27040
+ },
27041
+ "safari": {
27042
+ "3.1": "a",
27043
+ "3.2": "a",
27044
+ "4": "a",
27045
+ "5": "y",
27046
+ "5.1": "y",
27047
+ "6": "y",
27048
+ "6.1": "y",
27049
+ "7": "y"
27050
+ },
27051
+ "opera": {
27052
+ "9": "a",
27053
+ "9.5-9.6": "a",
27054
+ "10.0-10.1": "a",
27055
+ "10.5": "a",
27056
+ "10.6": "y",
27057
+ "11": "y",
27058
+ "11.1": "y",
27059
+ "11.5": "y",
27060
+ "11.6": "y",
27061
+ "12": "y",
27062
+ "12.1": "y",
27063
+ "15": "y",
27064
+ "16": "y",
27065
+ "17": "y",
27066
+ "18": "y"
27067
+ },
27068
+ "ios_saf": {
27069
+ "3.2": "a",
27070
+ "4.0-4.1": "a",
27071
+ "4.2-4.3": "a",
27072
+ "5.0-5.1": "y",
27073
+ "6.0-6.1": "y",
27074
+ "7.0": "y"
27075
+ },
27076
+ "op_mini": {
27077
+ "5.0-7.0": "a"
27078
+ },
27079
+ "android": {
27080
+ "2.1": "a",
27081
+ "2.2": "a",
27082
+ "2.3": "a",
27083
+ "3": "a",
27084
+ "4": "y",
27085
+ "4.1": "y",
27086
+ "4.2-4.3": "y",
27087
+ "4.4": "y"
27088
+ },
27089
+ "bb": {
27090
+ "7": "a",
27091
+ "10": "y"
27092
+ },
27093
+ "op_mob": {
27094
+ "10": "a",
27095
+ "11": "y",
27096
+ "11.1": "y",
27097
+ "11.5": "y",
27098
+ "12": "y",
27099
+ "12.1": "y",
27100
+ "0": "y"
27101
+ },
27102
+ "and_chr": {
27103
+ "0": "y"
27104
+ },
27105
+ "and_ff": {
27106
+ "0": "y"
27107
+ },
27108
+ "ie_mob": {
27109
+ "10": "y"
27110
+ }
27111
+ },
27112
+ "notes": "Partial support in older Firefox versions refers to requiring the second parameter to be included. Partial support in all other browsers refers to not supporting getComputedStyle on pseudo-elements.",
27113
+ "usage_perc_y": 78.53,
27114
+ "usage_perc_a": 7,
27115
+ "ucprefix": false,
27116
+ "parent": "",
27117
+ "keywords": ""
27118
+ },
27119
+ "word-break": {
27120
+ "title": "CSS3 word-break",
27121
+ "description": "Property to prevent or allow words to be broken over multiple lines between letters.",
27122
+ "spec": "http://www.w3.org/TR/css3-text/#word-break",
27123
+ "status": "wd",
27124
+ "links": [{
27125
+ "url": "http://docs.webplatform.org/wiki/css/properties/word-break",
27126
+ "title": "WebPlatform Docs"
27127
+ }, {
27128
+ "url": "https://developer.mozilla.org/en/CSS/word-break",
27129
+ "title": "MDN article"
27130
+ }],
27131
+ "categories": ["CSS3"],
27132
+ "stats": {
27133
+ "ie": {
27134
+ "5.5": "y",
27135
+ "6": "y",
27136
+ "7": "y",
27137
+ "8": "y",
27138
+ "9": "y",
27139
+ "10": "y",
27140
+ "11": "y"
27141
+ },
27142
+ "firefox": {
27143
+ "2": "n",
27144
+ "3": "n",
27145
+ "3.5": "n",
27146
+ "3.6": "n",
27147
+ "4": "n",
27148
+ "5": "n",
27149
+ "6": "n",
27150
+ "7": "n",
27151
+ "8": "n",
27152
+ "9": "n",
27153
+ "10": "n",
27154
+ "11": "n",
27155
+ "12": "n",
27156
+ "13": "n",
27157
+ "14": "n",
27158
+ "15": "y",
27159
+ "16": "y",
27160
+ "17": "y",
27161
+ "18": "y",
27162
+ "19": "y",
27163
+ "20": "y",
27164
+ "21": "y",
27165
+ "22": "y",
27166
+ "23": "y",
27167
+ "24": "y",
27168
+ "25": "y",
27169
+ "26": "y",
27170
+ "27": "y"
27171
+ },
27172
+ "chrome": {
27173
+ "4": "a",
27174
+ "5": "a",
27175
+ "6": "a",
27176
+ "7": "a",
27177
+ "8": "a",
27178
+ "9": "a",
27179
+ "10": "a",
27180
+ "11": "a",
27181
+ "12": "a",
27182
+ "13": "a",
27183
+ "14": "a",
27184
+ "15": "a",
27185
+ "16": "a",
27186
+ "17": "a",
27187
+ "18": "a",
27188
+ "19": "a",
27189
+ "20": "a",
27190
+ "21": "a",
27191
+ "22": "a",
27192
+ "23": "a",
27193
+ "24": "a",
27194
+ "25": "a",
27195
+ "26": "a",
27196
+ "27": "a",
27197
+ "28": "a",
27198
+ "29": "a",
27199
+ "30": "a",
27200
+ "31": "a",
27201
+ "32": "a"
27202
+ },
27203
+ "safari": {
27204
+ "3.1": "a",
27205
+ "3.2": "a",
27206
+ "4": "a",
27207
+ "5": "a",
27208
+ "5.1": "a",
27209
+ "6": "a",
27210
+ "6.1": "a",
27211
+ "7": "a"
27212
+ },
27213
+ "opera": {
27214
+ "9": "n",
27215
+ "9.5-9.6": "n",
27216
+ "10.0-10.1": "n",
27217
+ "10.5": "n",
27218
+ "10.6": "n",
27219
+ "11": "n",
27220
+ "11.1": "n",
27221
+ "11.5": "n",
27222
+ "11.6": "n",
27223
+ "12": "n",
27224
+ "12.1": "n",
27225
+ "15": "a",
27226
+ "16": "a",
27227
+ "17": "a",
27228
+ "18": "a"
27229
+ },
27230
+ "ios_saf": {
27231
+ "3.2": "a",
27232
+ "4.0-4.1": "a",
27233
+ "4.2-4.3": "a",
27234
+ "5.0-5.1": "a",
27235
+ "6.0-6.1": "a",
27236
+ "7.0": "a"
27237
+ },
27238
+ "op_mini": {
27239
+ "5.0-7.0": "n"
27240
+ },
27241
+ "android": {
27242
+ "2.1": "a",
27243
+ "2.2": "a",
27244
+ "2.3": "a",
27245
+ "3": "a",
27246
+ "4": "a",
27247
+ "4.1": "a",
27248
+ "4.2-4.3": "a",
27249
+ "4.4": "a"
27250
+ },
27251
+ "bb": {
27252
+ "7": "a",
27253
+ "10": "a"
27254
+ },
27255
+ "op_mob": {
27256
+ "10": "n",
27257
+ "11": "n",
27258
+ "11.1": "n",
27259
+ "11.5": "n",
27260
+ "12": "n",
27261
+ "12.1": "n",
27262
+ "0": "a"
27263
+ },
27264
+ "and_chr": {
27265
+ "0": "a"
27266
+ },
27267
+ "and_ff": {
27268
+ "0": "y"
27269
+ },
27270
+ "ie_mob": {
27271
+ "10": "y"
27272
+ }
27273
+ },
27274
+ "notes": "Partial support refers to supporting the \"break-all\" value, but not the \"keep-all\" value.",
27275
+ "usage_perc_y": 39.39,
27276
+ "usage_perc_a": 48.42,
27277
+ "ucprefix": false,
27278
+ "parent": "",
27279
+ "keywords": "break-all,keep-all"
27280
+ },
27281
+ "viewport-units": {
27282
+ "title": "Viewport units: vw, vh, vmin, vmax",
27283
+ "description": "Length units representing 1% of the viewport size for viewport width (vw), height (vh), the smaller of the two (vmin), or the larger of the two (vmax).",
27284
+ "spec": "http://www.w3.org/TR/css3-values/#viewport-relative-lengths",
27285
+ "status": "cr",
27286
+ "links": [{
27287
+ "url": "http://css-tricks.com/viewport-sized-typography/",
27288
+ "title": "Blog post"
27289
+ }, {
27290
+ "url": "https://github.com/saabi/vminpoly",
27291
+ "title": "Polyfill"
27292
+ }],
27293
+ "categories": ["CSS3"],
27294
+ "stats": {
27295
+ "ie": {
27296
+ "5.5": "n",
27297
+ "6": "n",
27298
+ "7": "n",
27299
+ "8": "n",
27300
+ "9": "a",
27301
+ "10": "a",
27302
+ "11": "y"
27303
+ },
27304
+ "firefox": {
27305
+ "2": "n",
27306
+ "3": "n",
27307
+ "3.5": "n",
27308
+ "3.6": "n",
27309
+ "4": "n",
27310
+ "5": "n",
27311
+ "6": "n",
27312
+ "7": "n",
27313
+ "8": "n",
27314
+ "9": "n",
27315
+ "10": "n",
27316
+ "11": "n",
27317
+ "12": "n",
27318
+ "13": "n",
27319
+ "14": "n",
27320
+ "15": "n",
27321
+ "16": "n",
27322
+ "17": "n",
27323
+ "18": "n",
27324
+ "19": "y",
27325
+ "20": "y",
27326
+ "21": "y",
27327
+ "22": "y",
27328
+ "23": "y",
27329
+ "24": "y",
27330
+ "25": "y",
27331
+ "26": "y",
27332
+ "27": "y"
27333
+ },
27334
+ "chrome": {
27335
+ "4": "n",
27336
+ "5": "n",
27337
+ "6": "n",
27338
+ "7": "n",
27339
+ "8": "n",
27340
+ "9": "n",
27341
+ "10": "n",
27342
+ "11": "n",
27343
+ "12": "n",
27344
+ "13": "n",
27345
+ "14": "n",
27346
+ "15": "n",
27347
+ "16": "n",
27348
+ "17": "n",
27349
+ "18": "n",
27350
+ "19": "n",
27351
+ "20": "a",
27352
+ "21": "a",
27353
+ "22": "a",
27354
+ "23": "a",
27355
+ "24": "a",
27356
+ "25": "a",
27357
+ "26": "y",
27358
+ "27": "y",
27359
+ "28": "y",
27360
+ "29": "y",
27361
+ "30": "y",
27362
+ "31": "y",
27363
+ "32": "y"
27364
+ },
27365
+ "safari": {
27366
+ "3.1": "n",
27367
+ "3.2": "n",
27368
+ "4": "n",
27369
+ "5": "n",
27370
+ "5.1": "n",
27371
+ "6": "a",
27372
+ "6.1": "a",
27373
+ "7": "a"
27374
+ },
27375
+ "opera": {
27376
+ "9": "n",
27377
+ "9.5-9.6": "n",
27378
+ "10.0-10.1": "n",
27379
+ "10.5": "n",
27380
+ "10.6": "n",
27381
+ "11": "n",
27382
+ "11.1": "n",
27383
+ "11.5": "n",
27384
+ "11.6": "n",
27385
+ "12": "n",
27386
+ "12.1": "n",
27387
+ "15": "y",
27388
+ "16": "y",
27389
+ "17": "y",
27390
+ "18": "y"
27391
+ },
27392
+ "ios_saf": {
27393
+ "3.2": "n",
27394
+ "4.0-4.1": "n",
27395
+ "4.2-4.3": "n",
27396
+ "5.0-5.1": "n",
27397
+ "6.0-6.1": "a",
27398
+ "7.0": "y"
27399
+ },
27400
+ "op_mini": {
27401
+ "5.0-7.0": "n"
27402
+ },
27403
+ "android": {
27404
+ "2.1": "n",
27405
+ "2.2": "n",
27406
+ "2.3": "n",
27407
+ "3": "n",
27408
+ "4": "n",
27409
+ "4.1": "n",
27410
+ "4.2-4.3": "n",
27411
+ "4.4": "y"
27412
+ },
27413
+ "bb": {
27414
+ "7": "n",
27415
+ "10": "a"
27416
+ },
27417
+ "op_mob": {
27418
+ "10": "n",
27419
+ "11": "n",
27420
+ "11.1": "n",
27421
+ "11.5": "n",
27422
+ "12": "n",
27423
+ "12.1": "n",
27424
+ "0": "y"
27425
+ },
27426
+ "and_chr": {
27427
+ "0": "y"
27428
+ },
27429
+ "and_ff": {
27430
+ "0": "y"
27431
+ },
27432
+ "ie_mob": {
27433
+ "10": "a"
27434
+ }
27435
+ },
27436
+ "notes": "Partial support in IE9 refers to supporting \"vm\" instead of \"vmin\". All other partial support refers to not supporting the \"vmax\" unit.",
27437
+ "usage_perc_y": 48.9,
27438
+ "usage_perc_a": 21.18,
27439
+ "ucprefix": false,
27440
+ "parent": "",
27441
+ "keywords": "vm,viewport-percentage"
27442
+ },
27443
+ "contentsecuritypolicy": {
27444
+ "title": "Content Security Policy",
27445
+ "description": "Mitigate cross-site scripting attacks by whitelisting allowed sources of script, style, and other resources.",
27446
+ "spec": "http://www.w3.org/TR/CSP/",
27447
+ "status": "cr",
27448
+ "links": [{
27449
+ "url": "http://content-security-policy.com/",
27450
+ "title": "CSP Examples & Quick Reference"
27451
+ }, {
27452
+ "url": "http://html5rocks.com/en/tutorials/security/content-security-policy/",
27453
+ "title": "HTML5Rocks article"
27454
+ }],
27455
+ "categories": ["Other"],
27456
+ "stats": {
27457
+ "ie": {
27458
+ "5.5": "n",
27459
+ "6": "n",
27460
+ "7": "n",
27461
+ "8": "n",
27462
+ "9": "n",
27463
+ "10": "a x",
27464
+ "11": "a x"
27465
+ },
27466
+ "firefox": {
27467
+ "2": "n",
27468
+ "3": "n",
27469
+ "3.5": "n",
27470
+ "3.6": "n",
27471
+ "4": "y x",
27472
+ "5": "y x",
27473
+ "6": "y x",
27474
+ "7": "y x",
27475
+ "8": "y x",
27476
+ "9": "y x",
27477
+ "10": "y x",
27478
+ "11": "y x",
27479
+ "12": "y x",
27480
+ "13": "y x",
27481
+ "14": "y x",
27482
+ "15": "y x",
27483
+ "16": "y x",
27484
+ "17": "y x",
27485
+ "18": "y x",
27486
+ "19": "y x",
27487
+ "20": "y x",
27488
+ "21": "y x",
27489
+ "22": "y x",
27490
+ "23": "y",
27491
+ "24": "y",
27492
+ "25": "y",
27493
+ "26": "y",
27494
+ "27": "y"
27495
+ },
27496
+ "chrome": {
27497
+ "4": "n",
27498
+ "5": "n",
27499
+ "6": "n",
27500
+ "7": "n",
27501
+ "8": "n",
27502
+ "9": "n",
27503
+ "10": "n",
27504
+ "11": "n",
27505
+ "12": "n",
27506
+ "13": "n",
27507
+ "14": "y x",
27508
+ "15": "y x",
27509
+ "16": "y x",
27510
+ "17": "y x",
27511
+ "18": "y x",
27512
+ "19": "y x",
27513
+ "20": "y x",
27514
+ "21": "y x",
27515
+ "22": "y x",
27516
+ "23": "y x",
27517
+ "24": "y x",
27518
+ "25": "y",
27519
+ "26": "y",
27520
+ "27": "y",
27521
+ "28": "y",
27522
+ "29": "y",
27523
+ "30": "y",
27524
+ "31": "y",
27525
+ "32": "y"
27526
+ },
27527
+ "safari": {
27528
+ "3.1": "n",
27529
+ "3.2": "n",
27530
+ "4": "n",
27531
+ "5": "n",
27532
+ "5.1": "a x",
27533
+ "6": "y x",
27534
+ "6.1": "y x",
27535
+ "7": "y x"
27536
+ },
27537
+ "opera": {
27538
+ "9": "n",
27539
+ "9.5-9.6": "n",
27540
+ "10.0-10.1": "n",
27541
+ "10.5": "n",
27542
+ "10.6": "n",
27543
+ "11": "n",
27544
+ "11.1": "n",
27545
+ "11.5": "n",
27546
+ "11.6": "n",
27547
+ "12": "n",
27548
+ "12.1": "n",
27549
+ "15": "y",
27550
+ "16": "y",
27551
+ "17": "y",
27552
+ "18": "y"
27553
+ },
27554
+ "ios_saf": {
27555
+ "3.2": "n",
27556
+ "4.0-4.1": "n",
27557
+ "4.2-4.3": "n",
27558
+ "5.0-5.1": "a x",
27559
+ "6.0-6.1": "y x",
27560
+ "7.0": "y x"
27561
+ },
27562
+ "op_mini": {
27563
+ "5.0-7.0": "n"
27564
+ },
27565
+ "android": {
27566
+ "2.1": "n",
27567
+ "2.2": "n",
27568
+ "2.3": "n",
27569
+ "3": "n",
27570
+ "4": "n",
27571
+ "4.1": "n",
27572
+ "4.2-4.3": "n",
27573
+ "4.4": "y"
27574
+ },
27575
+ "bb": {
27576
+ "7": "n",
27577
+ "10": "y x"
27578
+ },
27579
+ "op_mob": {
27580
+ "10": "n",
27581
+ "11": "n",
27582
+ "11.1": "n",
27583
+ "11.5": "n",
27584
+ "12": "n",
27585
+ "12.1": "n",
27586
+ "0": "y"
27587
+ },
27588
+ "and_chr": {
27589
+ "0": "y"
27590
+ },
27591
+ "and_ff": {
27592
+ "0": "y x"
27593
+ },
27594
+ "ie_mob": {
27595
+ "10": "a x"
27596
+ }
27597
+ },
27598
+ "notes": "The HTTP header is 'X-Content-Security-Policy' for Firefox and IE 10&11, and 'X-WebKit-CSP' for Safari and Chrome. IE 10&11's support is limited to the 'sandbox' directive.",
27599
+ "usage_perc_y": 55.74,
27600
+ "usage_perc_a": 12.68,
27601
+ "ucprefix": false,
27602
+ "parent": "",
27603
+ "keywords": "csp,security,header"
27604
+ },
27605
+ "pagevisibility": {
27606
+ "title": "PageVisibility",
27607
+ "description": "JavaScript API for determining whether a document is visible on the display",
27608
+ "spec": "http://www.w3.org/TR/page-visibility/",
27609
+ "status": "cr",
27610
+ "links": [{
27611
+ "url": "https://developer.mozilla.org/en-US/docs/DOM/Using_the_Page_Visibility_API",
27612
+ "title": "MDN article"
27613
+ }, {
27614
+ "url": "http://docs.webplatform.org/wiki/apis/timing/properties/visibilityState",
27615
+ "title": "WebPlatform Docs"
27616
+ }],
27617
+ "categories": ["JS API"],
27618
+ "stats": {
27619
+ "ie": {
27620
+ "5.5": "n",
27621
+ "6": "n",
27622
+ "7": "n",
27623
+ "8": "n",
27624
+ "9": "n",
27625
+ "10": "y",
27626
+ "11": "y"
27627
+ },
27628
+ "firefox": {
27629
+ "2": "n",
27630
+ "3": "n",
27631
+ "3.5": "n",
27632
+ "3.6": "n",
27633
+ "4": "n",
27634
+ "5": "n",
27635
+ "6": "n",
27636
+ "7": "n",
27637
+ "8": "n",
27638
+ "9": "n",
27639
+ "10": "y x",
27640
+ "11": "y x",
27641
+ "12": "y x",
27642
+ "13": "y x",
27643
+ "14": "y x",
27644
+ "15": "y x",
27645
+ "16": "y x",
27646
+ "17": "y x",
27647
+ "18": "y",
27648
+ "19": "y",
27649
+ "20": "y",
27650
+ "21": "y",
27651
+ "22": "y",
27652
+ "23": "y",
27653
+ "24": "y",
27654
+ "25": "y",
27655
+ "26": "y",
27656
+ "27": "y"
27657
+ },
27658
+ "chrome": {
27659
+ "4": "n",
27660
+ "5": "n",
27661
+ "6": "n",
27662
+ "7": "n",
27663
+ "8": "n",
27664
+ "9": "n",
27665
+ "10": "n",
27666
+ "11": "n",
27667
+ "12": "n",
27668
+ "13": "n",
27669
+ "14": "y x",
27670
+ "15": "y x",
27671
+ "16": "y x",
27672
+ "17": "y x",
27673
+ "18": "y x",
27674
+ "19": "y x",
27675
+ "20": "y x",
27676
+ "21": "y x",
27677
+ "22": "y x",
27678
+ "23": "y x",
27679
+ "24": "y x",
27680
+ "25": "y x",
27681
+ "26": "y x",
27682
+ "27": "y x",
27683
+ "28": "y x",
27684
+ "29": "y x",
27685
+ "30": "y x",
27686
+ "31": "y x",
27687
+ "32": "y x"
27688
+ },
27689
+ "safari": {
27690
+ "3.1": "n",
27691
+ "3.2": "n",
27692
+ "4": "n",
27693
+ "5": "n",
27694
+ "5.1": "n",
27695
+ "6": "n",
27696
+ "6.1": "y",
27697
+ "7": "y"
27698
+ },
27699
+ "opera": {
27700
+ "9": "n",
27701
+ "9.5-9.6": "n",
27702
+ "10.0-10.1": "n",
27703
+ "10.5": "n",
27704
+ "10.6": "n",
27705
+ "11": "n",
27706
+ "11.1": "n",
27707
+ "11.5": "n",
27708
+ "11.6": "n",
27709
+ "12": "n",
27710
+ "12.1": "y",
27711
+ "15": "y x",
27712
+ "16": "y x",
27713
+ "17": "y x",
27714
+ "18": "y x"
27715
+ },
27716
+ "ios_saf": {
27717
+ "3.2": "n",
27718
+ "4.0-4.1": "n",
27719
+ "4.2-4.3": "n",
27720
+ "5.0-5.1": "n",
27721
+ "6.0-6.1": "n",
27722
+ "7.0": "y"
27723
+ },
27724
+ "op_mini": {
27725
+ "5.0-7.0": "n"
27726
+ },
27727
+ "android": {
27728
+ "2.1": "n",
27729
+ "2.2": "n",
27730
+ "2.3": "n",
27731
+ "3": "n",
27732
+ "4": "n",
27733
+ "4.1": "n",
27734
+ "4.2-4.3": "n",
27735
+ "4.4": "y x"
27736
+ },
27737
+ "bb": {
27738
+ "7": "n",
27739
+ "10": "y x"
27740
+ },
27741
+ "op_mob": {
27742
+ "10": "n",
27743
+ "11": "n",
27744
+ "11.1": "n",
27745
+ "11.5": "n",
27746
+ "12": "n",
27747
+ "12.1": "y",
27748
+ "0": "y x"
27749
+ },
27750
+ "and_chr": {
27751
+ "0": "y x"
27752
+ },
27753
+ "and_ff": {
27754
+ "0": "y"
27755
+ },
27756
+ "ie_mob": {
27757
+ "10": "y"
27758
+ }
27759
+ },
27760
+ "notes": "",
27761
+ "usage_perc_y": 63.89,
27762
+ "usage_perc_a": 0,
27763
+ "ucprefix": false,
27764
+ "parent": "",
27765
+ "keywords": "visibilitystate"
27766
+ },
27767
+ "stricttransportsecurity": {
27768
+ "title": "Strict Transport Security",
27769
+ "description": "Declare that a website is only accessible over a secure connection (HTTPS).",
27770
+ "spec": "http://tools.ietf.org/html/rfc6797",
27771
+ "status": "other",
27772
+ "links": [{
27773
+ "url": "http://dev.chromium.org/sts",
27774
+ "title": "Strict Transport Security @ Chromium"
27775
+ }, {
27776
+ "url": "https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security",
27777
+ "title": "Strict Transport Security @ Mozilla Developer Network"
27778
+ }],
27779
+ "categories": ["Other"],
27780
+ "stats": {
27781
+ "ie": {
27782
+ "5.5": "n",
27783
+ "6": "n",
27784
+ "7": "n",
27785
+ "8": "n",
27786
+ "9": "n",
27787
+ "10": "n",
27788
+ "11": "n"
27789
+ },
27790
+ "firefox": {
27791
+ "2": "n",
27792
+ "3": "n",
27793
+ "3.5": "n",
27794
+ "3.6": "n",
27795
+ "4": "y",
27796
+ "5": "y",
27797
+ "6": "y",
27798
+ "7": "y",
27799
+ "8": "y",
27800
+ "9": "y",
27801
+ "10": "y",
27802
+ "11": "y",
27803
+ "12": "y",
27804
+ "13": "y",
27805
+ "14": "y",
27806
+ "15": "y",
27807
+ "16": "y",
27808
+ "17": "y",
27809
+ "18": "y",
27810
+ "19": "y",
27811
+ "20": "y",
27812
+ "21": "y",
27813
+ "22": "y",
27814
+ "23": "y",
27815
+ "24": "y",
27816
+ "25": "y",
27817
+ "26": "y",
27818
+ "27": "y"
27819
+ },
27820
+ "chrome": {
27821
+ "4": "y",
27822
+ "5": "y",
27823
+ "6": "y",
27824
+ "7": "y",
27825
+ "8": "y",
27826
+ "9": "y",
27827
+ "10": "y",
27828
+ "11": "y",
27829
+ "12": "y",
27830
+ "13": "y",
27831
+ "14": "y",
27832
+ "15": "y",
27833
+ "16": "y",
27834
+ "17": "y",
27835
+ "18": "y",
27836
+ "19": "y",
27837
+ "20": "y",
27838
+ "21": "y",
27839
+ "22": "y",
27840
+ "23": "y",
27841
+ "24": "y",
27842
+ "25": "y",
27843
+ "26": "y",
27844
+ "27": "y",
27845
+ "28": "y",
27846
+ "29": "y",
27847
+ "30": "y",
27848
+ "31": "y",
27849
+ "32": "y"
27850
+ },
27851
+ "safari": {
27852
+ "3.1": "n",
27853
+ "3.2": "n",
27854
+ "4": "n",
27855
+ "5": "n",
27856
+ "5.1": "n",
27857
+ "6": "n",
27858
+ "6.1": "u",
27859
+ "7": "u"
27860
+ },
27861
+ "opera": {
27862
+ "9": "n",
27863
+ "9.5-9.6": "n",
27864
+ "10.0-10.1": "n",
27865
+ "10.5": "n",
27866
+ "10.6": "n",
27867
+ "11": "n",
27868
+ "11.1": "n",
27869
+ "11.5": "n",
27870
+ "11.6": "n",
27871
+ "12": "y",
27872
+ "12.1": "y",
27873
+ "15": "y",
27874
+ "16": "y",
27875
+ "17": "y",
27876
+ "18": "y"
27877
+ },
27878
+ "ios_saf": {
27879
+ "3.2": "n",
27880
+ "4.0-4.1": "n",
27881
+ "4.2-4.3": "n",
27882
+ "5.0-5.1": "n",
27883
+ "6.0-6.1": "n",
27884
+ "7.0": "u"
27885
+ },
27886
+ "op_mini": {
27887
+ "5.0-7.0": "n"
27888
+ },
27889
+ "android": {
27890
+ "2.1": "n",
27891
+ "2.2": "n",
27892
+ "2.3": "n",
27893
+ "3": "n",
27894
+ "4": "n",
27895
+ "4.1": "n",
27896
+ "4.2-4.3": "n",
27897
+ "4.4": "y"
27898
+ },
27899
+ "bb": {
27900
+ "7": "n",
27901
+ "10": "n"
27902
+ },
27903
+ "op_mob": {
27904
+ "10": "n",
27905
+ "11": "n",
27906
+ "11.1": "n",
27907
+ "11.5": "n",
27908
+ "12": "n",
27909
+ "12.1": "n",
27910
+ "0": "y"
27911
+ },
27912
+ "and_chr": {
27913
+ "0": "y"
27914
+ },
27915
+ "and_ff": {
27916
+ "0": "y"
27917
+ },
27918
+ "ie_mob": {
27919
+ "10": "n"
27920
+ }
27921
+ },
27922
+ "notes": "The HTTP header is 'Strict-Transport-Security'.",
27923
+ "usage_perc_y": 50.76,
27924
+ "usage_perc_a": 0,
27925
+ "ucprefix": false,
27926
+ "parent": "",
27927
+ "keywords": "sts,hsts,security,header"
27928
+ },
27929
+ "style-scoped": {
27930
+ "title": "Scoped CSS",
27931
+ "description": "Allows CSS rules to be scoped to part of the document, based on the position of the style element.",
27932
+ "spec": "http://www.w3.org/TR/html5/document-metadata.html#attr-style-scoped",
27933
+ "status": "cr",
27934
+ "links": [{
27935
+ "url": "https://github.com/PM5544/scoped-polyfill",
27936
+ "title": "Polyfill"
27937
+ }, {
27938
+ "url": "http://html5doctor.com/the-scoped-attribute/",
27939
+ "title": "HTML5 Doctor article"
27940
+ }, {
27941
+ "url": "http://updates.html5rocks.com/2012/03/A-New-Experimental-Feature-style-scoped",
27942
+ "title": "HTML5Rocks article"
27943
+ }],
27944
+ "categories": ["CSS", "HTML5"],
27945
+ "stats": {
27946
+ "ie": {
27947
+ "5.5": "n",
27948
+ "6": "n",
27949
+ "7": "n",
27950
+ "8": "n",
27951
+ "9": "n",
27952
+ "10": "n",
27953
+ "11": "n"
27954
+ },
27955
+ "firefox": {
27956
+ "2": "n",
27957
+ "3": "n",
27958
+ "3.5": "n",
27959
+ "3.6": "n",
27960
+ "4": "n",
27961
+ "5": "n",
27962
+ "6": "n",
27963
+ "7": "n",
27964
+ "8": "n",
27965
+ "9": "n",
27966
+ "10": "n",
27967
+ "11": "n",
27968
+ "12": "n",
27969
+ "13": "n",
27970
+ "14": "n",
27971
+ "15": "n",
27972
+ "16": "n",
27973
+ "17": "n",
27974
+ "18": "n",
27975
+ "19": "n",
27976
+ "20": "n",
27977
+ "21": "y",
27978
+ "22": "y",
27979
+ "23": "y",
27980
+ "24": "y",
27981
+ "25": "y",
27982
+ "26": "y",
27983
+ "27": "y"
27984
+ },
27985
+ "chrome": {
27986
+ "4": "n",
27987
+ "5": "n",
27988
+ "6": "n",
27989
+ "7": "n",
27990
+ "8": "n",
27991
+ "9": "n",
27992
+ "10": "n",
27993
+ "11": "n",
27994
+ "12": "n",
27995
+ "13": "n",
27996
+ "14": "n",
27997
+ "15": "n",
27998
+ "16": "n",
27999
+ "17": "n",
28000
+ "18": "n",
28001
+ "19": "n",
28002
+ "20": "n",
28003
+ "21": "n",
28004
+ "22": "n",
28005
+ "23": "n",
28006
+ "24": "n",
28007
+ "25": "n",
28008
+ "26": "n",
28009
+ "27": "n",
28010
+ "28": "n",
28011
+ "29": "n",
28012
+ "30": "n",
28013
+ "31": "u",
28014
+ "32": "u"
28015
+ },
28016
+ "safari": {
28017
+ "3.1": "n",
28018
+ "3.2": "n",
28019
+ "4": "n",
28020
+ "5": "n",
28021
+ "5.1": "n",
28022
+ "6": "n",
28023
+ "6.1": "u",
28024
+ "7": "u"
28025
+ },
28026
+ "opera": {
28027
+ "9": "n",
28028
+ "9.5-9.6": "n",
28029
+ "10.0-10.1": "n",
28030
+ "10.5": "n",
28031
+ "10.6": "n",
28032
+ "11": "n",
28033
+ "11.1": "n",
28034
+ "11.5": "n",
28035
+ "11.6": "n",
28036
+ "12": "n",
28037
+ "12.1": "n",
28038
+ "15": "n",
28039
+ "16": "n",
28040
+ "17": "n",
28041
+ "18": "n"
28042
+ },
28043
+ "ios_saf": {
28044
+ "3.2": "n",
28045
+ "4.0-4.1": "n",
28046
+ "4.2-4.3": "n",
28047
+ "5.0-5.1": "n",
28048
+ "6.0-6.1": "n",
28049
+ "7.0": "n"
28050
+ },
28051
+ "op_mini": {
28052
+ "5.0-7.0": "n"
28053
+ },
28054
+ "android": {
28055
+ "2.1": "n",
28056
+ "2.2": "n",
28057
+ "2.3": "n",
28058
+ "3": "n",
28059
+ "4": "n",
28060
+ "4.1": "n",
28061
+ "4.2-4.3": "n",
28062
+ "4.4": "n"
28063
+ },
28064
+ "bb": {
28065
+ "7": "n",
28066
+ "10": "n"
28067
+ },
28068
+ "op_mob": {
28069
+ "10": "n",
28070
+ "11": "n",
28071
+ "11.1": "n",
28072
+ "11.5": "n",
28073
+ "12": "n",
28074
+ "12.1": "u",
28075
+ "0": "n"
28076
+ },
28077
+ "and_chr": {
28078
+ "0": "n"
28079
+ },
28080
+ "and_ff": {
28081
+ "0": "y"
28082
+ },
28083
+ "ie_mob": {
28084
+ "10": "n"
28085
+ }
28086
+ },
28087
+ "notes": "Supported in Chrome 20+ by enabling the \"experimental WebKit features\" flag in chrome://flags.",
28088
+ "usage_perc_y": 13.05,
28089
+ "usage_perc_a": 0,
28090
+ "ucprefix": false,
28091
+ "parent": "",
28092
+ "keywords": "scope"
28093
+ },
28094
+ "svg-fragment": {
28095
+ "title": "SVG fragment identifiers",
28096
+ "description": "Method of displaying only a part of an SVG image by defining a view ID or view box dimensions as the file's fragment identifier.",
28097
+ "spec": "http://www.w3.org/TR/SVG/linking.html#SVGFragmentIdentifiers",
28098
+ "status": "rec",
28099
+ "links": [{
28100
+ "url": "http://www.broken-links.com/2012/08/14/better-svg-sprites-with-fragment-identifiers/",
28101
+ "title": "Blog post"
28102
+ }],
28103
+ "categories": ["SVG"],
28104
+ "stats": {
28105
+ "ie": {
28106
+ "5.5": "n",
28107
+ "6": "n",
28108
+ "7": "n",
28109
+ "8": "n",
28110
+ "9": "n",
28111
+ "10": "y",
28112
+ "11": "y"
28113
+ },
28114
+ "firefox": {
28115
+ "2": "n",
28116
+ "3": "n",
28117
+ "3.5": "n",
28118
+ "3.6": "n",
28119
+ "4": "n",
28120
+ "5": "n",
28121
+ "6": "n",
28122
+ "7": "n",
28123
+ "8": "n",
28124
+ "9": "n",
28125
+ "10": "n",
28126
+ "11": "n",
28127
+ "12": "n",
28128
+ "13": "n",
28129
+ "14": "n",
28130
+ "15": "y",
28131
+ "16": "y",
28132
+ "17": "y",
28133
+ "18": "y",
28134
+ "19": "y",
28135
+ "20": "y",
28136
+ "21": "y",
28137
+ "22": "y",
28138
+ "23": "y",
28139
+ "24": "y",
28140
+ "25": "y",
28141
+ "26": "y",
28142
+ "27": "y"
28143
+ },
28144
+ "chrome": {
28145
+ "4": "n",
28146
+ "5": "n",
28147
+ "6": "n",
28148
+ "7": "n",
28149
+ "8": "n",
28150
+ "9": "n",
28151
+ "10": "n",
28152
+ "11": "n",
28153
+ "12": "n",
28154
+ "13": "n",
28155
+ "14": "n",
28156
+ "15": "n",
28157
+ "16": "n",
28158
+ "17": "n",
28159
+ "18": "n",
28160
+ "19": "n",
28161
+ "20": "n",
28162
+ "21": "n",
28163
+ "22": "n",
28164
+ "23": "n",
28165
+ "24": "n",
28166
+ "25": "n",
28167
+ "26": "n",
28168
+ "27": "n",
28169
+ "28": "n",
28170
+ "29": "n",
28171
+ "30": "n",
28172
+ "31": "u",
28173
+ "32": "u"
28174
+ },
28175
+ "safari": {
28176
+ "3.1": "n",
28177
+ "3.2": "n",
28178
+ "4": "n",
28179
+ "5": "n",
28180
+ "5.1": "n",
28181
+ "6": "n",
28182
+ "6.1": "n",
28183
+ "7": "n"
28184
+ },
28185
+ "opera": {
28186
+ "9": "n",
28187
+ "9.5-9.6": "n",
28188
+ "10.0-10.1": "n",
28189
+ "10.5": "n",
28190
+ "10.6": "n",
28191
+ "11": "n",
28192
+ "11.1": "n",
28193
+ "11.5": "n",
28194
+ "11.6": "n",
28195
+ "12": "n",
28196
+ "12.1": "n",
28197
+ "15": "n",
28198
+ "16": "n",
28199
+ "17": "n",
28200
+ "18": "n"
28201
+ },
28202
+ "ios_saf": {
28203
+ "3.2": "n",
28204
+ "4.0-4.1": "n",
28205
+ "4.2-4.3": "n",
28206
+ "5.0-5.1": "n",
28207
+ "6.0-6.1": "n",
28208
+ "7.0": "n"
28209
+ },
28210
+ "op_mini": {
28211
+ "5.0-7.0": "n"
28212
+ },
28213
+ "android": {
28214
+ "2.1": "n",
28215
+ "2.2": "n",
28216
+ "2.3": "n",
28217
+ "3": "n",
28218
+ "4": "n",
28219
+ "4.1": "n",
28220
+ "4.2-4.3": "n",
28221
+ "4.4": "n"
28222
+ },
28223
+ "bb": {
28224
+ "7": "n",
28225
+ "10": "y"
28226
+ },
28227
+ "op_mob": {
28228
+ "10": "n",
28229
+ "11": "n",
28230
+ "11.1": "n",
28231
+ "11.5": "n",
28232
+ "12": "n",
28233
+ "12.1": "u",
28234
+ "0": "n"
28235
+ },
28236
+ "and_chr": {
28237
+ "0": "n"
28238
+ },
28239
+ "and_ff": {
28240
+ "0": "y"
28241
+ },
28242
+ "ie_mob": {
28243
+ "10": "y"
28244
+ }
28245
+ },
28246
+ "notes": "",
28247
+ "usage_perc_y": 25.15,
28248
+ "usage_perc_a": 0,
28249
+ "ucprefix": false,
28250
+ "parent": "",
28251
+ "keywords": "fragments,sprite"
28252
+ },
28253
+ "outline": {
28254
+ "title": "CSS outline",
28255
+ "description": "The CSS outline property is a shorthand property for setting one or more of the individual outline properties outline-style, outline-width and outline-color in a single rule. In most cases the use of this shortcut is preferable and more convenient.",
28256
+ "spec": "http://www.w3.org/TR/CSS2/ui.html#propdef-outline",
28257
+ "status": "rec",
28258
+ "links": [{
28259
+ "url": "https://developer.mozilla.org/en-US/docs/CSS/outline",
28260
+ "title": "Mozilla Developer Network: outline"
28261
+ }, {
28262
+ "url": "http://dev.w3.org/csswg/css3-ui/#outline",
28263
+ "title": "CSS Basic User Interface Module Level 3"
28264
+ }],
28265
+ "categories": ["CSS2"],
28266
+ "stats": {
28267
+ "ie": {
28268
+ "5.5": "n",
28269
+ "6": "n",
28270
+ "7": "n",
28271
+ "8": "y",
28272
+ "9": "y",
28273
+ "10": "y",
28274
+ "11": "y"
28275
+ },
28276
+ "firefox": {
28277
+ "2": "y",
28278
+ "3": "y",
28279
+ "3.5": "y",
28280
+ "3.6": "y",
28281
+ "4": "y",
28282
+ "5": "y",
28283
+ "6": "y",
28284
+ "7": "y",
28285
+ "8": "y",
28286
+ "9": "y",
28287
+ "10": "y",
28288
+ "11": "y",
28289
+ "12": "y",
28290
+ "13": "y",
28291
+ "14": "y",
28292
+ "15": "y",
28293
+ "16": "y",
28294
+ "17": "y",
28295
+ "18": "y",
28296
+ "19": "y",
28297
+ "20": "y",
28298
+ "21": "y",
28299
+ "22": "y",
28300
+ "23": "y",
28301
+ "24": "y",
28302
+ "25": "y",
28303
+ "26": "y",
28304
+ "27": "y"
28305
+ },
28306
+ "chrome": {
28307
+ "4": "y",
28308
+ "5": "y",
28309
+ "6": "y",
28310
+ "7": "y",
28311
+ "8": "y",
28312
+ "9": "y",
28313
+ "10": "y",
28314
+ "11": "y",
28315
+ "12": "y",
28316
+ "13": "y",
28317
+ "14": "y",
28318
+ "15": "y",
28319
+ "16": "y",
28320
+ "17": "y",
28321
+ "18": "y",
28322
+ "19": "y",
28323
+ "20": "y",
28324
+ "21": "y",
28325
+ "22": "y",
28326
+ "23": "y",
28327
+ "24": "y",
28328
+ "25": "y",
28329
+ "26": "y",
28330
+ "27": "y",
28331
+ "28": "y",
28332
+ "29": "y",
28333
+ "30": "y",
28334
+ "31": "y",
28335
+ "32": "y"
28336
+ },
28337
+ "safari": {
28338
+ "3.1": "y",
28339
+ "3.2": "y",
28340
+ "4": "y",
28341
+ "5": "y",
28342
+ "5.1": "y",
28343
+ "6": "y",
28344
+ "6.1": "y",
28345
+ "7": "y"
28346
+ },
28347
+ "opera": {
28348
+ "9": "y",
28349
+ "9.5-9.6": "y",
28350
+ "10.0-10.1": "y",
28351
+ "10.5": "y",
28352
+ "10.6": "y",
28353
+ "11": "y",
28354
+ "11.1": "y",
28355
+ "11.5": "y",
28356
+ "11.6": "y",
28357
+ "12": "y",
28358
+ "12.1": "y",
28359
+ "15": "y",
28360
+ "16": "y",
28361
+ "17": "y",
28362
+ "18": "y"
28363
+ },
28364
+ "ios_saf": {
28365
+ "3.2": "y",
28366
+ "4.0-4.1": "y",
28367
+ "4.2-4.3": "y",
28368
+ "5.0-5.1": "y",
28369
+ "6.0-6.1": "y",
28370
+ "7.0": "y"
28371
+ },
28372
+ "op_mini": {
28373
+ "5.0-7.0": "n"
28374
+ },
28375
+ "android": {
28376
+ "2.1": "y",
28377
+ "2.2": "y",
28378
+ "2.3": "y",
28379
+ "3": "y",
28380
+ "4": "y",
28381
+ "4.1": "y",
28382
+ "4.2-4.3": "y",
28383
+ "4.4": "y"
28384
+ },
28385
+ "bb": {
28386
+ "7": "y",
28387
+ "10": "y"
28388
+ },
28389
+ "op_mob": {
28390
+ "10": "y",
28391
+ "11": "y",
28392
+ "11.1": "y",
28393
+ "11.5": "y",
28394
+ "12": "y",
28395
+ "12.1": "y",
28396
+ "0": "y"
28397
+ },
28398
+ "and_chr": {
28399
+ "0": "y"
28400
+ },
28401
+ "and_ff": {
28402
+ "0": "y"
28403
+ },
28404
+ "ie_mob": {
28405
+ "10": "y"
28406
+ }
28407
+ },
28408
+ "notes": "",
28409
+ "usage_perc_y": 89.27,
28410
+ "usage_perc_a": 0,
28411
+ "ucprefix": false,
28412
+ "parent": "",
28413
+ "keywords": "-moz-outline,outline-width,outline-style,outline-color"
28414
+ },
28415
+ "download": {
28416
+ "title": "Download attribute",
28417
+ "description": "When used on an anchor, this attribute signifies that the resource it points to should be downloaded by the browser rather than navigate to it.",
28418
+ "spec": "http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#downloading-resources",
28419
+ "status": "wd",
28420
+ "links": [{
28421
+ "url": "http://html5-demos.appspot.com/static/a.download.html",
28422
+ "title": "Demo: creating a text file and downloading it."
28423
+ }, {
28424
+ "url": "http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download",
28425
+ "title": "HTML5Rocks post"
28426
+ }],
28427
+ "categories": ["HTML5"],
28428
+ "stats": {
28429
+ "ie": {
28430
+ "5.5": "n",
28431
+ "6": "n",
28432
+ "7": "n",
28433
+ "8": "n",
28434
+ "9": "n",
28435
+ "10": "n",
28436
+ "11": "n"
28437
+ },
28438
+ "firefox": {
28439
+ "2": "n",
28440
+ "3": "n",
28441
+ "3.5": "n",
28442
+ "3.6": "n",
28443
+ "4": "n",
28444
+ "5": "n",
28445
+ "6": "n",
28446
+ "7": "n",
28447
+ "8": "n",
28448
+ "9": "n",
28449
+ "10": "n",
28450
+ "11": "n",
28451
+ "12": "n",
28452
+ "13": "n",
28453
+ "14": "n",
28454
+ "15": "n",
28455
+ "16": "n",
28456
+ "17": "n",
28457
+ "18": "n",
28458
+ "19": "n",
28459
+ "20": "y",
28460
+ "21": "y",
28461
+ "22": "y",
28462
+ "23": "y",
28463
+ "24": "y",
28464
+ "25": "y",
28465
+ "26": "y",
28466
+ "27": "y"
28467
+ },
28468
+ "chrome": {
28469
+ "4": "n",
28470
+ "5": "n",
28471
+ "6": "n",
28472
+ "7": "n",
28473
+ "8": "n",
28474
+ "9": "n",
28475
+ "10": "n",
28476
+ "11": "n",
28477
+ "12": "n",
28478
+ "13": "n",
28479
+ "14": "y",
28480
+ "15": "y",
28481
+ "16": "y",
28482
+ "17": "y",
28483
+ "18": "y",
28484
+ "19": "y",
28485
+ "20": "y",
28486
+ "21": "y",
28487
+ "22": "y",
28488
+ "23": "y",
28489
+ "24": "y",
28490
+ "25": "y",
28491
+ "26": "y",
28492
+ "27": "y",
28493
+ "28": "y",
28494
+ "29": "y",
28495
+ "30": "y",
28496
+ "31": "y",
28497
+ "32": "y"
28498
+ },
28499
+ "safari": {
28500
+ "3.1": "n",
28501
+ "3.2": "n",
28502
+ "4": "n",
28503
+ "5": "n",
28504
+ "5.1": "n",
28505
+ "6": "n",
28506
+ "6.1": "n",
28507
+ "7": "n"
28508
+ },
28509
+ "opera": {
28510
+ "9": "n",
28511
+ "9.5-9.6": "n",
28512
+ "10.0-10.1": "n",
28513
+ "10.5": "n",
28514
+ "10.6": "n",
28515
+ "11": "n",
28516
+ "11.1": "n",
28517
+ "11.5": "n",
28518
+ "11.6": "n",
28519
+ "12": "n",
28520
+ "12.1": "n",
28521
+ "15": "y",
28522
+ "16": "y",
28523
+ "17": "y",
28524
+ "18": "y"
28525
+ },
28526
+ "ios_saf": {
28527
+ "3.2": "n",
28528
+ "4.0-4.1": "n",
28529
+ "4.2-4.3": "n",
28530
+ "5.0-5.1": "n",
28531
+ "6.0-6.1": "n",
28532
+ "7.0": "n"
28533
+ },
28534
+ "op_mini": {
28535
+ "5.0-7.0": "n"
28536
+ },
28537
+ "android": {
28538
+ "2.1": "n",
28539
+ "2.2": "n",
28540
+ "2.3": "n",
28541
+ "3": "n",
28542
+ "4": "n",
28543
+ "4.1": "n",
28544
+ "4.2-4.3": "n",
28545
+ "4.4": "y"
28546
+ },
28547
+ "bb": {
28548
+ "7": "n",
28549
+ "10": "y"
28550
+ },
28551
+ "op_mob": {
28552
+ "10": "n",
28553
+ "11": "n",
28554
+ "11.1": "n",
28555
+ "11.5": "n",
28556
+ "12": "n",
28557
+ "12.1": "n",
28558
+ "0": "y"
28559
+ },
28560
+ "and_chr": {
28561
+ "0": "y"
28562
+ },
28563
+ "and_ff": {
28564
+ "0": "y"
28565
+ },
28566
+ "ie_mob": {
28567
+ "10": "n"
28568
+ }
28569
+ },
28570
+ "notes": "",
28571
+ "usage_perc_y": 48.02,
28572
+ "usage_perc_a": 0,
28573
+ "ucprefix": false,
28574
+ "parent": "",
28575
+ "keywords": "download,a.download,a[download],download attribute"
28576
+ },
28577
+ "pointer": {
28578
+ "title": "Pointer events",
28579
+ "description": "This specification integrates various inputs from mice, touchscreens, and pens, making separate implementations no longer necessary and authoring for cross-device pointers easier. Not to be mistaken with the unrelated \"pointer-events\" CSS property.",
28580
+ "spec": "http://www.w3.org/TR/pointerevents/",
28581
+ "status": "cr",
28582
+ "links": [{
28583
+ "url": "http://blogs.msdn.com/b/eternalcoding/archive/2013/01/16/hand-js-a-polyfill-for-supporting-pointer-events-on-every-browser.aspx",
28584
+ "title": "Hand.js, the polyfill for browsers only supporting Touch Events"
28585
+ }, {
28586
+ "url": "http://blogs.msdn.com/b/ie/archive/2011/09/20/touch-input-for-ie10-and-metro-style-apps.aspx",
28587
+ "title": "Implementation of Pointer Events in IE10"
28588
+ }, {
28589
+ "url": "http://blogs.msdn.com/b/davrous/archive/2013/02/20/handling-touch-in-your-html5-apps-thanks-to-the-pointer-events-of-ie10-and-windows-8.aspx",
28590
+ "title": "Article & tutorial"
28591
+ }],
28592
+ "categories": ["DOM", "JS API"],
28593
+ "stats": {
28594
+ "ie": {
28595
+ "5.5": "n",
28596
+ "6": "n",
28597
+ "7": "n",
28598
+ "8": "n",
28599
+ "9": "n",
28600
+ "10": "a x",
28601
+ "11": "y"
28602
+ },
28603
+ "firefox": {
28604
+ "2": "n",
28605
+ "3": "n",
28606
+ "3.5": "n",
28607
+ "3.6": "n",
28608
+ "4": "n",
28609
+ "5": "n",
28610
+ "6": "p",
28611
+ "7": "p",
28612
+ "8": "p",
28613
+ "9": "p",
28614
+ "10": "p",
28615
+ "11": "p",
28616
+ "12": "p",
28617
+ "13": "p",
28618
+ "14": "p",
28619
+ "15": "p",
28620
+ "16": "p",
28621
+ "17": "p",
28622
+ "18": "p",
28623
+ "19": "p",
28624
+ "20": "p",
28625
+ "21": "p",
28626
+ "22": "p",
28627
+ "23": "p",
28628
+ "24": "p",
28629
+ "25": "p",
28630
+ "26": "p",
28631
+ "27": "p"
28632
+ },
28633
+ "chrome": {
28634
+ "4": "n",
28635
+ "5": "n",
28636
+ "6": "n",
28637
+ "7": "n",
28638
+ "8": "n",
28639
+ "9": "n",
28640
+ "10": "n",
28641
+ "11": "n",
28642
+ "12": "n",
28643
+ "13": "n",
28644
+ "14": "n",
28645
+ "15": "n",
28646
+ "16": "n",
28647
+ "17": "n",
28648
+ "18": "n",
28649
+ "19": "n",
28650
+ "20": "n",
28651
+ "21": "n",
28652
+ "22": "p",
28653
+ "23": "p",
28654
+ "24": "p",
28655
+ "25": "p",
28656
+ "26": "p",
28657
+ "27": "p",
28658
+ "28": "p",
28659
+ "29": "p",
28660
+ "30": "p",
28661
+ "31": "p",
28662
+ "32": "p"
28663
+ },
28664
+ "safari": {
28665
+ "3.1": "n",
28666
+ "3.2": "n",
28667
+ "4": "n",
28668
+ "5": "n",
28669
+ "5.1": "n",
28670
+ "6": "n",
28671
+ "6.1": "u",
28672
+ "7": "u"
28673
+ },
28674
+ "opera": {
28675
+ "9": "n",
28676
+ "9.5-9.6": "n",
28677
+ "10.0-10.1": "n",
28678
+ "10.5": "n",
28679
+ "10.6": "n",
28680
+ "11": "n",
28681
+ "11.1": "n",
28682
+ "11.5": "n",
28683
+ "11.6": "n",
28684
+ "12": "n",
28685
+ "12.1": "n",
28686
+ "15": "p",
28687
+ "16": "p",
28688
+ "17": "p",
28689
+ "18": "p"
28690
+ },
28691
+ "ios_saf": {
28692
+ "3.2": "p",
28693
+ "4.0-4.1": "p",
28694
+ "4.2-4.3": "p",
28695
+ "5.0-5.1": "p",
28696
+ "6.0-6.1": "p",
28697
+ "7.0": "p"
28698
+ },
28699
+ "op_mini": {
28700
+ "5.0-7.0": "n"
28701
+ },
28702
+ "android": {
28703
+ "2.1": "p",
28704
+ "2.2": "p",
28705
+ "2.3": "p",
28706
+ "3": "p",
28707
+ "4": "p",
28708
+ "4.1": "p",
28709
+ "4.2-4.3": "p",
28710
+ "4.4": "p"
28711
+ },
28712
+ "bb": {
28713
+ "7": "p",
28714
+ "10": "p"
28715
+ },
28716
+ "op_mob": {
28717
+ "10": "n",
28718
+ "11": "p",
28719
+ "11.1": "p",
28720
+ "11.5": "p",
28721
+ "12": "p",
28722
+ "12.1": "p",
28723
+ "0": "p"
28724
+ },
28725
+ "and_chr": {
28726
+ "0": "p"
28727
+ },
28728
+ "and_ff": {
28729
+ "0": "p"
28730
+ },
28731
+ "ie_mob": {
28732
+ "10": "a x"
28733
+ }
28734
+ },
28735
+ "notes": "Partial support in IE10 refers the lack of pointerenter and pointerleave events.",
28736
+ "usage_perc_y": 0.11,
28737
+ "usage_perc_a": 10.99,
28738
+ "ucprefix": false,
28739
+ "parent": "",
28740
+ "keywords": "pointerdown,pointermove,pointerup,pointercancel,pointerover,pointerout,pointerenter,pointerleave"
28741
+ },
28742
+ "user-select-none": {
28743
+ "title": "CSS user-select: none",
28744
+ "description": "Method of preventing text/element selection using CSS. ",
28745
+ "spec": "https://developer.mozilla.org/en-US/docs/CSS/user-select",
28746
+ "status": "unoff",
28747
+ "links": [{
28748
+ "url": "http://msdn.microsoft.com/en-us/library/ie/hh781492(v=vs.85).aspx",
28749
+ "title": "MSDN Documentation"
28750
+ }, {
28751
+ "url": "https://developer.mozilla.org/en-US/docs/CSS/user-select",
28752
+ "title": "MDN article"
28753
+ }, {
28754
+ "url": "http://css-tricks.com/almanac/properties/u/user-select/",
28755
+ "title": "CSS Tricks article"
28756
+ }],
28757
+ "categories": ["CSS"],
28758
+ "stats": {
28759
+ "ie": {
28760
+ "5.5": "n",
28761
+ "6": "n",
28762
+ "7": "n",
28763
+ "8": "n",
28764
+ "9": "n",
28765
+ "10": "y x",
28766
+ "11": "y x"
28767
+ },
28768
+ "firefox": {
28769
+ "2": "y x",
28770
+ "3": "y x",
28771
+ "3.5": "y x",
28772
+ "3.6": "y x",
28773
+ "4": "y x",
28774
+ "5": "y x",
28775
+ "6": "y x",
28776
+ "7": "y x",
28777
+ "8": "y x",
28778
+ "9": "y x",
28779
+ "10": "y x",
28780
+ "11": "y x",
28781
+ "12": "y x",
28782
+ "13": "y x",
28783
+ "14": "y x",
28784
+ "15": "y x",
28785
+ "16": "y x",
28786
+ "17": "y x",
28787
+ "18": "y x",
28788
+ "19": "y x",
28789
+ "20": "y x",
28790
+ "21": "y x",
28791
+ "22": "y x",
28792
+ "23": "y x",
28793
+ "24": "y x",
28794
+ "25": "y x",
28795
+ "26": "y x",
28796
+ "27": "y x"
28797
+ },
28798
+ "chrome": {
28799
+ "4": "u",
28800
+ "5": "u",
28801
+ "6": "y x",
28802
+ "7": "y x",
28803
+ "8": "y x",
28804
+ "9": "y x",
28805
+ "10": "y x",
28806
+ "11": "y x",
28807
+ "12": "y x",
28808
+ "13": "y x",
28809
+ "14": "y x",
28810
+ "15": "y x",
28811
+ "16": "y x",
28812
+ "17": "y x",
28813
+ "18": "y x",
28814
+ "19": "y x",
28815
+ "20": "y x",
28816
+ "21": "y x",
28817
+ "22": "y x",
28818
+ "23": "y x",
28819
+ "24": "y x",
28820
+ "25": "y x",
28821
+ "26": "y x",
28822
+ "27": "y x",
28823
+ "28": "y x",
28824
+ "29": "y x",
28825
+ "30": "y x",
28826
+ "31": "y x",
28827
+ "32": "y x"
28828
+ },
28829
+ "safari": {
28830
+ "3.1": "y x",
28831
+ "3.2": "y x",
28832
+ "4": "y x",
28833
+ "5": "y x",
28834
+ "5.1": "y x",
28835
+ "6": "y x",
28836
+ "6.1": "y x",
28837
+ "7": "y x"
28838
+ },
28839
+ "opera": {
28840
+ "9": "n",
28841
+ "9.5-9.6": "n",
28842
+ "10.0-10.1": "n",
28843
+ "10.5": "n",
28844
+ "10.6": "n",
28845
+ "11": "n",
28846
+ "11.1": "n",
28847
+ "11.5": "n",
28848
+ "11.6": "n",
28849
+ "12": "n",
28850
+ "12.1": "n",
28851
+ "15": "y x",
28852
+ "16": "y x",
28853
+ "17": "y x",
28854
+ "18": "y x"
28855
+ },
28856
+ "ios_saf": {
28857
+ "3.2": "y x",
28858
+ "4.0-4.1": "y x",
28859
+ "4.2-4.3": "y x",
28860
+ "5.0-5.1": "y x",
28861
+ "6.0-6.1": "y x",
28862
+ "7.0": "y x"
28863
+ },
28864
+ "op_mini": {
28865
+ "5.0-7.0": "n"
28866
+ },
28867
+ "android": {
28868
+ "2.1": "y x",
28869
+ "2.2": "y x",
28870
+ "2.3": "y x",
28871
+ "3": "y x",
28872
+ "4": "y x",
28873
+ "4.1": "y x",
28874
+ "4.2-4.3": "y x",
28875
+ "4.4": "y x"
28876
+ },
28877
+ "bb": {
28878
+ "7": "y x",
28879
+ "10": "y x"
28880
+ },
28881
+ "op_mob": {
28882
+ "10": "n",
28883
+ "11": "n",
28884
+ "11.1": "n",
28885
+ "11.5": "n",
28886
+ "12": "n",
28887
+ "12.1": "n",
28888
+ "0": "y x"
28889
+ },
28890
+ "and_chr": {
28891
+ "0": "y x"
28892
+ },
28893
+ "and_ff": {
28894
+ "0": "y x"
28895
+ },
28896
+ "ie_mob": {
28897
+ "10": "y x"
28898
+ }
28899
+ },
28900
+ "notes": "Currently the user-select property does not appear in any W3C specification. Support information here is only for \"none\" value, not others.",
28901
+ "usage_perc_y": 74.91,
28902
+ "usage_perc_a": 0,
28903
+ "ucprefix": false,
28904
+ "parent": "",
28905
+ "keywords": ""
28906
+ },
28907
+ "webp": {
28908
+ "title": "WebP image format",
28909
+ "description": "Image format that supports lossy and lossless compression, as well as animation and alpha transparency.",
28910
+ "spec": "https://developers.google.com/speed/webp/",
28911
+ "status": "other",
28912
+ "links": [{
28913
+ "url": "http://libwebpjs.appspot.com/",
28914
+ "title": "Decoder in JS"
28915
+ }, {
28916
+ "url": "https://developers.google.com/speed/webp/",
28917
+ "title": "Official website"
28918
+ }, {
28919
+ "url": "http://antimatter15.github.io/weppy/demo.html",
28920
+ "title": "Polyfill for browsers with WebM support"
28921
+ }, {
28922
+ "url": "http://webpjs.appspot.com/",
28923
+ "title": "Polyfill for browsers with or without WebM support (i.e. IE6-IE9, Safari/iOS version 6.1 and below; Firefox versions 24 and bel"
28924
+ }],
28925
+ "categories": ["Other"],
28926
+ "stats": {
28927
+ "ie": {
28928
+ "5.5": "n",
28929
+ "6": "n",
28930
+ "7": "n",
28931
+ "8": "n",
28932
+ "9": "n",
28933
+ "10": "n",
28934
+ "11": "n"
28935
+ },
28936
+ "firefox": {
28937
+ "2": "n",
28938
+ "3": "n",
28939
+ "3.5": "n",
28940
+ "3.6": "n",
28941
+ "4": "p",
28942
+ "5": "p",
28943
+ "6": "p",
28944
+ "7": "p",
28945
+ "8": "p",
28946
+ "9": "p",
28947
+ "10": "p",
28948
+ "11": "p",
28949
+ "12": "p",
28950
+ "13": "p",
28951
+ "14": "p",
28952
+ "15": "p",
28953
+ "16": "p",
28954
+ "17": "p",
28955
+ "18": "p",
28956
+ "19": "p",
28957
+ "20": "p",
28958
+ "21": "p",
28959
+ "22": "p",
28960
+ "23": "p",
28961
+ "24": "p",
28962
+ "25": "p",
28963
+ "26": "p",
28964
+ "27": "p"
28965
+ },
28966
+ "chrome": {
28967
+ "4": "n",
28968
+ "5": "n",
28969
+ "6": "p",
28970
+ "7": "p",
28971
+ "8": "p",
28972
+ "9": "y",
28973
+ "10": "y",
28974
+ "11": "y",
28975
+ "12": "y",
28976
+ "13": "y",
28977
+ "14": "y",
28978
+ "15": "y",
28979
+ "16": "y",
28980
+ "17": "y",
28981
+ "18": "y",
28982
+ "19": "y",
28983
+ "20": "y",
28984
+ "21": "y",
28985
+ "22": "y",
28986
+ "23": "y",
28987
+ "24": "y",
28988
+ "25": "y",
28989
+ "26": "y",
28990
+ "27": "y",
28991
+ "28": "y",
28992
+ "29": "y",
28993
+ "30": "y",
28994
+ "31": "y",
28995
+ "32": "y"
28996
+ },
28997
+ "safari": {
28998
+ "3.1": "n",
28999
+ "3.2": "n",
29000
+ "4": "n",
29001
+ "5": "n",
29002
+ "5.1": "n",
29003
+ "6": "n",
29004
+ "6.1": "n",
29005
+ "7": "n"
29006
+ },
29007
+ "opera": {
29008
+ "9": "n",
29009
+ "9.5-9.6": "n",
29010
+ "10.0-10.1": "n",
29011
+ "10.5": "n",
29012
+ "10.6": "p",
29013
+ "11": "p",
29014
+ "11.1": "p",
29015
+ "11.5": "p",
29016
+ "11.6": "p",
29017
+ "12": "y",
29018
+ "12.1": "y",
29019
+ "15": "y",
29020
+ "16": "y",
29021
+ "17": "y",
29022
+ "18": "y"
29023
+ },
29024
+ "ios_saf": {
29025
+ "3.2": "n",
29026
+ "4.0-4.1": "n",
29027
+ "4.2-4.3": "n",
29028
+ "5.0-5.1": "n",
29029
+ "6.0-6.1": "n",
29030
+ "7.0": "n"
29031
+ },
29032
+ "op_mini": {
29033
+ "5.0-7.0": "n"
29034
+ },
29035
+ "android": {
29036
+ "2.1": "n",
29037
+ "2.2": "n",
29038
+ "2.3": "n",
29039
+ "3": "n",
29040
+ "4": "y",
29041
+ "4.1": "y",
29042
+ "4.2-4.3": "y",
29043
+ "4.4": "y"
29044
+ },
29045
+ "bb": {
29046
+ "7": "n",
29047
+ "10": "n"
29048
+ },
29049
+ "op_mob": {
29050
+ "10": "n",
29051
+ "11": "a",
29052
+ "11.1": "y",
29053
+ "11.5": "y",
29054
+ "12": "y",
29055
+ "12.1": "y",
29056
+ "0": "y"
29057
+ },
29058
+ "and_chr": {
29059
+ "0": "y"
29060
+ },
29061
+ "and_ff": {
29062
+ "0": "n"
29063
+ },
29064
+ "ie_mob": {
29065
+ "10": "n"
29066
+ }
29067
+ },
29068
+ "notes": "Animated webp images are supported in Chrome 32+ and Opera 19+.",
29069
+ "usage_perc_y": 39.4,
29070
+ "usage_perc_a": 0.01,
29071
+ "ucprefix": false,
29072
+ "parent": "",
29073
+ "keywords": ""
29074
+ },
29075
+ "intrinsic-width": {
29076
+ "title": "Intrinsic & Extrinsic Sizing",
29077
+ "description": "Allows for the heights and widths to be specified in intrinsic values using the fill-available, max-content, min-content, and fit-content properties.",
29078
+ "spec": "http://www.w3.org/TR/css3-sizing/",
29079
+ "status": "wd",
29080
+ "links": [{
29081
+ "url": "http://demosthenes.info/blog/662/Design-From-the-Inside-Out-With-CSS-MinContent",
29082
+ "title": "Min-Content tutorial"
29083
+ }],
29084
+ "categories": ["CSS3"],
29085
+ "stats": {
29086
+ "ie": {
29087
+ "5.5": "n",
29088
+ "6": "n",
29089
+ "7": "n",
29090
+ "8": "n",
29091
+ "9": "n",
29092
+ "10": "n",
29093
+ "11": "n"
29094
+ },
29095
+ "firefox": {
29096
+ "2": "n",
29097
+ "3": "n",
29098
+ "3.5": "n",
29099
+ "3.6": "n",
29100
+ "4": "y x",
29101
+ "5": "y x",
29102
+ "6": "y x",
29103
+ "7": "y x",
29104
+ "8": "y x",
29105
+ "9": "y x",
29106
+ "10": "y x",
29107
+ "11": "y x",
29108
+ "12": "y x",
29109
+ "13": "y x",
29110
+ "14": "y x",
29111
+ "15": "y x",
29112
+ "16": "y x",
29113
+ "17": "y x",
29114
+ "18": "y x",
29115
+ "19": "y x",
29116
+ "20": "y x",
29117
+ "21": "y x",
29118
+ "22": "y x",
29119
+ "23": "y x",
29120
+ "24": "y x",
29121
+ "25": "y x",
29122
+ "26": "y x",
29123
+ "27": "y x"
29124
+ },
29125
+ "chrome": {
29126
+ "4": "n",
29127
+ "5": "n",
29128
+ "6": "n",
29129
+ "7": "n",
29130
+ "8": "n",
29131
+ "9": "n",
29132
+ "10": "n",
29133
+ "11": "n",
29134
+ "12": "n",
29135
+ "13": "n",
29136
+ "14": "n",
29137
+ "15": "n",
29138
+ "16": "n",
29139
+ "17": "n",
29140
+ "18": "n",
29141
+ "19": "n",
29142
+ "20": "n",
29143
+ "21": "n",
29144
+ "22": "y x",
29145
+ "23": "y x",
29146
+ "24": "y x",
29147
+ "25": "y x",
29148
+ "26": "y x",
29149
+ "27": "y x",
29150
+ "28": "y x",
29151
+ "29": "y x",
29152
+ "30": "y x",
29153
+ "31": "y x",
29154
+ "32": "y x"
29155
+ },
29156
+ "safari": {
29157
+ "3.1": "n",
29158
+ "3.2": "n",
29159
+ "4": "n",
29160
+ "5": "n",
29161
+ "5.1": "n",
29162
+ "6": "n",
29163
+ "6.1": "y x",
29164
+ "7": "y x"
29165
+ },
29166
+ "opera": {
29167
+ "9": "n",
29168
+ "9.5-9.6": "n",
29169
+ "10.0-10.1": "n",
29170
+ "10.5": "n",
29171
+ "10.6": "n",
29172
+ "11": "n",
29173
+ "11.1": "n",
29174
+ "11.5": "n",
29175
+ "11.6": "n",
29176
+ "12": "n",
29177
+ "12.1": "n",
29178
+ "15": "y x",
29179
+ "16": "y x",
29180
+ "17": "y x",
29181
+ "18": "y x"
29182
+ },
29183
+ "ios_saf": {
29184
+ "3.2": "n",
29185
+ "4.0-4.1": "n",
29186
+ "4.2-4.3": "n",
29187
+ "5.0-5.1": "n",
29188
+ "6.0-6.1": "n",
29189
+ "7.0": "y x"
29190
+ },
29191
+ "op_mini": {
29192
+ "5.0-7.0": "n"
29193
+ },
29194
+ "android": {
29195
+ "2.1": "n",
29196
+ "2.2": "n",
29197
+ "2.3": "n",
29198
+ "3": "n",
29199
+ "4": "n",
29200
+ "4.1": "n",
29201
+ "4.2-4.3": "n",
29202
+ "4.4": "y x"
29203
+ },
29204
+ "bb": {
29205
+ "7": "n",
29206
+ "10": "y x"
29207
+ },
29208
+ "op_mob": {
29209
+ "10": "n",
29210
+ "11": "n",
29211
+ "11.1": "n",
29212
+ "11.5": "n",
29213
+ "12": "n",
29214
+ "12.1": "n",
29215
+ "0": "y x"
29216
+ },
29217
+ "and_chr": {
29218
+ "0": "y x"
29219
+ },
29220
+ "and_ff": {
29221
+ "0": "y x"
29222
+ },
29223
+ "ie_mob": {
29224
+ "10": "n"
29225
+ }
29226
+ },
29227
+ "notes": "Prefixes are on the values, not the property names (e.g. -webkit-min-content) Firefox currently supports the \"-moz-available\" property rather than \"-moz-fill-available\".",
29228
+ "usage_perc_y": 51.68,
29229
+ "usage_perc_a": 0,
29230
+ "ucprefix": false,
29231
+ "parent": "",
29232
+ "keywords": "fill-available,max-content,min-content,fit-content,contain-floats"
29233
+ },
29234
+ "template": {
29235
+ "title": "HTML templates",
29236
+ "description": "Method of declaring a portion of reusable markup that is parsed but not rendered until cloned.",
29237
+ "spec": "http://www.w3.org/TR/html-templates/",
29238
+ "status": "wd",
29239
+ "links": [{
29240
+ "url": "http://www.html5rocks.com/en/tutorials/webcomponents/template/",
29241
+ "title": "HTML5Rocks - HTML's New template Tag"
29242
+ }, {
29243
+ "url": "http://polymer-project.org",
29244
+ "title": "Polymer project (polyfill & web compontents framework)"
29245
+ }],
29246
+ "categories": ["DOM", "HTML5"],
29247
+ "stats": {
29248
+ "ie": {
29249
+ "5.5": "n",
29250
+ "6": "n",
29251
+ "7": "n",
29252
+ "8": "n",
29253
+ "9": "n",
29254
+ "10": "n",
29255
+ "11": "n"
29256
+ },
29257
+ "firefox": {
29258
+ "2": "n",
29259
+ "3": "n",
29260
+ "3.5": "n",
29261
+ "3.6": "n",
29262
+ "4": "n",
29263
+ "5": "n",
29264
+ "6": "n",
29265
+ "7": "n",
29266
+ "8": "n",
29267
+ "9": "n",
29268
+ "10": "n",
29269
+ "11": "n",
29270
+ "12": "n",
29271
+ "13": "n",
29272
+ "14": "n",
29273
+ "15": "n",
29274
+ "16": "n",
29275
+ "17": "n",
29276
+ "18": "n",
29277
+ "19": "n",
29278
+ "20": "n",
29279
+ "21": "n",
29280
+ "22": "y",
29281
+ "23": "y",
29282
+ "24": "y",
29283
+ "25": "y",
29284
+ "26": "y",
29285
+ "27": "y"
29286
+ },
29287
+ "chrome": {
29288
+ "4": "n",
29289
+ "5": "n",
29290
+ "6": "n",
29291
+ "7": "n",
29292
+ "8": "n",
29293
+ "9": "n",
29294
+ "10": "n",
29295
+ "11": "n",
29296
+ "12": "n",
29297
+ "13": "n",
29298
+ "14": "n",
29299
+ "15": "n",
29300
+ "16": "n",
29301
+ "17": "n",
29302
+ "18": "n",
29303
+ "19": "n",
29304
+ "20": "n",
29305
+ "21": "n",
29306
+ "22": "n",
29307
+ "23": "n",
29308
+ "24": "n",
29309
+ "25": "n",
29310
+ "26": "y",
29311
+ "27": "y",
29312
+ "28": "y",
29313
+ "29": "y",
29314
+ "30": "y",
29315
+ "31": "y",
29316
+ "32": "y"
29317
+ },
29318
+ "safari": {
29319
+ "3.1": "n",
29320
+ "3.2": "n",
29321
+ "4": "n",
29322
+ "5": "n",
29323
+ "5.1": "n",
29324
+ "6": "n",
29325
+ "6.1": "n",
29326
+ "7": "n"
29327
+ },
29328
+ "opera": {
29329
+ "9": "n",
29330
+ "9.5-9.6": "n",
29331
+ "10.0-10.1": "n",
29332
+ "10.5": "n",
29333
+ "10.6": "n",
29334
+ "11": "n",
29335
+ "11.1": "n",
29336
+ "11.5": "n",
29337
+ "11.6": "n",
29338
+ "12": "n",
29339
+ "12.1": "n",
29340
+ "15": "y",
29341
+ "16": "y",
29342
+ "17": "y",
29343
+ "18": "y"
29344
+ },
29345
+ "ios_saf": {
29346
+ "3.2": "n",
29347
+ "4.0-4.1": "n",
29348
+ "4.2-4.3": "n",
29349
+ "5.0-5.1": "n",
29350
+ "6.0-6.1": "n",
29351
+ "7.0": "n"
29352
+ },
29353
+ "op_mini": {
29354
+ "5.0-7.0": "n"
29355
+ },
29356
+ "android": {
29357
+ "2.1": "n",
29358
+ "2.2": "n",
29359
+ "2.3": "n",
29360
+ "3": "n",
29361
+ "4": "n",
29362
+ "4.1": "n",
29363
+ "4.2-4.3": "n",
29364
+ "4.4": "y"
29365
+ },
29366
+ "bb": {
29367
+ "7": "n",
29368
+ "10": "n"
29369
+ },
29370
+ "op_mob": {
29371
+ "10": "n",
29372
+ "11": "n",
29373
+ "11.1": "n",
29374
+ "11.5": "n",
29375
+ "12": "n",
29376
+ "12.1": "n",
29377
+ "0": "y"
29378
+ },
29379
+ "and_chr": {
29380
+ "0": "y"
29381
+ },
29382
+ "and_ff": {
29383
+ "0": "y"
29384
+ },
29385
+ "ie_mob": {
29386
+ "10": "n"
29387
+ }
29388
+ },
29389
+ "notes": "",
29390
+ "usage_perc_y": 45.76,
29391
+ "usage_perc_a": 0,
29392
+ "ucprefix": false,
29393
+ "parent": "",
29394
+ "keywords": "web components, template"
29395
+ },
29396
+ "opus": {
29397
+ "title": "Opus",
29398
+ "description": "Royalty-free open audio codec by IETF, which incorporated SILK from Skype and CELT from Xiph.org, to serve higher sound quality and lower latency at the same bitrate.",
29399
+ "spec": "http://tools.ietf.org/html/rfc6716",
29400
+ "status": "other",
29401
+ "links": [{
29402
+ "url": "https://hacks.mozilla.org/2012/07/firefox-beta-15-supports-the-new-opus-audio-format/",
29403
+ "title": "Introduction of Opus by Mozilla"
29404
+ }, {
29405
+ "url": "http://www.ietf.org/mail-archive/web/rtcweb/current/msg04953.html",
29406
+ "title": "Google's statement about the use of VP8 and Opus codec for WebRTC standard"
29407
+ }],
29408
+ "categories": ["Other"],
29409
+ "stats": {
29410
+ "ie": {
29411
+ "5.5": "n",
29412
+ "6": "n",
29413
+ "7": "n",
29414
+ "8": "n",
29415
+ "9": "n",
29416
+ "10": "n",
29417
+ "11": "n"
29418
+ },
29419
+ "firefox": {
29420
+ "2": "n",
29421
+ "3": "n",
29422
+ "3.5": "n",
29423
+ "3.6": "n",
29424
+ "4": "n",
29425
+ "5": "n",
29426
+ "6": "n",
29427
+ "7": "n",
29428
+ "8": "n",
29429
+ "9": "n",
29430
+ "10": "n",
29431
+ "11": "n",
29432
+ "12": "n",
29433
+ "13": "n",
29434
+ "14": "n",
29435
+ "15": "y",
29436
+ "16": "y",
29437
+ "17": "y",
29438
+ "18": "y",
29439
+ "19": "y",
29440
+ "20": "y",
29441
+ "21": "y",
29442
+ "22": "y",
29443
+ "23": "y",
29444
+ "24": "y",
29445
+ "25": "y",
29446
+ "26": "y",
29447
+ "27": "y"
29448
+ },
29449
+ "chrome": {
29450
+ "4": "n",
29451
+ "5": "n",
29452
+ "6": "n",
29453
+ "7": "n",
29454
+ "8": "n",
29455
+ "9": "n",
29456
+ "10": "n",
29457
+ "11": "n",
29458
+ "12": "n",
29459
+ "13": "n",
29460
+ "14": "n",
29461
+ "15": "n",
29462
+ "16": "n",
29463
+ "17": "n",
29464
+ "18": "n",
29465
+ "19": "n",
29466
+ "20": "n",
29467
+ "21": "n",
29468
+ "22": "n",
29469
+ "23": "n",
29470
+ "24": "n",
29471
+ "25": "n",
29472
+ "26": "n",
29473
+ "27": "n",
29474
+ "28": "n",
29475
+ "29": "n",
29476
+ "30": "n",
29477
+ "31": "n",
29478
+ "32": "n"
29479
+ },
29480
+ "safari": {
29481
+ "3.1": "n",
29482
+ "3.2": "n",
29483
+ "4": "n",
29484
+ "5": "n",
29485
+ "5.1": "n",
29486
+ "6": "n",
29487
+ "6.1": "u",
29488
+ "7": "u"
29489
+ },
29490
+ "opera": {
29491
+ "9": "n",
29492
+ "9.5-9.6": "n",
29493
+ "10.0-10.1": "n",
29494
+ "10.5": "n",
29495
+ "10.6": "n",
29496
+ "11": "n",
29497
+ "11.1": "n",
29498
+ "11.5": "n",
29499
+ "11.6": "n",
29500
+ "12": "n",
29501
+ "12.1": "n",
29502
+ "15": "n",
29503
+ "16": "n",
29504
+ "17": "n",
29505
+ "18": "n"
29506
+ },
29507
+ "ios_saf": {
29508
+ "3.2": "n",
29509
+ "4.0-4.1": "n",
29510
+ "4.2-4.3": "n",
29511
+ "5.0-5.1": "n",
29512
+ "6.0-6.1": "n",
29513
+ "7.0": "u"
29514
+ },
29515
+ "op_mini": {
29516
+ "5.0-7.0": "n"
29517
+ },
29518
+ "android": {
29519
+ "2.1": "n",
29520
+ "2.2": "n",
29521
+ "2.3": "n",
29522
+ "3": "n",
29523
+ "4": "n",
29524
+ "4.1": "n",
29525
+ "4.2-4.3": "n",
29526
+ "4.4": "n"
29527
+ },
29528
+ "bb": {
29529
+ "7": "n",
29530
+ "10": "n"
29531
+ },
29532
+ "op_mob": {
29533
+ "10": "n",
29534
+ "11": "n",
29535
+ "11.1": "n",
29536
+ "11.5": "n",
29537
+ "12": "n",
29538
+ "12.1": "n",
29539
+ "0": "n"
29540
+ },
29541
+ "and_chr": {
29542
+ "0": "n"
29543
+ },
29544
+ "and_ff": {
29545
+ "0": "y"
29546
+ },
29547
+ "ie_mob": {
29548
+ "10": "n"
29549
+ }
29550
+ },
29551
+ "notes": "Chrome does not support Opus by default but users can enable it via the 'enable-opus-playback' flag. When it comes to Opera, it is said that the Linux version may be able to play it when the GStreamer module is up to date and the served mime-type is 'audio/ogg'.",
29552
+ "usage_perc_y": 14.04,
29553
+ "usage_perc_a": 0,
29554
+ "ucprefix": false,
29555
+ "parent": "audio",
29556
+ "keywords": ""
29557
+ },
29558
+ "jpegxr": {
29559
+ "title": "JPEG XR image format",
29560
+ "description": "The latest JPEG image format of Joint Photographic Experts Group which boasts better compression and supports lossless compression, alpha channel, and 48-bit deep color over normal jpg format.",
29561
+ "spec": "http://www.itu.int/rec/T-REC-T.832",
29562
+ "status": "other",
29563
+ "links": [{
29564
+ "url": "http://msdn.microsoft.com/en-us/library/windows/desktop/hh707223(v=vs.85).aspx",
29565
+ "title": "Microsoft JPEG XR Codec Overview"
29566
+ }],
29567
+ "categories": ["Other"],
29568
+ "stats": {
29569
+ "ie": {
29570
+ "5.5": "n",
29571
+ "6": "n",
29572
+ "7": "n",
29573
+ "8": "n",
29574
+ "9": "y",
29575
+ "10": "y",
29576
+ "11": "y"
29577
+ },
29578
+ "firefox": {
29579
+ "2": "n",
29580
+ "3": "n",
29581
+ "3.5": "n",
29582
+ "3.6": "n",
29583
+ "4": "n",
29584
+ "5": "n",
29585
+ "6": "n",
29586
+ "7": "n",
29587
+ "8": "n",
29588
+ "9": "n",
29589
+ "10": "n",
29590
+ "11": "n",
29591
+ "12": "n",
29592
+ "13": "n",
29593
+ "14": "n",
29594
+ "15": "n",
29595
+ "16": "n",
29596
+ "17": "n",
29597
+ "18": "n",
29598
+ "19": "n",
29599
+ "20": "n",
29600
+ "21": "n",
29601
+ "22": "n",
29602
+ "23": "n",
29603
+ "24": "n",
29604
+ "25": "n",
29605
+ "26": "n",
29606
+ "27": "n"
29607
+ },
29608
+ "chrome": {
29609
+ "4": "n",
29610
+ "5": "n",
29611
+ "6": "n",
29612
+ "7": "n",
29613
+ "8": "n",
29614
+ "9": "n",
29615
+ "10": "n",
29616
+ "11": "n",
29617
+ "12": "n",
29618
+ "13": "n",
29619
+ "14": "n",
29620
+ "15": "n",
29621
+ "16": "n",
29622
+ "17": "n",
29623
+ "18": "n",
29624
+ "19": "n",
29625
+ "20": "n",
29626
+ "21": "n",
29627
+ "22": "n",
29628
+ "23": "n",
29629
+ "24": "n",
29630
+ "25": "n",
29631
+ "26": "n",
29632
+ "27": "n",
29633
+ "28": "n",
29634
+ "29": "n",
29635
+ "30": "n",
29636
+ "31": "n",
29637
+ "32": "n"
29638
+ },
29639
+ "safari": {
29640
+ "3.1": "n",
29641
+ "3.2": "n",
29642
+ "4": "n",
29643
+ "5": "n",
29644
+ "5.1": "n",
29645
+ "6": "n",
29646
+ "6.1": "n",
29647
+ "7": "n"
29648
+ },
29649
+ "opera": {
29650
+ "9": "n",
29651
+ "9.5-9.6": "n",
29652
+ "10.0-10.1": "n",
29653
+ "10.5": "n",
29654
+ "10.6": "n",
29655
+ "11": "n",
29656
+ "11.1": "n",
29657
+ "11.5": "n",
29658
+ "11.6": "n",
29659
+ "12": "n",
29660
+ "12.1": "n",
29661
+ "15": "n",
29662
+ "16": "n",
29663
+ "17": "n",
29664
+ "18": "n"
29665
+ },
29666
+ "ios_saf": {
29667
+ "3.2": "n",
29668
+ "4.0-4.1": "n",
29669
+ "4.2-4.3": "n",
29670
+ "5.0-5.1": "n",
29671
+ "6.0-6.1": "n",
29672
+ "7.0": "n"
29673
+ },
29674
+ "op_mini": {
29675
+ "5.0-7.0": "n"
29676
+ },
29677
+ "android": {
29678
+ "2.1": "n",
29679
+ "2.2": "n",
29680
+ "2.3": "n",
29681
+ "3": "n",
29682
+ "4": "n",
29683
+ "4.1": "n",
29684
+ "4.2-4.3": "n",
29685
+ "4.4": "n"
29686
+ },
29687
+ "bb": {
29688
+ "7": "n",
29689
+ "10": "n"
29690
+ },
29691
+ "op_mob": {
29692
+ "10": "n",
29693
+ "11": "n",
29694
+ "11.1": "n",
29695
+ "11.5": "n",
29696
+ "12": "n",
29697
+ "12.1": "n",
29698
+ "0": "n"
29699
+ },
29700
+ "and_chr": {
29701
+ "0": "n"
29702
+ },
29703
+ "and_ff": {
29704
+ "0": "n"
29705
+ },
29706
+ "ie_mob": {
29707
+ "10": "y"
29708
+ }
29709
+ },
29710
+ "notes": "",
29711
+ "usage_perc_y": 16.32,
29712
+ "usage_perc_a": 0,
29713
+ "ucprefix": false,
29714
+ "parent": "",
29715
+ "keywords": ""
29716
+ },
29717
+ "channel-messaging": {
29718
+ "title": "Channel messaging",
29719
+ "description": "Method for having two-way communication between browsing contexts (using MessageChannel)",
29720
+ "spec": "http://www.w3.org/TR/webmessaging/#channel-messaging",
29721
+ "status": "cr",
29722
+ "links": [{
29723
+ "url": "http://dev.opera.com/articles/view/window-postmessage-messagechannel/#channel",
29724
+ "title": "An Introduction to HTML5 web messaging"
29725
+ }],
29726
+ "categories": ["JS API"],
29727
+ "stats": {
29728
+ "ie": {
29729
+ "5.5": "n",
29730
+ "6": "n",
29731
+ "7": "n",
29732
+ "8": "n",
29733
+ "9": "n",
29734
+ "10": "y",
29735
+ "11": "y"
29736
+ },
29737
+ "firefox": {
29738
+ "2": "n",
29739
+ "3": "n",
29740
+ "3.5": "n",
29741
+ "3.6": "n",
29742
+ "4": "n",
29743
+ "5": "n",
29744
+ "6": "n",
29745
+ "7": "n",
29746
+ "8": "n",
29747
+ "9": "n",
29748
+ "10": "n",
29749
+ "11": "n",
29750
+ "12": "n",
29751
+ "13": "n",
29752
+ "14": "n",
29753
+ "15": "n",
29754
+ "16": "n",
29755
+ "17": "n",
29756
+ "18": "n",
29757
+ "19": "n",
29758
+ "20": "n",
29759
+ "21": "n",
29760
+ "22": "n",
29761
+ "23": "n",
29762
+ "24": "n",
29763
+ "25": "n",
29764
+ "26": "n",
29765
+ "27": "n"
29766
+ },
29767
+ "chrome": {
29768
+ "4": "y",
29769
+ "5": "y",
29770
+ "6": "y",
29771
+ "7": "y",
29772
+ "8": "y",
29773
+ "9": "y",
29774
+ "10": "y",
29775
+ "11": "y",
29776
+ "12": "y",
29777
+ "13": "y",
29778
+ "14": "y",
29779
+ "15": "y",
29780
+ "16": "y",
29781
+ "17": "y",
29782
+ "18": "y",
29783
+ "19": "y",
29784
+ "20": "y",
29785
+ "21": "y",
29786
+ "22": "y",
29787
+ "23": "y",
29788
+ "24": "y",
29789
+ "25": "y",
29790
+ "26": "y",
29791
+ "27": "y",
29792
+ "28": "y",
29793
+ "29": "y",
29794
+ "30": "y",
29795
+ "31": "y",
29796
+ "32": "y"
29797
+ },
29798
+ "safari": {
29799
+ "3.1": "n",
29800
+ "3.2": "n",
29801
+ "4": "n",
29802
+ "5": "y",
29803
+ "5.1": "y",
29804
+ "6": "y",
29805
+ "6.1": "y",
29806
+ "7": "y"
29807
+ },
29808
+ "opera": {
29809
+ "9": "n",
29810
+ "9.5-9.6": "u",
29811
+ "10.0-10.1": "u",
29812
+ "10.5": "u",
29813
+ "10.6": "y",
29814
+ "11": "y",
29815
+ "11.1": "y",
29816
+ "11.5": "y",
29817
+ "11.6": "y",
29818
+ "12": "y",
29819
+ "12.1": "y",
29820
+ "15": "y",
29821
+ "16": "y",
29822
+ "17": "y",
29823
+ "18": "y"
29824
+ },
29825
+ "ios_saf": {
29826
+ "3.2": "n",
29827
+ "4.0-4.1": "n",
29828
+ "4.2-4.3": "n",
29829
+ "5.0-5.1": "y",
29830
+ "6.0-6.1": "y",
29831
+ "7.0": "y"
29832
+ },
29833
+ "op_mini": {
29834
+ "5.0-7.0": "n"
29835
+ },
29836
+ "android": {
29837
+ "2.1": "n",
29838
+ "2.2": "n",
29839
+ "2.3": "n",
29840
+ "3": "n",
29841
+ "4": "n",
29842
+ "4.1": "n",
29843
+ "4.2-4.3": "n",
29844
+ "4.4": "y"
29845
+ },
29846
+ "bb": {
29847
+ "7": "y",
29848
+ "10": "y"
29849
+ },
29850
+ "op_mob": {
29851
+ "10": "u",
29852
+ "11": "y",
29853
+ "11.1": "y",
29854
+ "11.5": "y",
29855
+ "12": "y",
29856
+ "12.1": "y",
29857
+ "0": "y"
29858
+ },
29859
+ "and_chr": {
29860
+ "0": "y"
29861
+ },
29862
+ "and_ff": {
29863
+ "0": "n"
29864
+ },
29865
+ "ie_mob": {
29866
+ "10": "y"
29867
+ }
29868
+ },
29869
+ "notes": "",
29870
+ "usage_perc_y": 55.07,
29871
+ "usage_perc_a": 0,
29872
+ "ucprefix": false,
29873
+ "parent": "x-doc-messaging",
29874
+ "keywords": ""
29875
+ },
29876
+ "css3-tabsize": {
29877
+ "title": "CSS3 tab-size",
29878
+ "description": "Method of customizing the width of a tab character. Only effective using 'white-space: pre'.",
29879
+ "spec": "http://www.w3.org/TR/css3-text/#tab-size1",
29880
+ "status": "wd",
29881
+ "links": [{
29882
+ "url": "https://developer.mozilla.org/en-US/docs/Web/CSS/tab-size",
29883
+ "title": "MDN article"
29884
+ }],
29885
+ "categories": ["CSS3"],
29886
+ "stats": {
29887
+ "ie": {
29888
+ "5.5": "n",
29889
+ "6": "n",
29890
+ "7": "n",
29891
+ "8": "n",
29892
+ "9": "n",
29893
+ "10": "n",
29894
+ "11": "n"
29895
+ },
29896
+ "firefox": {
29897
+ "2": "n",
29898
+ "3": "n",
29899
+ "3.5": "n",
29900
+ "3.6": "n",
29901
+ "4": "y x",
29902
+ "5": "y x",
29903
+ "6": "y x",
29904
+ "7": "y x",
29905
+ "8": "y x",
29906
+ "9": "y x",
29907
+ "10": "y x",
29908
+ "11": "y x",
29909
+ "12": "y x",
29910
+ "13": "y x",
29911
+ "14": "y x",
29912
+ "15": "y x",
29913
+ "16": "y x",
29914
+ "17": "y x",
29915
+ "18": "y x",
29916
+ "19": "y x",
29917
+ "20": "y x",
29918
+ "21": "y x",
29919
+ "22": "y x",
29920
+ "23": "y x",
29921
+ "24": "y x",
29922
+ "25": "y x",
29923
+ "26": "y x",
29924
+ "27": "y x"
29925
+ },
29926
+ "chrome": {
29927
+ "4": "n",
29928
+ "5": "n",
29929
+ "6": "n",
29930
+ "7": "n",
29931
+ "8": "n",
29932
+ "9": "n",
29933
+ "10": "n",
29934
+ "11": "n",
29935
+ "12": "n",
29936
+ "13": "n",
29937
+ "14": "n",
29938
+ "15": "n",
29939
+ "16": "n",
29940
+ "17": "n",
29941
+ "18": "n",
29942
+ "19": "n",
29943
+ "20": "n",
29944
+ "21": "y",
29945
+ "22": "y",
29946
+ "23": "y",
29947
+ "24": "y",
29948
+ "25": "y",
29949
+ "26": "y",
29950
+ "27": "y",
29951
+ "28": "y",
29952
+ "29": "y",
29953
+ "30": "y",
29954
+ "31": "y",
29955
+ "32": "y"
29956
+ },
29957
+ "safari": {
29958
+ "3.1": "n",
29959
+ "3.2": "n",
29960
+ "4": "n",
29961
+ "5": "n",
29962
+ "5.1": "n",
29963
+ "6": "n",
29964
+ "6.1": "y",
29965
+ "7": "y"
29966
+ },
29967
+ "opera": {
29968
+ "9": "n",
29969
+ "9.5-9.6": "n",
29970
+ "10.0-10.1": "n",
29971
+ "10.5": "n",
29972
+ "10.6": "y x",
29973
+ "11": "y x",
29974
+ "11.1": "y x",
29975
+ "11.5": "y x",
29976
+ "11.6": "y x",
29977
+ "12": "y x",
29978
+ "12.1": "y x",
29979
+ "15": "y",
29980
+ "16": "y",
29981
+ "17": "y",
29982
+ "18": "y"
29983
+ },
29984
+ "ios_saf": {
29985
+ "3.2": "n",
29986
+ "4.0-4.1": "n",
29987
+ "4.2-4.3": "n",
29988
+ "5.0-5.1": "n",
29989
+ "6.0-6.1": "n",
29990
+ "7.0": "y"
29991
+ },
29992
+ "op_mini": {
29993
+ "5.0-7.0": "n"
29994
+ },
29995
+ "android": {
29996
+ "2.1": "n",
29997
+ "2.2": "n",
29998
+ "2.3": "n",
29999
+ "3": "n",
30000
+ "4": "n",
30001
+ "4.1": "n",
30002
+ "4.2-4.3": "n",
30003
+ "4.4": "y"
30004
+ },
30005
+ "bb": {
30006
+ "7": "y",
30007
+ "10": "y"
30008
+ },
30009
+ "op_mob": {
30010
+ "10": "n",
30011
+ "11": "y x",
30012
+ "11.1": "y x",
30013
+ "11.5": "y x",
30014
+ "12": "y x",
30015
+ "12.1": "y x",
30016
+ "0": "y"
30017
+ },
30018
+ "and_chr": {
30019
+ "0": "y"
30020
+ },
30021
+ "and_ff": {
30022
+ "0": "y x"
30023
+ },
30024
+ "ie_mob": {
30025
+ "10": "n"
30026
+ }
30027
+ },
30028
+ "notes": "",
30029
+ "usage_perc_y": 53.05,
30030
+ "usage_perc_a": 0,
30031
+ "ucprefix": false,
30032
+ "parent": "",
30033
+ "keywords": "tab-size,tab-width"
30034
+ },
30035
+ "mutationobserver": {
30036
+ "title": "Mutation Observer",
30037
+ "description": "Method for observing and reacting to changes to the DOM. Replaces MutationEvents, which is deprecated.",
30038
+ "spec": "http://www.w3.org/TR/dom/",
30039
+ "status": "wd",
30040
+ "links": [{
30041
+ "url": "https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver",
30042
+ "title": "MutationObserver from MDN"
30043
+ }, {
30044
+ "url": "https://github.com/Polymer/MutationObservers",
30045
+ "title": "Polyfill"
30046
+ }],
30047
+ "categories": ["DOM", "JS API"],
30048
+ "stats": {
30049
+ "ie": {
30050
+ "5.5": "n",
30051
+ "6": "n",
30052
+ "7": "n",
30053
+ "8": "n",
30054
+ "9": "p",
30055
+ "10": "p",
30056
+ "11": "y"
30057
+ },
30058
+ "firefox": {
30059
+ "2": "n",
30060
+ "3": "n",
30061
+ "3.5": "n",
30062
+ "3.6": "n",
30063
+ "4": "n",
30064
+ "5": "n",
30065
+ "6": "n",
30066
+ "7": "n",
30067
+ "8": "n",
30068
+ "9": "n",
30069
+ "10": "n",
30070
+ "11": "n",
30071
+ "12": "n",
30072
+ "13": "n",
30073
+ "14": "y",
30074
+ "15": "y",
30075
+ "16": "y",
30076
+ "17": "y",
30077
+ "18": "y",
30078
+ "19": "y",
30079
+ "20": "y",
30080
+ "21": "y",
30081
+ "22": "y",
30082
+ "23": "y",
30083
+ "24": "y",
30084
+ "25": "y",
30085
+ "26": "y",
30086
+ "27": "y"
30087
+ },
30088
+ "chrome": {
30089
+ "4": "n",
30090
+ "5": "n",
30091
+ "6": "n",
30092
+ "7": "n",
30093
+ "8": "n",
30094
+ "9": "n",
30095
+ "10": "n",
30096
+ "11": "n",
30097
+ "12": "n",
30098
+ "13": "n",
30099
+ "14": "n",
30100
+ "15": "n",
30101
+ "16": "n",
30102
+ "17": "n",
30103
+ "18": "y x",
30104
+ "19": "y x",
30105
+ "20": "y x",
30106
+ "21": "y x",
30107
+ "22": "y x",
30108
+ "23": "y x",
30109
+ "24": "y x",
30110
+ "25": "y x",
30111
+ "26": "y x",
30112
+ "27": "y",
30113
+ "28": "y",
30114
+ "29": "y",
30115
+ "30": "y",
30116
+ "31": "y",
30117
+ "32": "y"
30118
+ },
30119
+ "safari": {
30120
+ "3.1": "n",
30121
+ "3.2": "n",
30122
+ "4": "n",
30123
+ "5": "n",
30124
+ "5.1": "n",
30125
+ "6": "y x",
30126
+ "6.1": "y",
30127
+ "7": "y"
30128
+ },
30129
+ "opera": {
30130
+ "9": "n",
30131
+ "9.5-9.6": "n",
30132
+ "10.0-10.1": "n",
30133
+ "10.5": "n",
30134
+ "10.6": "n",
30135
+ "11": "n",
30136
+ "11.1": "n",
30137
+ "11.5": "n",
30138
+ "11.6": "n",
30139
+ "12": "n",
30140
+ "12.1": "n",
30141
+ "15": "y",
30142
+ "16": "y",
30143
+ "17": "y",
30144
+ "18": "y"
30145
+ },
30146
+ "ios_saf": {
30147
+ "3.2": "n",
30148
+ "4.0-4.1": "n",
30149
+ "4.2-4.3": "n",
30150
+ "5.0-5.1": "n",
30151
+ "6.0-6.1": "y x",
30152
+ "7.0": "y"
30153
+ },
30154
+ "op_mini": {
30155
+ "5.0-7.0": "n"
30156
+ },
30157
+ "android": {
30158
+ "2.1": "n",
30159
+ "2.2": "n",
30160
+ "2.3": "n",
30161
+ "3": "n",
30162
+ "4": "p",
30163
+ "4.1": "p",
30164
+ "4.2-4.3": "p",
30165
+ "4.4": "y"
30166
+ },
30167
+ "bb": {
30168
+ "7": "n",
30169
+ "10": "y x"
30170
+ },
30171
+ "op_mob": {
30172
+ "10": "n",
30173
+ "11": "n",
30174
+ "11.1": "n",
30175
+ "11.5": "n",
30176
+ "12": "n",
30177
+ "12.1": "n",
30178
+ "0": "y"
30179
+ },
30180
+ "and_chr": {
30181
+ "0": "y"
30182
+ },
30183
+ "and_ff": {
30184
+ "0": "y"
30185
+ },
30186
+ "ie_mob": {
30187
+ "10": "p"
30188
+ }
30189
+ },
30190
+ "notes": "When the content of a node with a single CharacterData child node is changed by innerHTML attribute and the node have a single different one as a result, WebKit browsers consider it as a characterData mutation of the child CharacterData node, while other browsers think it as a childList mutation of the parent node.",
30191
+ "usage_perc_y": 54.8,
30192
+ "usage_perc_a": 0,
30193
+ "ucprefix": false,
30194
+ "parent": "",
30195
+ "keywords": "MutationObserver"
30196
+ },
30197
+ "css-selection": {
30198
+ "title": "::selection CSS pseudo-element",
30199
+ "description": "The ::selection CSS pseudo-element applies rules to the portion of a document that has been highlighted (e.g., selected with the mouse or another pointing device) by the user.",
30200
+ "spec": "https://developer.mozilla.org/en-US/docs/Web/CSS/::selection",
30201
+ "status": "unoff",
30202
+ "links": [{
30203
+ "url": "http://docs.webplatform.org/wiki/css/selectors/pseudo-elements/::selection",
30204
+ "title": "WebPlatform Docs"
30205
+ }, {
30206
+ "url": "http://quirksmode.org/css/selectors/selection.html",
30207
+ "title": "::selection test"
30208
+ }],
30209
+ "categories": ["CSS"],
30210
+ "stats": {
30211
+ "ie": {
30212
+ "5.5": "n",
30213
+ "6": "n",
30214
+ "7": "n",
30215
+ "8": "n",
30216
+ "9": "y",
30217
+ "10": "y",
30218
+ "11": "y"
30219
+ },
30220
+ "firefox": {
30221
+ "2": "y x",
30222
+ "3": "y x",
30223
+ "3.5": "y x",
30224
+ "3.6": "y x",
30225
+ "4": "y x",
30226
+ "5": "y x",
30227
+ "6": "y x",
30228
+ "7": "y x",
30229
+ "8": "y x",
30230
+ "9": "y x",
30231
+ "10": "y x",
30232
+ "11": "y x",
30233
+ "12": "y x",
30234
+ "13": "y x",
30235
+ "14": "y x",
30236
+ "15": "y x",
30237
+ "16": "y x",
30238
+ "17": "y x",
30239
+ "18": "y x",
30240
+ "19": "y x",
30241
+ "20": "y x",
30242
+ "21": "y x",
30243
+ "22": "y x",
30244
+ "23": "y x",
30245
+ "24": "y x",
30246
+ "25": "y x",
30247
+ "26": "y x",
30248
+ "27": "y x"
30249
+ },
30250
+ "chrome": {
30251
+ "4": "y",
30252
+ "5": "y",
30253
+ "6": "y",
30254
+ "7": "y",
30255
+ "8": "y",
30256
+ "9": "y",
30257
+ "10": "y",
30258
+ "11": "y",
30259
+ "12": "y",
30260
+ "13": "y",
30261
+ "14": "y",
30262
+ "15": "y",
30263
+ "16": "y",
30264
+ "17": "y",
30265
+ "18": "y",
30266
+ "19": "y",
30267
+ "20": "y",
30268
+ "21": "y",
30269
+ "22": "y",
30270
+ "23": "y",
30271
+ "24": "y",
30272
+ "25": "y",
30273
+ "26": "y",
30274
+ "27": "y",
30275
+ "28": "y",
30276
+ "29": "y",
30277
+ "30": "y",
30278
+ "31": "y",
30279
+ "32": "y"
30280
+ },
30281
+ "safari": {
30282
+ "3.1": "y",
30283
+ "3.2": "y",
30284
+ "4": "y",
30285
+ "5": "y",
30286
+ "5.1": "y",
30287
+ "6": "y",
30288
+ "6.1": "y",
30289
+ "7": "y"
30290
+ },
30291
+ "opera": {
30292
+ "9": "n",
30293
+ "9.5-9.6": "y",
30294
+ "10.0-10.1": "y",
30295
+ "10.5": "y",
30296
+ "10.6": "y",
30297
+ "11": "y",
30298
+ "11.1": "y",
30299
+ "11.5": "y",
30300
+ "11.6": "y",
30301
+ "12": "y",
30302
+ "12.1": "y",
30303
+ "15": "y",
30304
+ "16": "y",
30305
+ "17": "y",
30306
+ "18": "y"
30307
+ },
30308
+ "ios_saf": {
30309
+ "3.2": "n",
30310
+ "4.0-4.1": "n",
30311
+ "4.2-4.3": "n",
30312
+ "5.0-5.1": "n",
30313
+ "6.0-6.1": "n",
30314
+ "7.0": "n"
30315
+ },
30316
+ "op_mini": {
30317
+ "5.0-7.0": "n"
30318
+ },
30319
+ "android": {
30320
+ "2.1": "n",
30321
+ "2.2": "n",
30322
+ "2.3": "n",
30323
+ "3": "n",
30324
+ "4": "n",
30325
+ "4.1": "n",
30326
+ "4.2-4.3": "n",
30327
+ "4.4": "y"
30328
+ },
30329
+ "bb": {
30330
+ "7": "n",
30331
+ "10": "n"
30332
+ },
30333
+ "op_mob": {
30334
+ "10": "u",
30335
+ "11": "u",
30336
+ "11.1": "u",
30337
+ "11.5": "y",
30338
+ "12": "y",
30339
+ "12.1": "y",
30340
+ "0": "y"
30341
+ },
30342
+ "and_chr": {
30343
+ "0": "y"
30344
+ },
30345
+ "and_ff": {
30346
+ "0": "n"
30347
+ },
30348
+ "ie_mob": {
30349
+ "10": "y"
30350
+ }
30351
+ },
30352
+ "notes": "",
30353
+ "usage_perc_y": 71.68,
30354
+ "usage_perc_a": 0,
30355
+ "ucprefix": false,
30356
+ "parent": "",
30357
+ "keywords": "::selection,selection"
30358
+ },
30359
+ "canvas-blending": {
30360
+ "title": "Canvas blend modes",
30361
+ "description": "Method of defining the effect resulting from overlaying two layers on a Canvas element. ",
30362
+ "spec": "http://www.w3.org/TR/compositing-1/#blending",
30363
+ "status": "wd",
30364
+ "links": [{
30365
+ "url": "http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/",
30366
+ "title": "Blog post"
30367
+ }],
30368
+ "categories": ["Canvas"],
30369
+ "stats": {
30370
+ "ie": {
30371
+ "5.5": "n",
30372
+ "6": "n",
30373
+ "7": "n",
30374
+ "8": "n",
30375
+ "9": "n",
30376
+ "10": "n",
30377
+ "11": "n"
30378
+ },
30379
+ "firefox": {
30380
+ "2": "n",
30381
+ "3": "n",
30382
+ "3.5": "n",
30383
+ "3.6": "n",
30384
+ "4": "n",
30385
+ "5": "n",
30386
+ "6": "n",
30387
+ "7": "n",
30388
+ "8": "n",
30389
+ "9": "n",
30390
+ "10": "n",
30391
+ "11": "n",
30392
+ "12": "n",
30393
+ "13": "n",
30394
+ "14": "n",
30395
+ "15": "n",
30396
+ "16": "n",
30397
+ "17": "n",
30398
+ "18": "n",
30399
+ "19": "n",
30400
+ "20": "y",
30401
+ "21": "y",
30402
+ "22": "y",
30403
+ "23": "y",
30404
+ "24": "y",
30405
+ "25": "y",
30406
+ "26": "y",
30407
+ "27": "y"
30408
+ },
30409
+ "chrome": {
30410
+ "4": "n",
30411
+ "5": "n",
30412
+ "6": "n",
30413
+ "7": "n",
30414
+ "8": "n",
30415
+ "9": "n",
30416
+ "10": "n",
30417
+ "11": "n",
30418
+ "12": "n",
30419
+ "13": "n",
30420
+ "14": "n",
30421
+ "15": "n",
30422
+ "16": "n",
30423
+ "17": "n",
30424
+ "18": "n",
30425
+ "19": "n",
30426
+ "20": "n",
30427
+ "21": "n",
30428
+ "22": "n",
30429
+ "23": "n",
30430
+ "24": "n",
30431
+ "25": "n",
30432
+ "26": "n",
30433
+ "27": "n",
30434
+ "28": "n",
30435
+ "29": "n",
30436
+ "30": "y",
30437
+ "31": "y",
30438
+ "32": "y"
30439
+ },
30440
+ "safari": {
30441
+ "3.1": "n",
30442
+ "3.2": "n",
30443
+ "4": "n",
30444
+ "5": "n",
30445
+ "5.1": "n",
30446
+ "6": "n",
30447
+ "6.1": "y",
30448
+ "7": "y"
30449
+ },
30450
+ "opera": {
30451
+ "9": "n",
30452
+ "9.5-9.6": "n",
30453
+ "10.0-10.1": "n",
30454
+ "10.5": "n",
30455
+ "10.6": "n",
30456
+ "11": "n",
30457
+ "11.1": "n",
30458
+ "11.5": "n",
30459
+ "11.6": "n",
30460
+ "12": "n",
30461
+ "12.1": "n",
30462
+ "15": "n",
30463
+ "16": "n",
30464
+ "17": "y",
30465
+ "18": "y"
30466
+ },
30467
+ "ios_saf": {
30468
+ "3.2": "n",
30469
+ "4.0-4.1": "n",
30470
+ "4.2-4.3": "n",
30471
+ "5.0-5.1": "n",
30472
+ "6.0-6.1": "n",
30473
+ "7.0": "y"
30474
+ },
30475
+ "op_mini": {
30476
+ "5.0-7.0": "n"
30477
+ },
30478
+ "android": {
30479
+ "2.1": "n",
30480
+ "2.2": "n",
30481
+ "2.3": "n",
30482
+ "3": "n",
30483
+ "4": "n",
30484
+ "4.1": "n",
30485
+ "4.2-4.3": "n",
30486
+ "4.4": "y"
30487
+ },
30488
+ "bb": {
30489
+ "7": "n",
30490
+ "10": "n"
30491
+ },
30492
+ "op_mob": {
30493
+ "10": "n",
30494
+ "11": "n",
30495
+ "11.1": "n",
30496
+ "11.5": "n",
30497
+ "12": "n",
30498
+ "12.1": "n",
30499
+ "0": "n"
30500
+ },
30501
+ "and_chr": {
30502
+ "0": "y"
30503
+ },
30504
+ "and_ff": {
30505
+ "0": "y"
30506
+ },
30507
+ "ie_mob": {
30508
+ "10": "n"
30509
+ }
30510
+ },
30511
+ "notes": "",
30512
+ "usage_perc_y": 42.33,
30513
+ "usage_perc_a": 0,
30514
+ "ucprefix": false,
30515
+ "parent": "canvas",
30516
+ "keywords": ""
30517
+ },
30518
+ "clipboard": {
30519
+ "title": "Clipboard API",
30520
+ "description": "API to provide copy, cut and paste functionality using the OS clipboard.",
30521
+ "spec": "http://www.w3.org/TR/clipboard-apis/",
30522
+ "status": "wd",
30523
+ "links": [{
30524
+ "url": "http://www.deluxeblogtips.com/2010/06/javascript-copy-to-clipboard.html",
30525
+ "title": "Blog post on cross-browser usage"
30526
+ }, {
30527
+ "url": "https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent",
30528
+ "title": "MDN page on ClipboardEvent"
30529
+ }],
30530
+ "categories": ["JS API"],
30531
+ "stats": {
30532
+ "ie": {
30533
+ "5.5": "a #1",
30534
+ "6": "a #1",
30535
+ "7": "a #1",
30536
+ "8": "a #1",
30537
+ "9": "a #1",
30538
+ "10": "a #1",
30539
+ "11": "a #1"
30540
+ },
30541
+ "firefox": {
30542
+ "2": "n",
30543
+ "3": "n",
30544
+ "3.5": "n",
30545
+ "3.6": "n",
30546
+ "4": "n",
30547
+ "5": "n",
30548
+ "6": "n",
30549
+ "7": "n",
30550
+ "8": "n",
30551
+ "9": "n",
30552
+ "10": "n",
30553
+ "11": "n",
30554
+ "12": "n",
30555
+ "13": "n",
30556
+ "14": "n",
30557
+ "15": "n",
30558
+ "16": "n",
30559
+ "17": "n",
30560
+ "18": "n",
30561
+ "19": "n",
30562
+ "20": "n",
30563
+ "21": "n",
30564
+ "22": "y",
30565
+ "23": "y",
30566
+ "24": "y",
30567
+ "25": "y",
30568
+ "26": "y",
30569
+ "27": "y"
30570
+ },
30571
+ "chrome": {
30572
+ "4": "n",
30573
+ "5": "n",
30574
+ "6": "n",
30575
+ "7": "n",
30576
+ "8": "n",
30577
+ "9": "n",
30578
+ "10": "n",
30579
+ "11": "n",
30580
+ "12": "n",
30581
+ "13": "a",
30582
+ "14": "a",
30583
+ "15": "a",
30584
+ "16": "a",
30585
+ "17": "a",
30586
+ "18": "a",
30587
+ "19": "a",
30588
+ "20": "a",
30589
+ "21": "a",
30590
+ "22": "a",
30591
+ "23": "a",
30592
+ "24": "a",
30593
+ "25": "a",
30594
+ "26": "a",
30595
+ "27": "a",
30596
+ "28": "a",
30597
+ "29": "a",
30598
+ "30": "a",
30599
+ "31": "a",
30600
+ "32": "a"
30601
+ },
30602
+ "safari": {
30603
+ "3.1": "u",
30604
+ "3.2": "u",
30605
+ "4": "a",
30606
+ "5": "a",
30607
+ "5.1": "a",
30608
+ "6": "a",
30609
+ "6.1": "a",
30610
+ "7": "a"
30611
+ },
30612
+ "opera": {
30613
+ "9": "n",
30614
+ "9.5-9.6": "n",
30615
+ "10.0-10.1": "n",
30616
+ "10.5": "n",
30617
+ "10.6": "n",
30618
+ "11": "n",
30619
+ "11.1": "n",
30620
+ "11.5": "n",
30621
+ "11.6": "n",
30622
+ "12": "n",
30623
+ "12.1": "n",
30624
+ "15": "n",
30625
+ "16": "a",
30626
+ "17": "a",
30627
+ "18": "a"
30628
+ },
30629
+ "ios_saf": {
30630
+ "3.2": "n",
30631
+ "4.0-4.1": "n",
30632
+ "4.2-4.3": "n",
30633
+ "5.0-5.1": "a",
30634
+ "6.0-6.1": "a",
30635
+ "7.0": "a"
30636
+ },
30637
+ "op_mini": {
30638
+ "5.0-7.0": "n"
30639
+ },
30640
+ "android": {
30641
+ "2.1": "n",
30642
+ "2.2": "n",
30643
+ "2.3": "n",
30644
+ "3": "n",
30645
+ "4": "n",
30646
+ "4.1": "n",
30647
+ "4.2-4.3": "n",
30648
+ "4.4": "a"
30649
+ },
30650
+ "bb": {
30651
+ "7": "n",
30652
+ "10": "a"
30653
+ },
30654
+ "op_mob": {
30655
+ "10": "n",
30656
+ "11": "n",
30657
+ "11.1": "n",
30658
+ "11.5": "n",
30659
+ "12": "n",
30660
+ "12.1": "n",
30661
+ "0": "a"
30662
+ },
30663
+ "and_chr": {
30664
+ "0": "a"
30665
+ },
30666
+ "and_ff": {
30667
+ "0": "y"
30668
+ },
30669
+ "ie_mob": {
30670
+ "10": "n"
30671
+ }
30672
+ },
30673
+ "notes": "Partial support in IE refers using <a href=\"http://msdn.microsoft.com/en-us/library/ie/ms535220%28v=vs.85%29.aspx\">a non-standard method</a> of interacting with the clipboard. For other browsers it refers to not supporting the ClipboardEvent constructor.",
30674
+ "usage_perc_y": 12.83,
30675
+ "usage_perc_a": 67.91,
30676
+ "ucprefix": false,
30677
+ "parent": "",
30678
+ "keywords": "cut,copy,paste,clipboarddata"
30679
+ },
30680
+ "rtcpeerconnection": {
30681
+ "title": "WebRTC Peer-to-peer connections",
30682
+ "description": "Method of allowing two users to communicate directly, browser to browser using the RTCPeerConnection API.",
30683
+ "spec": "http://www.w3.org/TR/webrtc/#peer-to-peer-connections",
30684
+ "status": "wd",
30685
+ "links": [{
30686
+ "url": "http://www.webrtc.org/",
30687
+ "title": "WebRTC Project site"
30688
+ }],
30689
+ "categories": ["JS API"],
30690
+ "stats": {
30691
+ "ie": {
30692
+ "5.5": "n",
30693
+ "6": "n",
30694
+ "7": "n",
30695
+ "8": "n",
30696
+ "9": "n",
30697
+ "10": "n",
30698
+ "11": "n"
30699
+ },
30700
+ "firefox": {
30701
+ "2": "n",
30702
+ "3": "n",
30703
+ "3.5": "n",
30704
+ "3.6": "n",
30705
+ "4": "n",
30706
+ "5": "n",
30707
+ "6": "n",
30708
+ "7": "n",
30709
+ "8": "n",
30710
+ "9": "n",
30711
+ "10": "n",
30712
+ "11": "n",
30713
+ "12": "n",
30714
+ "13": "n",
30715
+ "14": "n",
30716
+ "15": "n",
30717
+ "16": "n",
30718
+ "17": "n",
30719
+ "18": "n",
30720
+ "19": "n",
30721
+ "20": "n",
30722
+ "21": "n",
30723
+ "22": "y x",
30724
+ "23": "y x",
30725
+ "24": "y x",
30726
+ "25": "y x",
30727
+ "26": "y x",
30728
+ "27": "y x"
30729
+ },
30730
+ "chrome": {
30731
+ "4": "n",
30732
+ "5": "n",
30733
+ "6": "n",
30734
+ "7": "n",
30735
+ "8": "n",
30736
+ "9": "n",
30737
+ "10": "n",
30738
+ "11": "n",
30739
+ "12": "n",
30740
+ "13": "n",
30741
+ "14": "n",
30742
+ "15": "n",
30743
+ "16": "n",
30744
+ "17": "n",
30745
+ "18": "n",
30746
+ "19": "n",
30747
+ "20": "n",
30748
+ "21": "n",
30749
+ "22": "n",
30750
+ "23": "y x",
30751
+ "24": "y x",
30752
+ "25": "y x",
30753
+ "26": "y x",
30754
+ "27": "y x",
30755
+ "28": "y x",
30756
+ "29": "y x",
30757
+ "30": "y x",
30758
+ "31": "y x",
30759
+ "32": "y x"
30760
+ },
30761
+ "safari": {
30762
+ "3.1": "n",
30763
+ "3.2": "n",
30764
+ "4": "n",
30765
+ "5": "n",
30766
+ "5.1": "n",
30767
+ "6": "n",
30768
+ "6.1": "u",
30769
+ "7": "u"
30770
+ },
30771
+ "opera": {
30772
+ "9": "n",
30773
+ "9.5-9.6": "n",
30774
+ "10.0-10.1": "n",
30775
+ "10.5": "n",
30776
+ "10.6": "n",
30777
+ "11": "n",
30778
+ "11.1": "n",
30779
+ "11.5": "n",
30780
+ "11.6": "n",
30781
+ "12": "n",
30782
+ "12.1": "n",
30783
+ "15": "n",
30784
+ "16": "n",
30785
+ "17": "n",
30786
+ "18": "n"
30787
+ },
30788
+ "ios_saf": {
30789
+ "3.2": "n",
30790
+ "4.0-4.1": "n",
30791
+ "4.2-4.3": "n",
30792
+ "5.0-5.1": "n",
30793
+ "6.0-6.1": "n",
30794
+ "7.0": "n"
30795
+ },
30796
+ "op_mini": {
30797
+ "5.0-7.0": "n"
30798
+ },
30799
+ "android": {
30800
+ "2.1": "n",
30801
+ "2.2": "n",
30802
+ "2.3": "n",
30803
+ "3": "n",
30804
+ "4": "n",
30805
+ "4.1": "n",
30806
+ "4.2-4.3": "n",
30807
+ "4.4": "n"
30808
+ },
30809
+ "bb": {
30810
+ "7": "n",
30811
+ "10": "n"
30812
+ },
30813
+ "op_mob": {
30814
+ "10": "n",
30815
+ "11": "n",
30816
+ "11.1": "n",
30817
+ "11.5": "n",
30818
+ "12": "n",
30819
+ "12.1": "n",
30820
+ "0": "y x"
30821
+ },
30822
+ "and_chr": {
30823
+ "0": "y x"
30824
+ },
30825
+ "and_ff": {
30826
+ "0": "y x"
30827
+ },
30828
+ "ie_mob": {
30829
+ "10": "n"
30830
+ }
30831
+ },
30832
+ "notes": "BlackBerry 10 recognizes RTCPeerConnection but real support is unconfirmed.",
30833
+ "usage_perc_y": 46.24,
30834
+ "usage_perc_a": 0,
30835
+ "ucprefix": false,
30836
+ "parent": "",
30837
+ "keywords": ""
30838
+ }
30839
+ }
30840
+ }
30841
+ },{}],36:[function(require,module,exports){
30842
+ /**
30843
+ * Abstract implementation of edit tree interface.
30844
+ * Edit tree is a named container of editable “name-value” child elements,
30845
+ * parsed from <code>source</code>. This container provides convenient methods
30846
+ * for editing/adding/removing child elements. All these update actions are
30847
+ * instantly reflected in the <code>source</code> code with respect of formatting.
30848
+ * <br><br>
30849
+ * For example, developer can create an edit tree from CSS rule and add or
30850
+ * remove properties from it–all changes will be immediately reflected in the
30851
+ * original source.
30852
+ * <br><br>
30853
+ * All classes defined in this module should be extended the same way as in
30854
+ * Backbone framework: using <code>extend</code> method to create new class and
30855
+ * <code>initialize</code> method to define custom class constructor.
30856
+ *
30857
+ * @example
30858
+ * <pre><code>
30859
+ * var MyClass = require('editTree/base').EditElement.extend({
30860
+ * initialize: function() {
30861
+ * // constructor code here
30862
+ * }
30863
+ * });
30864
+ *
30865
+ * var elem = new MyClass();
30866
+ * </code></pre>
30867
+ */
30868
+ if (typeof module === 'object' && typeof define !== 'function') {
30869
+ var define = function (factory) {
30870
+ module.exports = factory(require, exports, module);
30871
+ };
30872
+ }
30873
+
30874
+ define(function(require, exports, module) {
30875
+ var range = require('../assets/range');
30876
+ var utils = require('../utils/common');
30877
+ var klass = require('../vendor/klass');
30878
+
30879
+ /**
30880
+ * Named container of edited source
30881
+ * @type EditContainer
30882
+ * @param {String} source
30883
+ * @param {Object} options
30884
+ */
30885
+ function EditContainer(source, options) {
30886
+ this.options = utils.extend({offset: 0}, options);
30887
+ /**
30888
+ * Source code of edited structure. All changes in the structure are
30889
+ * immediately reflected into this property
30890
+ */
30891
+ this.source = source;
30892
+
30893
+ /**
30894
+ * List of all editable children
30895
+ * @private
30896
+ */
30897
+ this._children = [];
30898
+
30899
+ /**
30900
+ * Hash of all positions of container
30901
+ * @private
30902
+ */
30903
+ this._positions = {
30904
+ name: 0
30905
+ };
30906
+
30907
+ this.initialize.apply(this, arguments);
30908
+ }
30909
+
30910
+ /**
30911
+ * The self-propagating extend function for classes.
30912
+ * @type Function
30913
+ */
30914
+ EditContainer.extend = klass.extend;
30915
+
30916
+ EditContainer.prototype = {
30917
+ type: 'container',
30918
+ /**
30919
+ * Child class constructor
30920
+ */
30921
+ initialize: function() {},
30922
+
30923
+ /**
30924
+ * Make position absolute
30925
+ * @private
30926
+ * @param {Number} num
30927
+ * @param {Boolean} isAbsolute
30928
+ * @returns {Boolean}
30929
+ */
30930
+ _pos: function(num, isAbsolute) {
30931
+ return num + (isAbsolute ? this.options.offset : 0);
30932
+ },
30933
+
30934
+ /**
30935
+ * Replace substring of tag's source
30936
+ * @param {String} value
30937
+ * @param {Number} start
30938
+ * @param {Number} end
30939
+ * @private
30940
+ */
30941
+ _updateSource: function(value, start, end) {
30942
+ // create modification range
30943
+ var r = range.create(start, typeof end === 'undefined' ? 0 : end - start);
30944
+ var delta = value.length - r.length();
30945
+
30946
+ var update = function(obj) {
30947
+ Object.keys(obj).forEach(function(k) {
30948
+ if (obj[k] >= r.end) {
30949
+ obj[k] += delta;
30950
+ }
30951
+ });
30952
+ };
30953
+
30954
+ // update affected positions of current container
30955
+ update(this._positions);
30956
+
30957
+ // update affected positions of children
30958
+ var recursiveUpdate = function(items) {
30959
+ items.forEach(function(item) {
30960
+ update(item._positions);
30961
+ if (item.type == 'container') {
30962
+ recursiveUpdate(item.list());
30963
+ }
30964
+ });
30965
+ };
30966
+
30967
+ recursiveUpdate(this.list());
30968
+ this.source = utils.replaceSubstring(this.source, value, r);
30969
+ },
30970
+
30971
+
30972
+ /**
30973
+ * Adds new attribute
30974
+ * @param {String} name Property name
30975
+ * @param {String} value Property value
30976
+ * @param {Number} pos Position at which to insert new property. By
30977
+ * default the property is inserted at the end of rule
30978
+ * @returns {EditElement} Newly created element
30979
+ */
30980
+ add: function(name, value, pos) {
30981
+ // this is abstract implementation
30982
+ var item = new EditElement(name, value);
30983
+ this._children.push(item);
30984
+ return item;
30985
+ },
30986
+
30987
+ /**
30988
+ * Returns attribute object
30989
+ * @param {String} name Attribute name or its index
30990
+ * @returns {EditElement}
30991
+ */
30992
+ get: function(name) {
30993
+ if (typeof name === 'number') {
30994
+ return this.list()[name];
30995
+ }
30996
+
30997
+ if (typeof name === 'string') {
30998
+ return utils.find(this.list(), function(prop) {
30999
+ return prop.name() === name;
31000
+ });
31001
+ }
31002
+
31003
+ return name;
31004
+ },
31005
+
31006
+ /**
31007
+ * Returns all children by name or indexes
31008
+ * @param {Object} name Element name(s) or indexes (<code>String</code>,
31009
+ * <code>Array</code>, <code>Number</code>)
31010
+ * @returns {Array}
31011
+ */
31012
+ getAll: function(name) {
31013
+ if (!Array.isArray(name))
31014
+ name = [name];
31015
+
31016
+ // split names and indexes
31017
+ var names = [], indexes = [];
31018
+ name.forEach(function(item) {
31019
+ if (typeof item === 'string') {
31020
+ names.push(item);
31021
+ } else if (typeof item === 'number') {
31022
+ indexes.push(item);
31023
+ }
31024
+ });
31025
+
31026
+ return this.list().filter(function(attribute, i) {
31027
+ return ~indexes.indexOf(i) || ~names.indexOf(attribute.name());
31028
+ });
31029
+ },
31030
+
31031
+ /**
31032
+ * Returns list of all editable child elements
31033
+ * @returns {Array}
31034
+ */
31035
+ list: function() {
31036
+ return this._children;
31037
+ },
31038
+
31039
+ /**
31040
+ * Remove child element
31041
+ * @param {String} name Property name or its index
31042
+ */
31043
+ remove: function(name) {
31044
+ var element = this.get(name);
31045
+ if (element) {
31046
+ this._updateSource('', element.fullRange());
31047
+ var ix = this._children.indexOf(element);
31048
+ if (~ix) {
31049
+ this._children.splice(ix, 1);
31050
+ }
31051
+ }
31052
+ },
31053
+
31054
+ /**
31055
+ * Returns index of editble child in list
31056
+ * @param {Object} item
31057
+ * @returns {Number}
31058
+ */
31059
+ indexOf: function(item) {
31060
+ return this.list().indexOf(this.get(item));
31061
+ },
31062
+
31063
+ /**
31064
+ * Returns or updates element value. If such element doesn't exists,
31065
+ * it will be created automatically and added at the end of child list.
31066
+ * @param {String} name Element name or its index
31067
+ * @param {String} value New element value
31068
+ * @returns {String}
31069
+ */
31070
+ value: function(name, value, pos) {
31071
+ var element = this.get(name);
31072
+ if (element)
31073
+ return element.value(value);
31074
+
31075
+ if (typeof value !== 'undefined') {
31076
+ // no such element — create it
31077
+ return this.add(name, value, pos);
31078
+ }
31079
+ },
31080
+
31081
+ /**
31082
+ * Returns all values of child elements found by <code>getAll()</code>
31083
+ * method
31084
+ * @param {Object} name Element name(s) or indexes (<code>String</code>,
31085
+ * <code>Array</code>, <code>Number</code>)
31086
+ * @returns {Array}
31087
+ */
31088
+ values: function(name) {
31089
+ return this.getAll(name).map(function(element) {
31090
+ return element.value();
31091
+ });
31092
+ },
31093
+
31094
+ /**
31095
+ * Sets or gets container name
31096
+ * @param {String} val New name. If not passed, current
31097
+ * name is returned
31098
+ * @return {String}
31099
+ */
31100
+ name: function(val) {
31101
+ if (typeof val !== 'undefined' && this._name !== (val = String(val))) {
31102
+ this._updateSource(val, this._positions.name, this._positions.name + this._name.length);
31103
+ this._name = val;
31104
+ }
31105
+
31106
+ return this._name;
31107
+ },
31108
+
31109
+ /**
31110
+ * Returns name range object
31111
+ * @param {Boolean} isAbsolute Return absolute range (with respect of
31112
+ * rule offset)
31113
+ * @returns {Range}
31114
+ */
31115
+ nameRange: function(isAbsolute) {
31116
+ return range.create(this._positions.name + (isAbsolute ? this.options.offset : 0), this.name());
31117
+ },
31118
+
31119
+ /**
31120
+ * Returns range of current source
31121
+ * @param {Boolean} isAbsolute
31122
+ */
31123
+ range: function(isAbsolute) {
31124
+ return range.create(isAbsolute ? this.options.offset : 0, this.valueOf());
31125
+ },
31126
+
31127
+ /**
31128
+ * Returns element that belongs to specified position
31129
+ * @param {Number} pos
31130
+ * @param {Boolean} isAbsolute
31131
+ * @returns {EditElement}
31132
+ */
31133
+ itemFromPosition: function(pos, isAbsolute) {
31134
+ return utils.find(this.list(), function(elem) {
31135
+ return elem.range(isAbsolute).inside(pos);
31136
+ });
31137
+ },
31138
+
31139
+ /**
31140
+ * Returns source code of current container
31141
+ * @returns {String}
31142
+ */
31143
+ toString: function() {
31144
+ return this.valueOf();
31145
+ },
31146
+
31147
+ valueOf: function() {
31148
+ return this.source;
31149
+ }
31150
+ };
31151
+
31152
+ /**
31153
+ * @param {EditContainer} parent
31154
+ * @param {Object} nameToken
31155
+ * @param {Object} valueToken
31156
+ */
31157
+ function EditElement(parent, nameToken, valueToken) {
31158
+ /** @type EditContainer */
31159
+ this.parent = parent;
31160
+
31161
+ this._name = nameToken.value;
31162
+ this._value = valueToken ? valueToken.value : '';
31163
+
31164
+ this._positions = {
31165
+ name: nameToken.start,
31166
+ value: valueToken ? valueToken.start : -1
31167
+ };
31168
+
31169
+ this.initialize.apply(this, arguments);
31170
+ }
31171
+
31172
+ /**
31173
+ * The self-propagating extend function for classes.
31174
+ * @type Function
31175
+ */
31176
+ EditElement.extend = klass.extend;
31177
+
31178
+ EditElement.prototype = {
31179
+ type: 'element',
31180
+
31181
+ /**
31182
+ * Child class constructor
31183
+ */
31184
+ initialize: function() {},
31185
+
31186
+ /**
31187
+ * Make position absolute
31188
+ * @private
31189
+ * @param {Number} num
31190
+ * @param {Boolean} isAbsolute
31191
+ * @returns {Boolean}
31192
+ */
31193
+ _pos: function(num, isAbsolute) {
31194
+ return num + (isAbsolute ? this.parent.options.offset : 0);
31195
+ },
31196
+
31197
+ /**
31198
+ * Sets of gets element value
31199
+ * @param {String} val New element value. If not passed, current
31200
+ * value is returned
31201
+ * @returns {String}
31202
+ */
31203
+ value: function(val) {
31204
+ if (typeof val !== 'undefined' && this._value !== (val = String(val))) {
31205
+ this.parent._updateSource(val, this.valueRange());
31206
+ this._value = val;
31207
+ }
31208
+
31209
+ return this._value;
31210
+ },
31211
+
31212
+ /**
31213
+ * Sets of gets element name
31214
+ * @param {String} val New element name. If not passed, current
31215
+ * name is returned
31216
+ * @returns {String}
31217
+ */
31218
+ name: function(val) {
31219
+ if (typeof val !== 'undefined' && this._name !== (val = String(val))) {
31220
+ this.parent._updateSource(val, this.nameRange());
31221
+ this._name = val;
31222
+ }
31223
+
31224
+ return this._name;
31225
+ },
31226
+
31227
+ /**
31228
+ * Returns position of element name token
31229
+ * @param {Boolean} isAbsolute Return absolute position
31230
+ * @returns {Number}
31231
+ */
31232
+ namePosition: function(isAbsolute) {
31233
+ return this._pos(this._positions.name, isAbsolute);
31234
+ },
31235
+
31236
+ /**
31237
+ * Returns position of element value token
31238
+ * @param {Boolean} isAbsolute Return absolute position
31239
+ * @returns {Number}
31240
+ */
31241
+ valuePosition: function(isAbsolute) {
31242
+ return this._pos(this._positions.value, isAbsolute);
31243
+ },
31244
+
31245
+ /**
31246
+ * Returns element name
31247
+ * @param {Boolean} isAbsolute Return absolute range
31248
+ * @returns {Range}
31249
+ */
31250
+ range: function(isAbsolute) {
31251
+ return range.create(this.namePosition(isAbsolute), this.valueOf());
31252
+ },
31253
+
31254
+ /**
31255
+ * Returns full element range, including possible indentation
31256
+ * @param {Boolean} isAbsolute Return absolute range
31257
+ * @returns {Range}
31258
+ */
31259
+ fullRange: function(isAbsolute) {
31260
+ return this.range(isAbsolute);
31261
+ },
31262
+
31263
+ /**
31264
+ * Returns element name range
31265
+ * @param {Boolean} isAbsolute Return absolute range
31266
+ * @returns {Range}
31267
+ */
31268
+ nameRange: function(isAbsolute) {
31269
+ return range.create(this.namePosition(isAbsolute), this.name());
31270
+ },
31271
+
31272
+ /**
31273
+ * Returns element value range
31274
+ * @param {Boolean} isAbsolute Return absolute range
31275
+ * @returns {Range}
31276
+ */
31277
+ valueRange: function(isAbsolute) {
31278
+ return range.create(this.valuePosition(isAbsolute), this.value());
31279
+ },
31280
+
31281
+ /**
31282
+ * Returns current element string representation
31283
+ * @returns {String}
31284
+ */
31285
+ toString: function() {
31286
+ return this.valueOf();
31287
+ },
31288
+
31289
+ valueOf: function() {
31290
+ return this.name() + this.value();
31291
+ }
31292
+ };
31293
+
31294
+ return {
31295
+ EditContainer: EditContainer,
31296
+ EditElement: EditElement,
31297
+
31298
+ /**
31299
+ * Creates token that can be fed to <code>EditElement</code>
31300
+ * @param {Number} start
31301
+ * @param {String} value
31302
+ * @param {String} type
31303
+ * @returns
31304
+ */
31305
+ createToken: function(start, value, type) {
31306
+ var obj = {
31307
+ start: start || 0,
31308
+ value: value || '',
31309
+ type: type
31310
+ };
31311
+
31312
+ obj.end = obj.start + obj.value.length;
31313
+ return obj;
31314
+ }
31315
+ };
31316
+ });
31317
+ },{"../assets/range":30,"../utils/common":73,"../vendor/klass":78}],37:[function(require,module,exports){
31318
+ /**
31319
+ * CSS EditTree is a module that can parse a CSS rule into a tree with
31320
+ * convenient methods for adding, modifying and removing CSS properties. These
31321
+ * changes can be written back to string with respect of code formatting.
31322
+ */
31323
+ if (typeof module === 'object' && typeof define !== 'function') {
31324
+ var define = function (factory) {
31325
+ module.exports = factory(require, exports, module);
31326
+ };
31327
+ }
31328
+
31329
+ define(function(require, exports, module) {
31330
+ var utils = require('../utils/common');
31331
+ var editTree = require('./base');
31332
+ var cssParser = require('../parser/css');
31333
+ var cssSections = require('../utils/cssSections');
31334
+ var range = require('../assets/range');
31335
+ var stringStream = require('../assets/stringStream');
31336
+ var tokenIterator = require('../assets/tokenIterator');
31337
+
31338
+ var defaultOptions = {
31339
+ styleBefore: '\n\t',
31340
+ styleSeparator: ': ',
31341
+ offset: 0
31342
+ };
31343
+
31344
+ var reSpaceStart = /^\s+/;
31345
+ var reSpaceEnd = /\s+$/;
31346
+ var WHITESPACE_REMOVE_FROM_START = 1;
31347
+ var WHITESPACE_REMOVE_FROM_END = 2;
31348
+
31349
+ /**
31350
+ * Modifies given range to remove whitespace from beginning
31351
+ * and/or from the end
31352
+ * @param {Range} rng Range to modify
31353
+ * @param {String} text Text that range belongs to
31354
+ * @param {Number} mask Mask indicating from which end
31355
+ * whitespace should be removed
31356
+ * @return {Range}
31357
+ */
31358
+ function trimWhitespaceInRange(rng, text, mask) {
31359
+ mask = mask || (WHITESPACE_REMOVE_FROM_START | WHITESPACE_REMOVE_FROM_END);
31360
+ text = rng.substring(text);
31361
+ var m;
31362
+ if ((mask & WHITESPACE_REMOVE_FROM_START) && (m = text.match(reSpaceStart))) {
31363
+ rng.start += m[0].length;
31364
+ }
31365
+
31366
+ if ((mask & WHITESPACE_REMOVE_FROM_END) && (m = text.match(reSpaceEnd))) {
31367
+ rng.end -= m[0].length;
31368
+ }
31369
+
31370
+ // in case given range is just a whatespace
31371
+ if (rng.end < rng.start) {
31372
+ rng.end = rng.start;
31373
+ }
31374
+
31375
+ return rng;
31376
+ }
31377
+
31378
+ /**
31379
+ * Consumes CSS property and value from current token
31380
+ * iterator state. Offsets iterator pointer into token
31381
+ * that can be used for next value consmption
31382
+ * @param {TokenIterator} it
31383
+ * @param {String} text
31384
+ * @return {Object} Object with `name` and `value` properties
31385
+ * ar ranges. Value range can be zero-length.
31386
+ */
31387
+ function consumeSingleProperty(it, text) {
31388
+ var name, value, end;
31389
+ var token = it.current();
31390
+
31391
+ if (!token) {
31392
+ return null;
31393
+ }
31394
+
31395
+ // skip whitespace
31396
+ var ws = {'white': 1, 'line': 1, 'comment': 1};
31397
+ while ((token = it.current())) {
31398
+ if (!(token.type in ws)) {
31399
+ break;
31400
+ }
31401
+ it.next();
31402
+ }
31403
+
31404
+ if (!it.hasNext()) {
31405
+ return null;
31406
+ }
31407
+
31408
+ // consume property name
31409
+ token = it.current();
31410
+ name = range(token.start, token.value);
31411
+ var isAtProperty = token.value.charAt(0) == '@';
31412
+ while (token = it.next()) {
31413
+ name.end = token.end;
31414
+ if (token.type == ':' || token.type == 'white') {
31415
+ name.end = token.start;
31416
+ it.next();
31417
+ if (token.type == ':' || isAtProperty) {
31418
+ // XXX I really ashame of this hardcode, but I need
31419
+ // to stop parsing if this is an SCSS mixin call,
31420
+ // for example: @include border-radius(10px)
31421
+ break;
31422
+ }
31423
+ } else if (token.type == ';' || token.type == 'line') {
31424
+ // there’s no value, looks like a mixin
31425
+ // or a special use case:
31426
+ // user is writing a new property or abbreviation
31427
+ name.end = token.start;
31428
+ value = range(token.start, 0);
31429
+ it.next();
31430
+ break;
31431
+ }
31432
+ }
31433
+
31434
+ token = it.current();
31435
+ if (!value && token) {
31436
+ if (token.type == 'line') {
31437
+ lastNewline = token;
31438
+ }
31439
+ // consume value
31440
+ value = range(token.start, token.value);
31441
+ var lastNewline;
31442
+ while ((token = it.next())) {
31443
+ value.end = token.end;
31444
+ if (token.type == 'line') {
31445
+ lastNewline = token;
31446
+ } else if (token.type == '}' || token.type == ';') {
31447
+ value.end = token.start;
31448
+ if (token.type == ';') {
31449
+ end = range(token.start, token.value);
31450
+ }
31451
+ it.next();
31452
+ break;
31453
+ } else if (token.type == ':' && lastNewline) {
31454
+ // A special case:
31455
+ // user is writing a value before existing
31456
+ // property, but didn’t inserted closing semi-colon.
31457
+ // In this case, limit value range to previous
31458
+ // newline
31459
+ value.end = lastNewline.start;
31460
+ it._i = it.tokens.indexOf(lastNewline);
31461
+ break;
31462
+ }
31463
+ }
31464
+ }
31465
+
31466
+ if (!value) {
31467
+ value = range(name.end, 0);
31468
+ }
31469
+
31470
+ return {
31471
+ name: trimWhitespaceInRange(name, text),
31472
+ value: trimWhitespaceInRange(value, text, WHITESPACE_REMOVE_FROM_START | (end ? WHITESPACE_REMOVE_FROM_END : 0)),
31473
+ end: end || range(value.end, 0)
31474
+ };
31475
+ }
31476
+
31477
+ /**
31478
+ * Finds parts of complex CSS value
31479
+ * @param {String} str
31480
+ * @returns {Array} Returns list of <code>Range</code>'s
31481
+ */
31482
+ function findParts(str) {
31483
+ /** @type StringStream */
31484
+ var stream = stringStream.create(str);
31485
+ var ch;
31486
+ var result = [];
31487
+ var sep = /[\s\u00a0,;]/;
31488
+
31489
+ var add = function() {
31490
+ stream.next();
31491
+ result.push(range(stream.start, stream.current()));
31492
+ stream.start = stream.pos;
31493
+ };
31494
+
31495
+ // skip whitespace
31496
+ stream.eatSpace();
31497
+ stream.start = stream.pos;
31498
+
31499
+ while ((ch = stream.next())) {
31500
+ if (ch == '"' || ch == "'") {
31501
+ stream.next();
31502
+ if (!stream.skipTo(ch)) break;
31503
+ add();
31504
+ } else if (ch == '(') {
31505
+ // function found, may have nested function
31506
+ stream.backUp(1);
31507
+ if (!stream.skipToPair('(', ')')) break;
31508
+ stream.backUp(1);
31509
+ add();
31510
+ } else {
31511
+ if (sep.test(ch)) {
31512
+ result.push(range(stream.start, stream.current().length - 1));
31513
+ stream.eatWhile(sep);
31514
+ stream.start = stream.pos;
31515
+ }
31516
+ }
31517
+ }
31518
+
31519
+ add();
31520
+
31521
+ return utils.unique(result.filter(function(item) {
31522
+ return !!item.length();
31523
+ }));
31524
+ }
31525
+
31526
+ /**
31527
+ * Parses CSS properties from given CSS source
31528
+ * and adds them to CSSEditContainer node
31529
+ * @param {CSSEditContainer} node
31530
+ * @param {String} source CSS source
31531
+ * @param {Number} offset Offset of properties subset from original source
31532
+ */
31533
+ function consumeProperties(node, source, offset) {
31534
+ var list = extractPropertiesFromSource(source, offset);
31535
+
31536
+ list.forEach(function(property) {
31537
+ node._children.push(new CSSEditElement(node,
31538
+ editTree.createToken(property.name.start, property.nameText),
31539
+ editTree.createToken(property.value.start, property.valueText),
31540
+ editTree.createToken(property.end.start, property.endText)
31541
+ ));
31542
+ });
31543
+ }
31544
+
31545
+ /**
31546
+ * Parses given CSS source and returns list of ranges of located CSS properties.
31547
+ * Normally, CSS source must contain properties only, it must be,
31548
+ * for example, a content of CSS selector or text between nested
31549
+ * CSS sections
31550
+ * @param {String} source CSS source
31551
+ * @param {Number} offset Offset of properties subset from original source.
31552
+ * Used to provide proper ranges of locates items
31553
+ */
31554
+ function extractPropertiesFromSource(source, offset) {
31555
+ offset = offset || 0;
31556
+ source = source.replace(reSpaceEnd, '');
31557
+ var out = [];
31558
+
31559
+ if (!source) {
31560
+ return out;
31561
+ }
31562
+
31563
+ var tokens = cssParser.parse(source);
31564
+ var it = tokenIterator.create(tokens);
31565
+ var property;
31566
+
31567
+ while ((property = consumeSingleProperty(it, source))) {
31568
+ out.push({
31569
+ nameText: property.name.substring(source),
31570
+ name: property.name.shift(offset),
31571
+
31572
+ valueText: property.value.substring(source),
31573
+ value: property.value.shift(offset),
31574
+
31575
+ endText: property.end.substring(source),
31576
+ end: property.end.shift(offset)
31577
+ });
31578
+ }
31579
+
31580
+ return out;
31581
+ }
31582
+
31583
+ /**
31584
+ * @class
31585
+ * @extends EditContainer
31586
+ */
31587
+ var CSSEditContainer = editTree.EditContainer.extend({
31588
+ initialize: function(source, options) {
31589
+ utils.extend(this.options, defaultOptions, options);
31590
+
31591
+ if (Array.isArray(source)) {
31592
+ source = cssParser.toSource(source);
31593
+ }
31594
+
31595
+ var allRules = cssSections.findAllRules(source);
31596
+ var currentRule = allRules.shift();
31597
+
31598
+ // keep top-level rules only since they will
31599
+ // be parsed by nested CSSEditContainer call
31600
+ var topLevelRules = [];
31601
+ allRules.forEach(function(r) {
31602
+ var isTopLevel = !utils.find(topLevelRules, function(tr) {
31603
+ return tr.contains(r);
31604
+ });
31605
+
31606
+ if (isTopLevel) {
31607
+ topLevelRules.push(r);
31608
+ }
31609
+ });
31610
+
31611
+
31612
+ var selectorRange = range.create2(currentRule.start, currentRule._selectorEnd);
31613
+ this._name = selectorRange.substring(source);
31614
+ this._positions.name = selectorRange.start;
31615
+ this._positions.contentStart = currentRule._contentStart + 1;
31616
+
31617
+ var sectionOffset = currentRule._contentStart + 1;
31618
+ var sectionEnd = currentRule.end - 1;
31619
+
31620
+ // parse properties between nested rules
31621
+ // and add nested rules as children
31622
+ var that = this;
31623
+ topLevelRules.forEach(function(r) {
31624
+ consumeProperties(that, source.substring(sectionOffset, r.start), sectionOffset);
31625
+ var opt = utils.extend({}, that.options, {offset: r.start + that.options.offset});
31626
+ // XXX I think I don’t need nested containers here
31627
+ // They should be handled separately
31628
+ // that._children.push(new CSSEditContainer(r.substring(source), opt));
31629
+ sectionOffset = r.end;
31630
+ });
31631
+
31632
+ // consume the rest of data
31633
+ consumeProperties(this, source.substring(sectionOffset, currentRule.end - 1), sectionOffset);
31634
+ this._saveStyle();
31635
+ },
31636
+
31637
+ /**
31638
+ * Remembers all styles of properties
31639
+ * @private
31640
+ */
31641
+ _saveStyle: function() {
31642
+ var start = this._positions.contentStart;
31643
+ var source = this.source;
31644
+
31645
+ this.list().forEach(function(p) {
31646
+ if (p.type === 'container') {
31647
+ return;
31648
+ }
31649
+
31650
+ p.styleBefore = source.substring(start, p.namePosition());
31651
+ // a small hack here:
31652
+ // Sometimes users add empty lines before properties to logically
31653
+ // separate groups of properties. In this case, a blind copy of
31654
+ // characters between rules may lead to undesired behavior,
31655
+ // especially when current rule is duplicated or used as a donor
31656
+ // to create new rule.
31657
+ // To solve this issue, we‘ll take only last newline indentation
31658
+ var lines = utils.splitByLines(p.styleBefore);
31659
+ if (lines.length > 1) {
31660
+ p.styleBefore = '\n' + lines[lines.length - 1];
31661
+ }
31662
+
31663
+ p.styleSeparator = source.substring(p.nameRange().end, p.valuePosition());
31664
+
31665
+ // graceful and naive comments removal
31666
+ var parts = p.styleBefore.split('*/');
31667
+ p.styleBefore = parts[parts.length - 1];
31668
+ p.styleSeparator = p.styleSeparator.replace(/\/\*.*?\*\//g, '');
31669
+
31670
+ start = p.range().end;
31671
+ });
31672
+ },
31673
+
31674
+ /**
31675
+ * Returns position of element name token
31676
+ * @param {Boolean} isAbsolute Return absolute position
31677
+ * @returns {Number}
31678
+ */
31679
+ namePosition: function(isAbsolute) {
31680
+ return this._pos(this._positions.name, isAbsolute);
31681
+ },
31682
+
31683
+ /**
31684
+ * Returns position of element value token
31685
+ * @param {Boolean} isAbsolute Return absolute position
31686
+ * @returns {Number}
31687
+ */
31688
+ valuePosition: function(isAbsolute) {
31689
+ return this._pos(this._positions.contentStart, isAbsolute);
31690
+ },
31691
+
31692
+ /**
31693
+ * Returns element value range
31694
+ * @param {Boolean} isAbsolute Return absolute range
31695
+ * @returns {Range}
31696
+ */
31697
+ valueRange: function(isAbsolute) {
31698
+ return range.create2(this.valuePosition(isAbsolute), this._pos(this.valueOf().length, isAbsolute) - 1);
31699
+ },
31700
+
31701
+ /**
31702
+ * Adds new CSS property
31703
+ * @param {String} name Property name
31704
+ * @param {String} value Property value
31705
+ * @param {Number} pos Position at which to insert new property. By
31706
+ * default the property is inserted at the end of rule
31707
+ * @returns {CSSEditProperty}
31708
+ */
31709
+ add: function(name, value, pos) {
31710
+ var list = this.list();
31711
+ var start = this._positions.contentStart;
31712
+ var styles = utils.pick(this.options, 'styleBefore', 'styleSeparator');
31713
+
31714
+ if (typeof pos === 'undefined') {
31715
+ pos = list.length;
31716
+ }
31717
+
31718
+ /** @type CSSEditProperty */
31719
+ var donor = list[pos];
31720
+ if (donor) {
31721
+ start = donor.fullRange().start;
31722
+ } else if ((donor = list[pos - 1])) {
31723
+ // make sure that donor has terminating semicolon
31724
+ donor.end(';');
31725
+ start = donor.range().end;
31726
+ }
31727
+
31728
+ if (donor) {
31729
+ styles = utils.pick(donor, 'styleBefore', 'styleSeparator');
31730
+ }
31731
+
31732
+ var nameToken = editTree.createToken(start + styles.styleBefore.length, name);
31733
+ var valueToken = editTree.createToken(nameToken.end + styles.styleSeparator.length, value);
31734
+
31735
+ var property = new CSSEditElement(this, nameToken, valueToken,
31736
+ editTree.createToken(valueToken.end, ';'));
31737
+
31738
+ utils.extend(property, styles);
31739
+
31740
+ // write new property into the source
31741
+ this._updateSource(property.styleBefore + property.toString(), start);
31742
+
31743
+ // insert new property
31744
+ this._children.splice(pos, 0, property);
31745
+ return property;
31746
+ }
31747
+ });
31748
+
31749
+ /**
31750
+ * @class
31751
+ * @type CSSEditElement
31752
+ * @constructor
31753
+ */
31754
+ var CSSEditElement = editTree.EditElement.extend({
31755
+ initialize: function(rule, name, value, end) {
31756
+ this.styleBefore = rule.options.styleBefore;
31757
+ this.styleSeparator = rule.options.styleSeparator;
31758
+
31759
+ this._end = end.value;
31760
+ this._positions.end = end.start;
31761
+ },
31762
+
31763
+ /**
31764
+ * Returns ranges of complex value parts
31765
+ * @returns {Array} Returns <code>null</code> if value is not complex
31766
+ */
31767
+ valueParts: function(isAbsolute) {
31768
+ var parts = findParts(this.value());
31769
+ if (isAbsolute) {
31770
+ var offset = this.valuePosition(true);
31771
+ parts.forEach(function(p) {
31772
+ p.shift(offset);
31773
+ });
31774
+ }
31775
+
31776
+ return parts;
31777
+ },
31778
+
31779
+ /**
31780
+ * Sets of gets element value.
31781
+ * When setting value, this implementation will ensure that your have
31782
+ * proper name-value separator
31783
+ * @param {String} val New element value. If not passed, current
31784
+ * value is returned
31785
+ * @returns {String}
31786
+ */
31787
+ value: function(val) {
31788
+ var isUpdating = typeof val !== 'undefined';
31789
+ var allItems = this.parent.list();
31790
+ if (isUpdating && this.isIncomplete()) {
31791
+ var self = this;
31792
+ var donor = utils.find(allItems, function(item) {
31793
+ return item !== self && !item.isIncomplete();
31794
+ });
31795
+
31796
+ this.styleSeparator = donor
31797
+ ? donor.styleSeparator
31798
+ : this.parent.options.styleSeparator;
31799
+ this.parent._updateSource(this.styleSeparator, range(this.valueRange().start, 0));
31800
+ }
31801
+
31802
+ var value = this.constructor.__super__.value.apply(this, arguments);
31803
+ if (isUpdating) {
31804
+ // make sure current property has terminating semi-colon
31805
+ // if it’s not the last one
31806
+ var ix = allItems.indexOf(this);
31807
+ if (ix !== allItems.length - 1 && !this.end()) {
31808
+ this.end(';');
31809
+ }
31810
+ }
31811
+ return value;
31812
+ },
31813
+
31814
+ /**
31815
+ * Test if current element is incomplete, e.g. has no explicit
31816
+ * name-value separator
31817
+ * @return {Boolean} [description]
31818
+ */
31819
+ isIncomplete: function() {
31820
+ return this.nameRange().end === this.valueRange().start;
31821
+ },
31822
+
31823
+ /**
31824
+ * Sets of gets property end value (basically, it's a semicolon)
31825
+ * @param {String} val New end value. If not passed, current
31826
+ * value is returned
31827
+ */
31828
+ end: function(val) {
31829
+ if (typeof val !== 'undefined' && this._end !== val) {
31830
+ this.parent._updateSource(val, this._positions.end, this._positions.end + this._end.length);
31831
+ this._end = val;
31832
+ }
31833
+
31834
+ return this._end;
31835
+ },
31836
+
31837
+ /**
31838
+ * Returns full rule range, with indentation
31839
+ * @param {Boolean} isAbsolute Return absolute range (with respect of
31840
+ * rule offset)
31841
+ * @returns {Range}
31842
+ */
31843
+ fullRange: function(isAbsolute) {
31844
+ var r = this.range(isAbsolute);
31845
+ r.start -= this.styleBefore.length;
31846
+ return r;
31847
+ },
31848
+
31849
+ /**
31850
+ * Returns item string representation
31851
+ * @returns {String}
31852
+ */
31853
+ valueOf: function() {
31854
+ return this.name() + this.styleSeparator + this.value() + this.end();
31855
+ }
31856
+ });
31857
+
31858
+ return {
31859
+ /**
31860
+ * Parses CSS rule into editable tree
31861
+ * @param {String} source
31862
+ * @param {Object} options
31863
+ * @memberOf emmet.cssEditTree
31864
+ * @returns {EditContainer}
31865
+ */
31866
+ parse: function(source, options) {
31867
+ return new CSSEditContainer(source, options);
31868
+ },
31869
+
31870
+ /**
31871
+ * Extract and parse CSS rule from specified position in <code>content</code>
31872
+ * @param {String} content CSS source code
31873
+ * @param {Number} pos Character position where to start source code extraction
31874
+ * @returns {EditContainer}
31875
+ */
31876
+ parseFromPosition: function(content, pos, isBackward) {
31877
+ var bounds = cssSections.locateRule(content, pos, isBackward);
31878
+ if (!bounds || !bounds.inside(pos)) {
31879
+ // no matching CSS rule or caret outside rule bounds
31880
+ return null;
31881
+ }
31882
+
31883
+ return this.parse(bounds.substring(content), {
31884
+ offset: bounds.start
31885
+ });
31886
+ },
31887
+
31888
+ /**
31889
+ * Locates CSS property in given CSS code fragment under specified character position
31890
+ * @param {String} css CSS code or parsed CSSEditContainer
31891
+ * @param {Number} pos Character position where to search CSS property
31892
+ * @return {CSSEditElement}
31893
+ */
31894
+ propertyFromPosition: function(css, pos) {
31895
+ var cssProp = null;
31896
+ /** @type EditContainer */
31897
+ var cssRule = typeof css === 'string' ? this.parseFromPosition(css, pos, true) : css;
31898
+ if (cssRule) {
31899
+ cssProp = cssRule.itemFromPosition(pos, true);
31900
+ if (!cssProp) {
31901
+ // in case user just started writing CSS property
31902
+ // and didn't include semicolon–try another approach
31903
+ cssProp = utils.find(cssRule.list(), function(elem) {
31904
+ return elem.range(true).end == pos;
31905
+ });
31906
+ }
31907
+ }
31908
+
31909
+ return cssProp;
31910
+ },
31911
+
31912
+ /**
31913
+ * Removes vendor prefix from CSS property
31914
+ * @param {String} name CSS property
31915
+ * @return {String}
31916
+ */
31917
+ baseName: function(name) {
31918
+ return name.replace(/^\s*\-\w+\-/, '');
31919
+ },
31920
+
31921
+ /**
31922
+ * Finds parts of complex CSS value
31923
+ * @param {String} str
31924
+ * @returns {Array}
31925
+ */
31926
+ findParts: findParts,
31927
+
31928
+ extractPropertiesFromSource: extractPropertiesFromSource
31929
+ };
31930
+ });
31931
+ },{"../assets/range":30,"../assets/stringStream":32,"../assets/tokenIterator":34,"../parser/css":56,"../utils/common":73,"../utils/cssSections":74,"./base":36}],38:[function(require,module,exports){
31932
+ /**
31933
+ * XML EditTree is a module that can parse an XML/HTML element into a tree with
31934
+ * convenient methods for adding, modifying and removing attributes. These
31935
+ * changes can be written back to string with respect of code formatting.
31936
+ */
31937
+ if (typeof module === 'object' && typeof define !== 'function') {
31938
+ var define = function (factory) {
31939
+ module.exports = factory(require, exports, module);
31940
+ };
31941
+ }
31942
+
31943
+ define(function(require, exports, module) {
31944
+ var editTree = require('./base');
31945
+ var xmlParser = require('../parser/xml');
31946
+ var range = require('../assets/range');
31947
+ var utils = require('../utils/common');
31948
+
31949
+ var defaultOptions = {
31950
+ styleBefore: ' ',
31951
+ styleSeparator: '=',
31952
+ styleQuote: '"',
31953
+ offset: 0
31954
+ };
31955
+
31956
+ var startTag = /^<([\w\:\-]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/m;
31957
+
31958
+ var XMLEditContainer = editTree.EditContainer.extend({
31959
+ initialize: function(source, options) {
31960
+ utils.defaults(this.options, defaultOptions);
31961
+ this._positions.name = 1;
31962
+
31963
+ var attrToken = null;
31964
+ var tokens = xmlParser.parse(source);
31965
+
31966
+ tokens.forEach(function(token) {
31967
+ token.value = range.create(token).substring(source);
31968
+ switch (token.type) {
31969
+ case 'tag':
31970
+ if (/^<[^\/]+/.test(token.value)) {
31971
+ this._name = token.value.substring(1);
31972
+ }
31973
+ break;
31974
+
31975
+ case 'attribute':
31976
+ // add empty attribute
31977
+ if (attrToken) {
31978
+ this._children.push(new XMLEditElement(this, attrToken));
31979
+ }
31980
+
31981
+ attrToken = token;
31982
+ break;
31983
+
31984
+ case 'string':
31985
+ this._children.push(new XMLEditElement(this, attrToken, token));
31986
+ attrToken = null;
31987
+ break;
31988
+ }
31989
+ }, this);
31990
+
31991
+ if (attrToken) {
31992
+ this._children.push(new XMLEditElement(this, attrToken));
31993
+ }
31994
+
31995
+ this._saveStyle();
31996
+ },
31997
+
31998
+ /**
31999
+ * Remembers all styles of properties
32000
+ * @private
32001
+ */
32002
+ _saveStyle: function() {
32003
+ var start = this.nameRange().end;
32004
+ var source = this.source;
32005
+
32006
+ this.list().forEach(function(p) {
32007
+ p.styleBefore = source.substring(start, p.namePosition());
32008
+
32009
+ if (p.valuePosition() !== -1) {
32010
+ p.styleSeparator = source.substring(p.namePosition() + p.name().length, p.valuePosition() - p.styleQuote.length);
32011
+ }
32012
+
32013
+ start = p.range().end;
32014
+ });
32015
+ },
32016
+
32017
+ /**
32018
+ * Adds new attribute
32019
+ * @param {String} name Property name
32020
+ * @param {String} value Property value
32021
+ * @param {Number} pos Position at which to insert new property. By
32022
+ * default the property is inserted at the end of rule
32023
+ */
32024
+ add: function(name, value, pos) {
32025
+ var list = this.list();
32026
+ var start = this.nameRange().end;
32027
+ var styles = utils.pick(this.options, 'styleBefore', 'styleSeparator', 'styleQuote');
32028
+
32029
+ if (typeof pos === 'undefined') {
32030
+ pos = list.length;
32031
+ }
32032
+
32033
+
32034
+ /** @type XMLEditAttribute */
32035
+ var donor = list[pos];
32036
+ if (donor) {
32037
+ start = donor.fullRange().start;
32038
+ } else if ((donor = list[pos - 1])) {
32039
+ start = donor.range().end;
32040
+ }
32041
+
32042
+ if (donor) {
32043
+ styles = utils.pick(donor, 'styleBefore', 'styleSeparator', 'styleQuote');
32044
+ }
32045
+
32046
+ value = styles.styleQuote + value + styles.styleQuote;
32047
+
32048
+ var attribute = new XMLEditElement(this,
32049
+ editTree.createToken(start + styles.styleBefore.length, name),
32050
+ editTree.createToken(start + styles.styleBefore.length + name.length
32051
+ + styles.styleSeparator.length, value)
32052
+ );
32053
+
32054
+ utils.extend(attribute, styles);
32055
+
32056
+ // write new attribute into the source
32057
+ this._updateSource(attribute.styleBefore + attribute.toString(), start);
32058
+
32059
+ // insert new attribute
32060
+ this._children.splice(pos, 0, attribute);
32061
+ return attribute;
32062
+ },
32063
+
32064
+ /**
32065
+ * A special case of attribute editing: adds class value to existing
32066
+ * `class` attribute
32067
+ * @param {String} value
32068
+ */
32069
+ addClass: function(value) {
32070
+ var attr = this.get('class');
32071
+ value = utils.trim(value);
32072
+ if (!attr) {
32073
+ return this.add('class', value);
32074
+ }
32075
+
32076
+ var classVal = attr.value();
32077
+ var classList = ' ' + classVal.replace(/\n/g, ' ') + ' ';
32078
+ if (!~classList.indexOf(' ' + value + ' ')) {
32079
+ attr.value(classVal + ' ' + value);
32080
+ }
32081
+ },
32082
+
32083
+ /**
32084
+ * A special case of attribute editing: removes class value from existing
32085
+ * `class` attribute
32086
+ * @param {String} value
32087
+ */
32088
+ removeClass: function(value) {
32089
+ var attr = this.get('class');
32090
+ value = utils.trim(value);
32091
+ if (!attr) {
32092
+ return;
32093
+ }
32094
+
32095
+ var reClass = new RegExp('(^|\\s+)' + utils.escapeForRegexp(value));
32096
+ var classVal = attr.value().replace(reClass, '');
32097
+ if (!utils.trim(classVal)) {
32098
+ this.remove('class');
32099
+ } else {
32100
+ attr.value(classVal);
32101
+ }
32102
+ }
32103
+ });
32104
+
32105
+ var XMLEditElement = editTree.EditElement.extend({
32106
+ initialize: function(parent, nameToken, valueToken) {
32107
+ this.styleBefore = parent.options.styleBefore;
32108
+ this.styleSeparator = parent.options.styleSeparator;
32109
+
32110
+ var value = '', quote = parent.options.styleQuote;
32111
+ if (valueToken) {
32112
+ value = valueToken.value;
32113
+ quote = value.charAt(0);
32114
+ if (quote == '"' || quote == "'") {
32115
+ value = value.substring(1);
32116
+ } else {
32117
+ quote = '';
32118
+ }
32119
+
32120
+ if (quote && value.charAt(value.length - 1) == quote) {
32121
+ value = value.substring(0, value.length - 1);
32122
+ }
32123
+ }
32124
+
32125
+ this.styleQuote = quote;
32126
+
32127
+ this._value = value;
32128
+ this._positions.value = valueToken ? valueToken.start + quote.length : -1;
32129
+ },
32130
+
32131
+ /**
32132
+ * Returns full rule range, with indentation
32133
+ * @param {Boolean} isAbsolute Return absolute range (with respect of
32134
+ * rule offset)
32135
+ * @returns {Range}
32136
+ */
32137
+ fullRange: function(isAbsolute) {
32138
+ var r = this.range(isAbsolute);
32139
+ r.start -= this.styleBefore.length;
32140
+ return r;
32141
+ },
32142
+
32143
+ valueOf: function() {
32144
+ return this.name() + this.styleSeparator
32145
+ + this.styleQuote + this.value() + this.styleQuote;
32146
+ }
32147
+ });
32148
+
32149
+ return {
32150
+ /**
32151
+ * Parses HTML element into editable tree
32152
+ * @param {String} source
32153
+ * @param {Object} options
32154
+ * @memberOf emmet.htmlEditTree
32155
+ * @returns {EditContainer}
32156
+ */
32157
+ parse: function(source, options) {
32158
+ return new XMLEditContainer(source, options);
32159
+ },
32160
+
32161
+ /**
32162
+ * Extract and parse HTML from specified position in <code>content</code>
32163
+ * @param {String} content CSS source code
32164
+ * @param {Number} pos Character position where to start source code extraction
32165
+ * @returns {XMLEditElement}
32166
+ */
32167
+ parseFromPosition: function(content, pos, isBackward) {
32168
+ var bounds = this.extractTag(content, pos, isBackward);
32169
+ if (!bounds || !bounds.inside(pos))
32170
+ // no matching HTML tag or caret outside tag bounds
32171
+ return null;
32172
+
32173
+ return this.parse(bounds.substring(content), {
32174
+ offset: bounds.start
32175
+ });
32176
+ },
32177
+
32178
+ /**
32179
+ * Extracts nearest HTML tag range from <code>content</code>, starting at
32180
+ * <code>pos</code> position
32181
+ * @param {String} content
32182
+ * @param {Number} pos
32183
+ * @param {Boolean} isBackward
32184
+ * @returns {Range}
32185
+ */
32186
+ extractTag: function(content, pos, isBackward) {
32187
+ var len = content.length, i;
32188
+
32189
+ // max extraction length. I don't think there may be tags larger
32190
+ // than 2000 characters length
32191
+ var maxLen = Math.min(2000, len);
32192
+
32193
+ /** @type Range */
32194
+ var r = null;
32195
+
32196
+ var match = function(pos) {
32197
+ var m;
32198
+ if (content.charAt(pos) == '<' && (m = content.substr(pos, maxLen).match(startTag)))
32199
+ return range.create(pos, m[0]);
32200
+ };
32201
+
32202
+ // lookup backward, in case we are inside tag already
32203
+ for (i = pos; i >= 0; i--) {
32204
+ if ((r = match(i))) break;
32205
+ }
32206
+
32207
+ if (r && (r.inside(pos) || isBackward))
32208
+ return r;
32209
+
32210
+ if (!r && isBackward)
32211
+ return null;
32212
+
32213
+ // search forward
32214
+ for (i = pos; i < len; i++) {
32215
+ if ((r = match(i)))
32216
+ return r;
32217
+ }
32218
+ }
32219
+ };
32220
+ });
32221
+ },{"../assets/range":30,"../parser/xml":62,"../utils/common":73,"./base":36}],39:[function(require,module,exports){
32222
+ if (typeof module === 'object' && typeof define !== 'function') {
32223
+ var define = function (factory) {
32224
+ module.exports = factory(require, exports, module);
32225
+ };
32226
+ }
32227
+
32228
+ define(function(require, exports, module) {
32229
+ var global = typeof self != 'undefined' ? self : this;
32230
+
32231
+ var utils = require('./utils/common');
32232
+ var actions = require('./action/main');
32233
+ var parser = require('./parser/abbreviation');
32234
+ var file = require('./plugin/file');
32235
+
32236
+ var preferences = require('./assets/preferences');
32237
+ var resources = require('./assets/resources');
32238
+ var profile = require('./assets/profile');
32239
+ var ciu = require('./assets/caniuse');
32240
+ var logger = require('./assets/logger');
32241
+
32242
+ var sliceFn = Array.prototype.slice;
32243
+
32244
+ /**
32245
+ * Returns file name part from path
32246
+ * @param {String} path Path to file
32247
+ * @return {String}
32248
+ */
32249
+ function getFileName(path) {
32250
+ var re = /([\w\.\-]+)$/i;
32251
+ var m = re.exec(path);
32252
+ return m ? m[1] : '';
32253
+ }
32254
+
32255
+ /**
32256
+ * Normalizes profile definition: converts some
32257
+ * properties to valid data types
32258
+ * @param {Object} profile
32259
+ * @return {Object}
32260
+ */
32261
+ function normalizeProfile(profile) {
32262
+ if (typeof profile === 'object') {
32263
+ if ('indent' in profile) {
32264
+ profile.indent = !!profile.indent;
32265
+ }
32266
+
32267
+ if ('self_closing_tag' in profile) {
32268
+ if (typeof profile.self_closing_tag === 'number') {
32269
+ profile.self_closing_tag = !!profile.self_closing_tag;
32270
+ }
32271
+ }
32272
+ }
32273
+
32274
+ return profile;
32275
+ }
32276
+
32277
+ return {
32278
+ /**
32279
+ * The essential function that expands Emmet abbreviation
32280
+ * @param {String} abbr Abbreviation to parse
32281
+ * @param {String} syntax Abbreviation's context syntax
32282
+ * @param {String} profile Output profile (or its name)
32283
+ * @param {Object} contextNode Contextual node where abbreviation is
32284
+ * written
32285
+ * @return {String}
32286
+ */
32287
+ expandAbbreviation: function(abbr, syntax, profile, contextNode) {
32288
+ return parser.expand(abbr, {
32289
+ syntax: syntax,
32290
+ profile: profile,
32291
+ contextNode: contextNode
32292
+ });
32293
+ },
32294
+
32295
+ /**
32296
+ * Runs given action
32297
+ * @param {String} name Action name
32298
+ * @param {IEmmetEditor} editor Editor instance
32299
+ * @return {Boolean} Returns true if action was performed successfully
32300
+ */
32301
+ run: function(name) {
32302
+ return actions.run.apply(actions, sliceFn.call(arguments, 0));
32303
+ },
32304
+
32305
+ /**
32306
+ * Loads Emmet extensions. Extensions are simple .js files that
32307
+ * uses Emmet modules and resources to create new actions, modify
32308
+ * existing ones etc.
32309
+ * @param {Array} fileList List of absolute paths to files in extensions
32310
+ * folder. Back-end app should not filter this list (e.g. by extension)
32311
+ * but return it "as-is" so bootstrap can decide how to load contents
32312
+ * of each file.
32313
+ * This method requires a <code>file</code> module of <code>IEmmetFile</code>
32314
+ * interface to be implemented.
32315
+ * @memberOf bootstrap
32316
+ */
32317
+ loadExtensions: function(fileList) {
32318
+ var payload = {};
32319
+ var userSnippets = null;
32320
+ var that = this;
32321
+
32322
+ // make sure file list contians only valid extension files
32323
+ fileList = fileList.filter(function(f) {
32324
+ var ext = file.getExt(f);
32325
+ return ext === 'json' || ext === 'js';
32326
+ });
32327
+
32328
+ var reader = (file.readText || file.read).bind(file);
32329
+ var next = function() {
32330
+ if (fileList.length) {
32331
+ var f = fileList.shift();
32332
+ reader(f, function(err, content) {
32333
+ if (err) {
32334
+ logger.log('Unable to read "' + f + '" file: '+ err);
32335
+ return next();
32336
+ }
32337
+
32338
+ switch (file.getExt(f)) {
32339
+ case 'js':
32340
+ try {
32341
+ eval(content);
32342
+ } catch (e) {
32343
+ logger.log('Unable to eval "' + f + '" file: '+ e);
32344
+ }
32345
+ break;
32346
+ case 'json':
32347
+ var fileName = getFileName(f).toLowerCase().replace(/\.json$/, '');
32348
+ if (/^snippets/.test(fileName)) {
32349
+ if (fileName === 'snippets') {
32350
+ // data in snippets.json is more important to user
32351
+ userSnippets = utils.parseJSON(content);
32352
+ } else {
32353
+ payload.snippets = utils.deepMerge(payload.snippets || {}, utils.parseJSON(content));
32354
+ }
32355
+ } else {
32356
+ payload[fileName] = content;
32357
+ }
32358
+
32359
+ break;
32360
+ }
32361
+
32362
+ next();
32363
+ });
32364
+ } else {
32365
+ // complete
32366
+ if (userSnippets) {
32367
+ payload.snippets = utils.deepMerge(payload.snippets || {}, userSnippets);
32368
+ }
32369
+
32370
+ that.loadUserData(payload);
32371
+ }
32372
+ };
32373
+
32374
+ next();
32375
+ },
32376
+
32377
+ /**
32378
+ * Loads preferences from JSON object (or string representation of JSON)
32379
+ * @param {Object} data
32380
+ * @returns
32381
+ */
32382
+ loadPreferences: function(data) {
32383
+ preferences.load(utils.parseJSON(data));
32384
+ },
32385
+
32386
+ /**
32387
+ * Loads user snippets and abbreviations. It doesn’t replace current
32388
+ * user resource vocabulary but merges it with passed one. If you need
32389
+ * to <i>replaces</i> user snippets you should call
32390
+ * <code>resetSnippets()</code> method first
32391
+ */
32392
+ loadSnippets: function(data) {
32393
+ data = utils.parseJSON(data);
32394
+
32395
+ var userData = resources.getVocabulary('user') || {};
32396
+ resources.setVocabulary(utils.deepMerge(userData, data), 'user');
32397
+ },
32398
+
32399
+ /**
32400
+ * Helper function that loads default snippets, defined in project’s
32401
+ * <i>snippets.json</i>
32402
+ * @param {Object} data
32403
+ */
32404
+ loadSystemSnippets: function(data) {
32405
+ resources.setVocabulary(utils.parseJSON(data), 'system');
32406
+ },
32407
+
32408
+ /**
32409
+ * Helper function that loads Can I Use database
32410
+ * @param {Object} data
32411
+ */
32412
+ loadCIU: function(data) {
32413
+ ciu.load(utils.parseJSON(data));
32414
+ },
32415
+
32416
+ /**
32417
+ * Removes all user-defined snippets
32418
+ */
32419
+ resetSnippets: function() {
32420
+ resources.setVocabulary({}, 'user');
32421
+ },
32422
+
32423
+ /**
32424
+ * Helper function that loads all user data (snippets and preferences)
32425
+ * defined as a single JSON object. This is useful for loading data
32426
+ * stored in a common storage, for example <code>NSUserDefaults</code>
32427
+ * @param {Object} data
32428
+ */
32429
+ loadUserData: function(data) {
32430
+ data = utils.parseJSON(data);
32431
+ if (data.snippets) {
32432
+ this.loadSnippets(data.snippets);
32433
+ }
32434
+
32435
+ if (data.preferences) {
32436
+ this.loadPreferences(data.preferences);
32437
+ }
32438
+
32439
+ if (data.profiles) {
32440
+ this.loadProfiles(data.profiles);
32441
+ }
32442
+
32443
+ if (data.caniuse) {
32444
+ this.loadCIU(data.caniuse);
32445
+ }
32446
+
32447
+ var profiles = data.syntaxProfiles || data.syntaxprofiles;
32448
+ if (profiles) {
32449
+ this.loadSyntaxProfiles(profiles);
32450
+ }
32451
+ },
32452
+
32453
+ /**
32454
+ * Resets all user-defined data: preferences, snippets etc.
32455
+ * @returns
32456
+ */
32457
+ resetUserData: function() {
32458
+ this.resetSnippets();
32459
+ preferences.reset();
32460
+ profile.reset();
32461
+ },
32462
+
32463
+ /**
32464
+ * Load syntax-specific output profiles. These are essentially
32465
+ * an extension to syntax snippets
32466
+ * @param {Object} profiles Dictionary of profiles
32467
+ */
32468
+ loadSyntaxProfiles: function(profiles) {
32469
+ profiles = utils.parseJSON(profiles);
32470
+ var snippets = {};
32471
+ Object.keys(profiles).forEach(function(syntax) {
32472
+ var options = profiles[syntax];
32473
+ if (!(syntax in snippets)) {
32474
+ snippets[syntax] = {};
32475
+ }
32476
+ snippets[syntax].profile = normalizeProfile(options);
32477
+ });
32478
+
32479
+ this.loadSnippets(snippets);
32480
+ },
32481
+
32482
+ /**
32483
+ * Load named profiles
32484
+ * @param {Object} profiles
32485
+ */
32486
+ loadProfiles: function(profiles) {
32487
+ profiles = utils.parseJSON(profiles);
32488
+ Object.keys(profiles).forEach(function(name) {
32489
+ profile.create(name, normalizeProfile(profiles[name]));
32490
+ });
32491
+ },
32492
+ require: require,
32493
+
32494
+ // expose some useful data for plugin authors
32495
+ actions: actions,
32496
+ file: file,
32497
+ preferences: preferences,
32498
+ resources: resources,
32499
+ profile: profile,
32500
+ tabStops: require('./assets/tabStops'),
32501
+ htmlMatcher: require('./assets/htmlMatcher'),
32502
+ utils: {
32503
+ common: utils,
32504
+ action: require('./utils/action'),
32505
+ editor: require('./utils/editor')
32506
+ }
32507
+ };
32508
+ });
32509
+ },{"./action/main":12,"./assets/caniuse":23,"./assets/htmlMatcher":26,"./assets/logger":27,"./assets/preferences":28,"./assets/profile":29,"./assets/resources":31,"./assets/tabStops":33,"./parser/abbreviation":55,"./plugin/file":63,"./utils/action":70,"./utils/common":73,"./utils/editor":75}],40:[function(require,module,exports){
32510
+ /**
32511
+ * Filter for aiding of writing elements with complex class names as described
32512
+ * in Yandex's BEM (Block, Element, Modifier) methodology. This filter will
32513
+ * automatically inherit block and element names from parent elements and insert
32514
+ * them into child element classes
32515
+ */
32516
+ if (typeof module === 'object' && typeof define !== 'function') {
32517
+ var define = function (factory) {
32518
+ module.exports = factory(require, exports, module);
32519
+ };
32520
+ }
32521
+
32522
+ define(function(require, exports, module) {
32523
+ var htmlFilter = require('./html');
32524
+ var prefs = require('../assets/preferences');
32525
+ var abbreviationUtils = require('../utils/abbreviation');
32526
+ var utils = require('../utils/common');
32527
+
32528
+ prefs.define('bem.elementSeparator', '__', 'Class name’s element separator.');
32529
+ prefs.define('bem.modifierSeparator', '_', 'Class name’s modifier separator.');
32530
+ prefs.define('bem.shortElementPrefix', '-',
32531
+ 'Symbol for describing short “block-element” notation. Class names '
32532
+ + 'prefixed with this symbol will be treated as element name for parent‘s '
32533
+ + 'block name. Each symbol instance traverses one level up in parsed '
32534
+ + 'tree for block name lookup. Empty value will disable short notation.');
32535
+
32536
+ var shouldRunHtmlFilter = false;
32537
+
32538
+ function getSeparators() {
32539
+ return {
32540
+ element: prefs.get('bem.elementSeparator'),
32541
+ modifier: prefs.get('bem.modifierSeparator')
32542
+ };
32543
+ }
32544
+
32545
+ /**
32546
+ * @param {AbbreviationNode} item
32547
+ */
32548
+ function bemParse(item) {
32549
+ if (abbreviationUtils.isSnippet(item))
32550
+ return item;
32551
+
32552
+ // save BEM stuff in cache for faster lookups
32553
+ item.__bem = {
32554
+ block: '',
32555
+ element: '',
32556
+ modifier: ''
32557
+ };
32558
+
32559
+ var classNames = normalizeClassName(item.attribute('class')).split(' ');
32560
+
32561
+ // guess best match for block name
32562
+ var reBlockName = /^[a-z]\-/i;
32563
+ item.__bem.block = utils.find(classNames, function(name) {
32564
+ return reBlockName.test(name);
32565
+ });
32566
+
32567
+ // guessing doesn't worked, pick first class name as block name
32568
+ if (!item.__bem.block) {
32569
+ reBlockName = /^[a-z]/i;
32570
+ item.__bem.block = utils.find(classNames, function(name) {
32571
+ return reBlockName.test(name);
32572
+ }) || '';
32573
+ }
32574
+
32575
+ classNames = classNames.map(function(name) {
32576
+ return processClassName(name, item);
32577
+ });
32578
+
32579
+ classNames = utils.unique(utils.flatten(classNames)).join(' ');
32580
+ if (classNames) {
32581
+ item.attribute('class', classNames);
32582
+ }
32583
+
32584
+ return item;
32585
+ }
32586
+
32587
+ /**
32588
+ * @param {String} className
32589
+ * @returns {String}
32590
+ */
32591
+ function normalizeClassName(className) {
32592
+ className = (' ' + (className || '') + ' ').replace(/\s+/g, ' ');
32593
+
32594
+ var shortSymbol = prefs.get('bem.shortElementPrefix');
32595
+ if (shortSymbol) {
32596
+ var re = new RegExp('\\s(' + utils.escapeForRegexp(shortSymbol) + '+)', 'g');
32597
+ className = className.replace(re, function(str, p1) {
32598
+ return ' ' + utils.repeatString(getSeparators().element, p1.length);
32599
+ });
32600
+ }
32601
+
32602
+ return utils.trim(className);
32603
+ }
32604
+
32605
+ /**
32606
+ * Processes class name
32607
+ * @param {String} name Class name item to process
32608
+ * @param {AbbreviationNode} item Host node for provided class name
32609
+ * @returns Processed class name. May return <code>Array</code> of
32610
+ * class names
32611
+ */
32612
+ function processClassName(name, item) {
32613
+ name = transformClassName(name, item, 'element');
32614
+ name = transformClassName(name, item, 'modifier');
32615
+
32616
+ // expand class name
32617
+ // possible values:
32618
+ // * block__element
32619
+ // * block__element_modifier
32620
+ // * block__element_modifier1_modifier2
32621
+ // * block_modifier
32622
+ var block = '', element = '', modifier = '';
32623
+ var separators = getSeparators();
32624
+ if (~name.indexOf(separators.element)) {
32625
+ var elements = name.split(separators.element);
32626
+ block = elements.shift();
32627
+
32628
+ var modifiers = elements.pop().split(separators.modifier);
32629
+ elements.push(modifiers.shift());
32630
+ element = elements.join(separators.element);
32631
+ modifier = modifiers.join(separators.modifier);
32632
+ } else if (~name.indexOf(separators.modifier)) {
32633
+ var blockModifiers = name.split(separators.modifier);
32634
+
32635
+ block = blockModifiers.shift();
32636
+ modifier = blockModifiers.join(separators.modifier);
32637
+ }
32638
+
32639
+ if (block || element || modifier) {
32640
+ if (!block) {
32641
+ block = item.__bem.block;
32642
+ }
32643
+
32644
+ // inherit parent bem element, if exists
32645
+ // if (item.parent && item.parent.__bem && item.parent.__bem.element)
32646
+ // element = item.parent.__bem.element + separators.element + element;
32647
+
32648
+ // produce multiple classes
32649
+ var prefix = block;
32650
+ var result = [];
32651
+
32652
+ if (element) {
32653
+ prefix += separators.element + element;
32654
+ result.push(prefix);
32655
+ } else {
32656
+ result.push(prefix);
32657
+ }
32658
+
32659
+ if (modifier) {
32660
+ result.push(prefix + separators.modifier + modifier);
32661
+ }
32662
+
32663
+ item.__bem.block = block;
32664
+ item.__bem.element = element;
32665
+ item.__bem.modifier = modifier;
32666
+
32667
+ return result;
32668
+ }
32669
+
32670
+ // ...otherwise, return processed or original class name
32671
+ return name;
32672
+ }
32673
+
32674
+ /**
32675
+ * Low-level function to transform user-typed class name into full BEM class
32676
+ * @param {String} name Class name item to process
32677
+ * @param {AbbreviationNode} item Host node for provided class name
32678
+ * @param {String} entityType Type of entity to be tried to transform
32679
+ * ('element' or 'modifier')
32680
+ * @returns {String} Processed class name or original one if it can't be
32681
+ * transformed
32682
+ */
32683
+ function transformClassName(name, item, entityType) {
32684
+ var separators = getSeparators();
32685
+ var reSep = new RegExp('^(' + separators[entityType] + ')+', 'g');
32686
+ if (reSep.test(name)) {
32687
+ var depth = 0; // parent lookup depth
32688
+ var cleanName = name.replace(reSep, function(str) {
32689
+ depth = str.length / separators[entityType].length;
32690
+ return '';
32691
+ });
32692
+
32693
+ // find donor element
32694
+ var donor = item;
32695
+ while (donor.parent && depth--) {
32696
+ donor = donor.parent;
32697
+ }
32698
+
32699
+ if (!donor || !donor.__bem)
32700
+ donor = item;
32701
+
32702
+ if (donor && donor.__bem) {
32703
+ var prefix = donor.__bem.block;
32704
+
32705
+ // decide if we should inherit element name
32706
+ // if (entityType == 'element') {
32707
+ // var curElem = cleanName.split(separators.modifier, 1)[0];
32708
+ // if (donor.__bem.element && donor.__bem.element != curElem)
32709
+ // prefix += separators.element + donor.__bem.element;
32710
+ // }
32711
+
32712
+ if (entityType == 'modifier' && donor.__bem.element)
32713
+ prefix += separators.element + donor.__bem.element;
32714
+
32715
+ return prefix + separators[entityType] + cleanName;
32716
+ }
32717
+ }
32718
+
32719
+ return name;
32720
+ }
32721
+
32722
+ /**
32723
+ * Recursive function for processing tags, which extends class names
32724
+ * according to BEM specs: http://bem.github.com/bem-method/pages/beginning/beginning.ru.html
32725
+ * <br><br>
32726
+ * It does several things:<br>
32727
+ * <ul>
32728
+ * <li>Expands complex class name (according to BEM symbol semantics):
32729
+ * .block__elem_modifier → .block.block__elem.block__elem_modifier
32730
+ * </li>
32731
+ * <li>Inherits block name on child elements:
32732
+ * .b-block > .__el > .__el → .b-block > .b-block__el > .b-block__el__el
32733
+ * </li>
32734
+ * <li>Treats first dash symbol as '__'</li>
32735
+ * <li>Double underscore (or typographic '–') is also treated as an element
32736
+ * level lookup, e.g. ____el will search for element definition in parent’s
32737
+ * parent element:
32738
+ * .b-block > .__el1 > .____el2 → .b-block > .b-block__el1 > .b-block__el2
32739
+ * </li>
32740
+ * </ul>
32741
+ *
32742
+ * @param {AbbreviationNode} tree
32743
+ * @param {Object} profile
32744
+ */
32745
+ function process(tree, profile) {
32746
+ if (tree.name) {
32747
+ bemParse(tree, profile);
32748
+ }
32749
+
32750
+ tree.children.forEach(function(item) {
32751
+ process(item, profile);
32752
+ if (!abbreviationUtils.isSnippet(item) && item.start) {
32753
+ shouldRunHtmlFilter = true;
32754
+ }
32755
+ });
32756
+
32757
+ return tree;
32758
+ }
32759
+
32760
+ return function(tree, profile) {
32761
+ shouldRunHtmlFilter = false;
32762
+ tree = process(tree, profile);
32763
+ // in case 'bem' filter is applied after 'html' filter: run it again
32764
+ // to update output
32765
+ if (shouldRunHtmlFilter) {
32766
+ tree = htmlFilter(tree, profile);
32767
+ }
32768
+
32769
+ return tree;
32770
+ };
32771
+ });
32772
+ },{"../assets/preferences":28,"../utils/abbreviation":69,"../utils/common":73,"./html":46}],41:[function(require,module,exports){
32773
+ /**
32774
+ * Comment important tags (with 'id' and 'class' attributes)
32775
+ */
32776
+ if (typeof module === 'object' && typeof define !== 'function') {
32777
+ var define = function (factory) {
32778
+ module.exports = factory(require, exports, module);
32779
+ };
32780
+ }
32781
+
32782
+ define(function(require, exports, module) {
32783
+ var prefs = require('../assets/preferences');
32784
+ var utils = require('../utils/common');
32785
+ var template = require('../utils/template');
32786
+ var abbrUtils = require('../utils/abbreviation');
32787
+ var filterCore = require('./main');
32788
+
32789
+ prefs.define('filter.commentAfter',
32790
+ '\n<!-- /<%= attr("id", "#") %><%= attr("class", ".") %> -->',
32791
+ 'A definition of comment that should be placed <i>after</i> matched '
32792
+ + 'element when <code>comment</code> filter is applied. This definition '
32793
+ + 'is an ERB-style template passed to <code>_.template()</code> '
32794
+ + 'function (see Underscore.js docs for details). In template context, '
32795
+ + 'the following properties and functions are availabe:\n'
32796
+ + '<ul>'
32797
+
32798
+ + '<li><code>attr(name, before, after)</code> – a function that outputs'
32799
+ + 'specified attribute value concatenated with <code>before</code> '
32800
+ + 'and <code>after</code> strings. If attribute doesn\'t exists, the '
32801
+ + 'empty string will be returned.</li>'
32802
+
32803
+ + '<li><code>node</code> – current node (instance of <code>AbbreviationNode</code>)</li>'
32804
+
32805
+ + '<li><code>name</code> – name of current tag</li>'
32806
+
32807
+ + '<li><code>padding</code> – current string padding, can be used '
32808
+ + 'for formatting</li>'
32809
+
32810
+ +'</ul>');
32811
+
32812
+ prefs.define('filter.commentBefore',
32813
+ '',
32814
+ 'A definition of comment that should be placed <i>before</i> matched '
32815
+ + 'element when <code>comment</code> filter is applied. '
32816
+ + 'For more info, read description of <code>filter.commentAfter</code> '
32817
+ + 'property');
32818
+
32819
+ prefs.define('filter.commentTrigger', 'id, class',
32820
+ 'A comma-separated list of attribute names that should exist in abbreviatoin '
32821
+ + 'where comment should be added. If you wish to add comment for '
32822
+ + 'every element, set this option to <code>*</code>');
32823
+
32824
+ /**
32825
+ * Add comments to tag
32826
+ * @param {AbbreviationNode} node
32827
+ */
32828
+ function addComments(node, templateBefore, templateAfter) {
32829
+ // check if comments should be added
32830
+ var trigger = prefs.get('filter.commentTrigger');
32831
+ if (trigger != '*') {
32832
+ var shouldAdd = utils.find(trigger.split(','), function(name) {
32833
+ return !!node.attribute(utils.trim(name));
32834
+ });
32835
+
32836
+ if (!shouldAdd) {
32837
+ return;
32838
+ }
32839
+ }
32840
+
32841
+ var ctx = {
32842
+ node: node,
32843
+ name: node.name(),
32844
+ padding: node.parent ? node.parent.padding : '',
32845
+ attr: function(name, before, after) {
32846
+ var attr = node.attribute(name);
32847
+ if (attr) {
32848
+ return (before || '') + attr + (after || '');
32849
+ }
32850
+
32851
+ return '';
32852
+ }
32853
+ };
32854
+
32855
+ var nodeBefore = templateBefore ? templateBefore(ctx) : '';
32856
+ var nodeAfter = templateAfter ? templateAfter(ctx) : '';
32857
+
32858
+ node.start = node.start.replace(/</, nodeBefore + '<');
32859
+ node.end = node.end.replace(/>/, '>' + nodeAfter);
32860
+ }
32861
+
32862
+ function process(tree, before, after) {
32863
+ tree.children.forEach(function(item) {
32864
+ if (abbrUtils.isBlock(item)) {
32865
+ addComments(item, before, after);
32866
+ }
32867
+
32868
+ process(item, before, after);
32869
+ });
32870
+
32871
+ return tree;
32872
+ }
32873
+
32874
+ return function(tree) {
32875
+ var templateBefore = template(prefs.get('filter.commentBefore'));
32876
+ var templateAfter = template(prefs.get('filter.commentAfter'));
32877
+
32878
+ return process(tree, templateBefore, templateAfter);
32879
+ };
32880
+ });
32881
+
32882
+ },{"../assets/preferences":28,"../utils/abbreviation":69,"../utils/common":73,"../utils/template":77,"./main":49}],42:[function(require,module,exports){
32883
+ /**
32884
+ * Filter for outputting CSS and alike
32885
+ */
32886
+ if (typeof module === 'object' && typeof define !== 'function') {
32887
+ var define = function (factory) {
32888
+ module.exports = factory(require, exports, module);
32889
+ };
32890
+ }
32891
+
32892
+ define(function(require, exports, module) {
32893
+ /**
32894
+ * Test if passed item is very first child in parsed tree
32895
+ * @param {AbbreviationNode} item
32896
+ */
32897
+ function isVeryFirstChild(item) {
32898
+ return item.parent && !item.parent.parent && !item.index();
32899
+ }
32900
+
32901
+ return function process(tree, profile, level) {
32902
+ level = level || 0;
32903
+
32904
+ tree.children.forEach(function(item) {
32905
+ if (!isVeryFirstChild(item) && profile.tag_nl !== false) {
32906
+ item.start = '\n' + item.start;
32907
+ }
32908
+ process(item, profile, level + 1);
32909
+ });
32910
+
32911
+ return tree;
32912
+ };
32913
+ });
32914
+ },{}],43:[function(require,module,exports){
32915
+ /**
32916
+ * Filter for escaping unsafe XML characters: <, >, &
32917
+ */
32918
+ if (typeof module === 'object' && typeof define !== 'function') {
32919
+ var define = function (factory) {
32920
+ module.exports = factory(require, exports, module);
32921
+ };
32922
+ }
32923
+
32924
+ define(function(require, exports, module) {
32925
+ var charMap = {
32926
+ '<': '&lt;',
32927
+ '>': '&gt;',
32928
+ '&': '&amp;'
32929
+ };
32930
+
32931
+ function escapeChars(str) {
32932
+ return str.replace(/([<>&])/g, function(str, p1){
32933
+ return charMap[p1];
32934
+ });
32935
+ }
32936
+
32937
+ return function process(tree) {
32938
+ tree.children.forEach(function(item) {
32939
+ item.start = escapeChars(item.start);
32940
+ item.end = escapeChars(item.end);
32941
+ item.content = escapeChars(item.content);
32942
+ process(item);
32943
+ });
32944
+
32945
+ return tree;
32946
+ };
32947
+ });
32948
+ },{}],44:[function(require,module,exports){
32949
+ /**
32950
+ * Generic formatting filter: creates proper indentation for each tree node,
32951
+ * placing "%s" placeholder where the actual output should be. You can use
32952
+ * this filter to preformat tree and then replace %s placeholder to whatever you
32953
+ * need. This filter should't be called directly from editor as a part
32954
+ * of abbreviation.
32955
+ */
32956
+ if (typeof module === 'object' && typeof define !== 'function') {
32957
+ var define = function (factory) {
32958
+ module.exports = factory(require, exports, module);
32959
+ };
32960
+ }
32961
+
32962
+ define(function(require, exports, module) {
32963
+ var utils = require('../utils/common');
32964
+ var abbrUtils = require('../utils/abbreviation');
32965
+ var prefs = require('../assets/preferences');
32966
+ var resources = require('../assets/resources');
32967
+
32968
+ prefs.define('format.noIndentTags', 'html',
32969
+ 'A comma-separated list of tag names that should not get inner indentation.');
32970
+
32971
+ prefs.define('format.forceIndentationForTags', 'body',
32972
+ 'A comma-separated list of tag names that should <em>always</em> get inner indentation.');
32973
+
32974
+ var placeholder = '%s';
32975
+
32976
+ /**
32977
+ * Get indentation for given node
32978
+ * @param {AbbreviationNode} node
32979
+ * @returns {String}
32980
+ */
32981
+ function getIndentation(node) {
32982
+ var items = prefs.getArray('format.noIndentTags') || [];
32983
+ if (~items.indexOf(node.name())) {
32984
+ return '';
32985
+ }
32986
+
32987
+ return '\t';
32988
+ }
32989
+
32990
+ /**
32991
+ * Test if passed node has block-level sibling element
32992
+ * @param {AbbreviationNode} item
32993
+ * @return {Boolean}
32994
+ */
32995
+ function hasBlockSibling(item) {
32996
+ return item.parent && abbrUtils.hasBlockChildren(item.parent);
32997
+ }
32998
+
32999
+ /**
33000
+ * Test if passed item is very first child in parsed tree
33001
+ * @param {AbbreviationNode} item
33002
+ */
33003
+ function isVeryFirstChild(item) {
33004
+ return item.parent && !item.parent.parent && !item.index();
33005
+ }
33006
+
33007
+ /**
33008
+ * Check if a newline should be added before element
33009
+ * @param {AbbreviationNode} node
33010
+ * @param {OutputProfile} profile
33011
+ * @return {Boolean}
33012
+ */
33013
+ function shouldAddLineBreak(node, profile) {
33014
+ if (profile.tag_nl === true || abbrUtils.isBlock(node))
33015
+ return true;
33016
+
33017
+ if (!node.parent || !profile.inline_break)
33018
+ return false;
33019
+
33020
+ // check if there are required amount of adjacent inline element
33021
+ return shouldFormatInline(node.parent, profile);
33022
+ }
33023
+
33024
+ /**
33025
+ * Need to add newline because <code>item</code> has too many inline children
33026
+ * @param {AbbreviationNode} node
33027
+ * @param {OutputProfile} profile
33028
+ */
33029
+ function shouldBreakChild(node, profile) {
33030
+ // we need to test only one child element, because
33031
+ // hasBlockChildren() method will do the rest
33032
+ return node.children.length && shouldAddLineBreak(node.children[0], profile);
33033
+ }
33034
+
33035
+ function shouldFormatInline(node, profile) {
33036
+ var nodeCount = 0;
33037
+ return !!utils.find(node.children, function(child) {
33038
+ if (child.isTextNode() || !abbrUtils.isInline(child))
33039
+ nodeCount = 0;
33040
+ else if (abbrUtils.isInline(child))
33041
+ nodeCount++;
33042
+
33043
+ if (nodeCount >= profile.inline_break)
33044
+ return true;
33045
+ });
33046
+ }
33047
+
33048
+ function isRoot(item) {
33049
+ return !item.parent;
33050
+ }
33051
+
33052
+ /**
33053
+ * Processes element with matched resource of type <code>snippet</code>
33054
+ * @param {AbbreviationNode} item
33055
+ * @param {OutputProfile} profile
33056
+ */
33057
+ function processSnippet(item, profile) {
33058
+ item.start = item.end = '';
33059
+ if (!isVeryFirstChild(item) && profile.tag_nl !== false && shouldAddLineBreak(item, profile)) {
33060
+ // check if we’re not inside inline element
33061
+ if (isRoot(item.parent) || !abbrUtils.isInline(item.parent)) {
33062
+ item.start = '\n' + item.start;
33063
+ }
33064
+ }
33065
+
33066
+ return item;
33067
+ }
33068
+
33069
+ /**
33070
+ * Check if we should add line breaks inside inline element
33071
+ * @param {AbbreviationNode} node
33072
+ * @param {OutputProfile} profile
33073
+ * @return {Boolean}
33074
+ */
33075
+ function shouldBreakInsideInline(node, profile) {
33076
+ var hasBlockElems = node.children.some(function(child) {
33077
+ if (abbrUtils.isSnippet(child))
33078
+ return false;
33079
+
33080
+ return !abbrUtils.isInline(child);
33081
+ });
33082
+
33083
+ if (!hasBlockElems) {
33084
+ return shouldFormatInline(node, profile);
33085
+ }
33086
+
33087
+ return true;
33088
+ }
33089
+
33090
+ /**
33091
+ * Processes element with <code>tag</code> type
33092
+ * @param {AbbreviationNode} item
33093
+ * @param {OutputProfile} profile
33094
+ */
33095
+ function processTag(item, profile) {
33096
+ item.start = item.end = placeholder;
33097
+ var isUnary = abbrUtils.isUnary(item);
33098
+ var nl = '\n';
33099
+ var indent = getIndentation(item);
33100
+
33101
+ // formatting output
33102
+ if (profile.tag_nl !== false) {
33103
+ var forceNl = profile.tag_nl === true && (profile.tag_nl_leaf || item.children.length);
33104
+ if (!forceNl) {
33105
+ var forceIndentTags = prefs.getArray('format.forceIndentationForTags') || [];
33106
+ forceNl = ~forceIndentTags.indexOf(item.name());
33107
+ }
33108
+
33109
+ // formatting block-level elements
33110
+ if (!item.isTextNode()) {
33111
+ if (shouldAddLineBreak(item, profile)) {
33112
+ // - do not indent the very first element
33113
+ // - do not indent first child of a snippet
33114
+ if (!isVeryFirstChild(item) && (!abbrUtils.isSnippet(item.parent) || item.index()))
33115
+ item.start = nl + item.start;
33116
+
33117
+ if (abbrUtils.hasBlockChildren(item) || shouldBreakChild(item, profile) || (forceNl && !isUnary))
33118
+ item.end = nl + item.end;
33119
+
33120
+ if (abbrUtils.hasTagsInContent(item) || (forceNl && !item.children.length && !isUnary))
33121
+ item.start += nl + indent;
33122
+ } else if (abbrUtils.isInline(item) && hasBlockSibling(item) && !isVeryFirstChild(item)) {
33123
+ item.start = nl + item.start;
33124
+ } else if (abbrUtils.isInline(item) && shouldBreakInsideInline(item, profile)) {
33125
+ item.end = nl + item.end;
33126
+ }
33127
+
33128
+ item.padding = indent;
33129
+ }
33130
+ }
33131
+
33132
+ return item;
33133
+ }
33134
+
33135
+ /**
33136
+ * Processes simplified tree, making it suitable for output as HTML structure
33137
+ * @param {AbbreviationNode} tree
33138
+ * @param {OutputProfile} profile
33139
+ * @param {Number} level Depth level
33140
+ */
33141
+ return function process(tree, profile, level) {
33142
+ level = level || 0;
33143
+
33144
+ tree.children.forEach(function(item) {
33145
+ if (abbrUtils.isSnippet(item)) {
33146
+ processSnippet(item, profile, level);
33147
+ } else {
33148
+ processTag(item, profile, level);
33149
+ }
33150
+
33151
+ process(item, profile, level + 1);
33152
+ });
33153
+
33154
+ return tree;
33155
+ };
33156
+ });
33157
+ },{"../assets/preferences":28,"../assets/resources":31,"../utils/abbreviation":69,"../utils/common":73}],45:[function(require,module,exports){
33158
+ /**
33159
+ * Filter for producing HAML code from abbreviation.
33160
+ */
33161
+ if (typeof module === 'object' && typeof define !== 'function') {
33162
+ var define = function (factory) {
33163
+ module.exports = factory(require, exports, module);
33164
+ };
33165
+ }
33166
+
33167
+ define(function(require, exports, module) {
33168
+ var utils = require('../utils/common');
33169
+ var abbrUtils = require('../utils/abbreviation');
33170
+ var formatFilter = require('./format');
33171
+
33172
+ function transformClassName(className) {
33173
+ return utils.trim(className).replace(/\s+/g, '.');
33174
+ }
33175
+
33176
+ /**
33177
+ * Condenses all "data-" attributes into a single entry.
33178
+ * HAML allows data attributes to be ouputted as a sub-hash
33179
+ * of `:data` key
33180
+ * @param {Array} attrs
33181
+ * @return {Array}
33182
+ */
33183
+ function condenseDataAttrs(attrs) {
33184
+ var out = [], data = null;
33185
+ var reData = /^data-/i;
33186
+ attrs.forEach(function(attr) {
33187
+ if (reData.test(attr.name)) {
33188
+ if (!data) {
33189
+ data = [];
33190
+ out.push({
33191
+ name: 'data',
33192
+ value: data
33193
+ });
33194
+ }
33195
+
33196
+ data.push(utils.extend({}, attr, {name: attr.name.replace(reData, '')}));
33197
+ } else {
33198
+ out.push(attr);
33199
+ }
33200
+ });
33201
+
33202
+ return out;
33203
+ }
33204
+
33205
+ function stringifyAttrs(attrs, profile) {
33206
+ var attrQuote = profile.attributeQuote();
33207
+ return '{' + attrs.map(function(attr) {
33208
+ var value = attrQuote + attr.value + attrQuote;
33209
+ if (Array.isArray(attr.value)) {
33210
+ value = stringifyAttrs(attr.value, profile);
33211
+ } else if (attr.isBoolean) {
33212
+ value = 'true';
33213
+ }
33214
+
33215
+ return ':' + attr.name + ' => ' + value
33216
+ }).join(', ') + '}';
33217
+ }
33218
+
33219
+ /**
33220
+ * Creates HAML attributes string from tag according to profile settings
33221
+ * @param {AbbreviationNode} tag
33222
+ * @param {Object} profile
33223
+ */
33224
+ function makeAttributesString(tag, profile) {
33225
+ var attrs = '';
33226
+ var otherAttrs = [];
33227
+ var attrQuote = profile.attributeQuote();
33228
+ var cursor = profile.cursor();
33229
+
33230
+ tag.attributeList().forEach(function(a) {
33231
+ var attrName = profile.attributeName(a.name);
33232
+ switch (attrName.toLowerCase()) {
33233
+ // use short notation for ID and CLASS attributes
33234
+ case 'id':
33235
+ attrs += '#' + (a.value || cursor);
33236
+ break;
33237
+ case 'class':
33238
+ attrs += '.' + transformClassName(a.value || cursor);
33239
+ break;
33240
+ // process other attributes
33241
+ default:
33242
+ otherAttrs.push({
33243
+ name: attrName,
33244
+ value: a.value || cursor,
33245
+ isBoolean: profile.isBoolean(a.name, a.value)
33246
+ });
33247
+ }
33248
+ });
33249
+
33250
+ if (otherAttrs.length) {
33251
+ attrs += stringifyAttrs(condenseDataAttrs(otherAttrs), profile);
33252
+ }
33253
+
33254
+ return attrs;
33255
+ }
33256
+
33257
+ /**
33258
+ * Processes element with <code>tag</code> type
33259
+ * @param {AbbreviationNode} item
33260
+ * @param {OutputProfile} profile
33261
+ */
33262
+ function processTag(item, profile) {
33263
+ if (!item.parent)
33264
+ // looks like it's root element
33265
+ return item;
33266
+
33267
+ var attrs = makeAttributesString(item, profile);
33268
+ var cursor = profile.cursor();
33269
+ var isUnary = abbrUtils.isUnary(item);
33270
+ var selfClosing = profile.self_closing_tag && isUnary ? '/' : '';
33271
+ var start= '';
33272
+
33273
+ // define tag name
33274
+ var tagName = '%' + profile.tagName(item.name());
33275
+ if (tagName.toLowerCase() == '%div' && attrs && attrs.indexOf('{') == -1)
33276
+ // omit div tag
33277
+ tagName = '';
33278
+
33279
+ item.end = '';
33280
+ start = tagName + attrs + selfClosing;
33281
+ if (item.content && !/^\s/.test(item.content)) {
33282
+ item.content = ' ' + item.content;
33283
+ }
33284
+
33285
+ var placeholder = '%s';
33286
+ // We can't just replace placeholder with new value because
33287
+ // JavaScript will treat double $ character as a single one, assuming
33288
+ // we're using RegExp literal.
33289
+ item.start = utils.replaceSubstring(item.start, start, item.start.indexOf(placeholder), placeholder);
33290
+
33291
+ if (!item.children.length && !isUnary)
33292
+ item.start += cursor;
33293
+
33294
+ return item;
33295
+ }
33296
+
33297
+ return function process(tree, profile, level) {
33298
+ level = level || 0;
33299
+
33300
+ if (!level) {
33301
+ tree = formatFilter(tree, '_format', profile);
33302
+ }
33303
+
33304
+ tree.children.forEach(function(item) {
33305
+ if (!abbrUtils.isSnippet(item)) {
33306
+ processTag(item, profile, level);
33307
+ }
33308
+
33309
+ process(item, profile, level + 1);
33310
+ });
33311
+
33312
+ return tree;
33313
+ };
33314
+ });
33315
+ },{"../utils/abbreviation":69,"../utils/common":73,"./format":44}],46:[function(require,module,exports){
33316
+ /**
33317
+ * Filter that produces HTML tree
33318
+ */
33319
+ if (typeof module === 'object' && typeof define !== 'function') {
33320
+ var define = function (factory) {
33321
+ module.exports = factory(require, exports, module);
33322
+ };
33323
+ }
33324
+
33325
+ define(function(require, exports, module) {
33326
+ var abbrUtils = require('../utils/abbreviation');
33327
+ var utils = require('../utils/common');
33328
+ var tabStops = require('../assets/tabStops');
33329
+ var formatFilter = require('./format');
33330
+
33331
+ /**
33332
+ * Creates HTML attributes string from tag according to profile settings
33333
+ * @param {AbbreviationNode} node
33334
+ * @param {OutputProfile} profile
33335
+ */
33336
+ function makeAttributesString(node, profile) {
33337
+ var attrQuote = profile.attributeQuote();
33338
+ var cursor = profile.cursor();
33339
+
33340
+ return node.attributeList().map(function(a) {
33341
+ var isBoolean = profile.isBoolean(a.name, a.value);
33342
+ var attrName = profile.attributeName(a.name);
33343
+ var attrValue = isBoolean ? attrName : a.value;
33344
+ if (isBoolean && profile.allowCompactBoolean()) {
33345
+ return ' ' + attrName;
33346
+ }
33347
+ return ' ' + attrName + '=' + attrQuote + (attrValue || cursor) + attrQuote;
33348
+ }).join('');
33349
+ }
33350
+
33351
+ /**
33352
+ * Processes element with <code>tag</code> type
33353
+ * @param {AbbreviationNode} item
33354
+ * @param {OutputProfile} profile
33355
+ */
33356
+ function processTag(item, profile) {
33357
+ if (!item.parent) { // looks like it's root element
33358
+ return item;
33359
+ }
33360
+
33361
+ var attrs = makeAttributesString(item, profile);
33362
+ var cursor = profile.cursor();
33363
+ var isUnary = abbrUtils.isUnary(item);
33364
+ var start = '';
33365
+ var end = '';
33366
+
33367
+ // define opening and closing tags
33368
+ if (!item.isTextNode()) {
33369
+ var tagName = profile.tagName(item.name());
33370
+ if (isUnary) {
33371
+ start = '<' + tagName + attrs + profile.selfClosing() + '>';
33372
+ item.end = '';
33373
+ } else {
33374
+ start = '<' + tagName + attrs + '>';
33375
+ end = '</' + tagName + '>';
33376
+ }
33377
+ }
33378
+
33379
+ var placeholder = '%s';
33380
+ // We can't just replace placeholder with new value because
33381
+ // JavaScript will treat double $ character as a single one, assuming
33382
+ // we're using RegExp literal.
33383
+ item.start = utils.replaceSubstring(item.start, start, item.start.indexOf(placeholder), placeholder);
33384
+ item.end = utils.replaceSubstring(item.end, end, item.end.indexOf(placeholder), placeholder);
33385
+
33386
+ // should we put caret placeholder after opening tag?
33387
+ if (
33388
+ !item.children.length
33389
+ && !isUnary
33390
+ && !~item.content.indexOf(cursor)
33391
+ && !tabStops.extract(item.content).tabstops.length
33392
+ ) {
33393
+ item.start += cursor;
33394
+ }
33395
+
33396
+ return item;
33397
+ }
33398
+
33399
+ return function process(tree, profile, level) {
33400
+ level = level || 0;
33401
+
33402
+ if (!level) {
33403
+ tree = formatFilter(tree, profile, level)
33404
+ }
33405
+
33406
+ tree.children.forEach(function(item) {
33407
+ if (!abbrUtils.isSnippet(item)) {
33408
+ processTag(item, profile, level);
33409
+ }
33410
+
33411
+ process(item, profile, level + 1);
33412
+ });
33413
+
33414
+ return tree;
33415
+ };
33416
+ });
33417
+ },{"../assets/tabStops":33,"../utils/abbreviation":69,"../utils/common":73,"./format":44}],47:[function(require,module,exports){
33418
+ /**
33419
+ * Filter for producing Jade code from abbreviation.
33420
+ */
33421
+ if (typeof module === 'object' && typeof define !== 'function') {
33422
+ var define = function (factory) {
33423
+ module.exports = factory(require, exports, module);
33424
+ };
33425
+ }
33426
+
33427
+ define(function(require, exports, module) {
33428
+ var utils = require('../utils/common');
33429
+ var abbrUtils = require('../utils/abbreviation');
33430
+ var formatFilter = require('./format');
33431
+ var tabStops = require('../assets/tabStops');
33432
+ var profile = require('../assets/profile');
33433
+
33434
+ var reNl = /[\n\r]/;
33435
+ var reIndentedText = /^\s*\|/;
33436
+ var reSpace = /^\s/;
33437
+
33438
+ function transformClassName(className) {
33439
+ return utils.trim(className).replace(/\s+/g, '.');
33440
+ }
33441
+
33442
+ function stringifyAttrs(attrs, profile) {
33443
+ var attrQuote = profile.attributeQuote();
33444
+ return '(' + attrs.map(function(attr) {
33445
+ if (attr.isBoolean) {
33446
+ return attr.name;
33447
+ }
33448
+
33449
+ return attr.name + '=' + attrQuote + attr.value + attrQuote;
33450
+ }).join(', ') + ')';
33451
+ }
33452
+
33453
+ /**
33454
+ * Creates HAML attributes string from tag according to profile settings
33455
+ * @param {AbbreviationNode} tag
33456
+ * @param {Object} profile
33457
+ */
33458
+ function makeAttributesString(tag, profile) {
33459
+ var attrs = '';
33460
+ var otherAttrs = [];
33461
+ var attrQuote = profile.attributeQuote();
33462
+ var cursor = profile.cursor();
33463
+
33464
+ tag.attributeList().forEach(function(a) {
33465
+ var attrName = profile.attributeName(a.name);
33466
+ switch (attrName.toLowerCase()) {
33467
+ // use short notation for ID and CLASS attributes
33468
+ case 'id':
33469
+ attrs += '#' + (a.value || cursor);
33470
+ break;
33471
+ case 'class':
33472
+ attrs += '.' + transformClassName(a.value || cursor);
33473
+ break;
33474
+ // process other attributes
33475
+ default:
33476
+ otherAttrs.push({
33477
+ name: attrName,
33478
+ value: a.value || cursor,
33479
+ isBoolean: profile.isBoolean(a.name, a.value)
33480
+ });
33481
+ }
33482
+ });
33483
+
33484
+ if (otherAttrs.length) {
33485
+ attrs += stringifyAttrs(otherAttrs, profile);
33486
+ }
33487
+
33488
+ return attrs;
33489
+ }
33490
+
33491
+ function processTagContent(item) {
33492
+ if (!item.content) {
33493
+ return;
33494
+ }
33495
+
33496
+ var content = tabStops.replaceVariables(item.content, function(str, name) {
33497
+ if (name === 'nl' || name === 'newline') {
33498
+ return '\n';
33499
+ }
33500
+ return str;
33501
+ });
33502
+
33503
+ if (reNl.test(content) && !reIndentedText.test(content)) {
33504
+ // multiline content: pad it with indentation and pipe
33505
+ var pad = '| ';
33506
+ item.content = '\n' + pad + utils.padString(content, pad);
33507
+ } else if (!reSpace.test(content)) {
33508
+ item.content = ' ' + content;
33509
+ }
33510
+ }
33511
+
33512
+ /**
33513
+ * Processes element with <code>tag</code> type
33514
+ * @param {AbbreviationNode} item
33515
+ * @param {OutputProfile} profile
33516
+ */
33517
+ function processTag(item, profile) {
33518
+ if (!item.parent)
33519
+ // looks like it's a root (empty) element
33520
+ return item;
33521
+
33522
+ var attrs = makeAttributesString(item, profile);
33523
+ var cursor = profile.cursor();
33524
+ var isUnary = abbrUtils.isUnary(item);
33525
+
33526
+ // define tag name
33527
+ var tagName = profile.tagName(item.name());
33528
+ if (tagName.toLowerCase() == 'div' && attrs && attrs.charAt(0) != '(')
33529
+ // omit div tag
33530
+ tagName = '';
33531
+
33532
+ item.end = '';
33533
+ var start = tagName + attrs;
33534
+ processTagContent(item);
33535
+
33536
+ var placeholder = '%s';
33537
+ // We can't just replace placeholder with new value because
33538
+ // JavaScript will treat double $ character as a single one, assuming
33539
+ // we're using RegExp literal.
33540
+ item.start = utils.replaceSubstring(item.start, start, item.start.indexOf(placeholder), placeholder);
33541
+
33542
+ if (!item.children.length && !isUnary)
33543
+ item.start += cursor;
33544
+
33545
+ return item;
33546
+ }
33547
+
33548
+ return function process(tree, curProfile, level) {
33549
+ level = level || 0;
33550
+
33551
+ if (!level) {
33552
+ // always format with `xml` profile since
33553
+ // Jade requires all tags to be on separate lines
33554
+ tree = formatFilter(tree, profile.get('xml'));
33555
+ }
33556
+
33557
+ tree.children.forEach(function(item) {
33558
+ if (!abbrUtils.isSnippet(item)) {
33559
+ processTag(item, curProfile, level);
33560
+ }
33561
+
33562
+ process(item, curProfile, level + 1);
33563
+ });
33564
+
33565
+ return tree;
33566
+ };
33567
+ });
33568
+ },{"../assets/profile":29,"../assets/tabStops":33,"../utils/abbreviation":69,"../utils/common":73,"./format":44}],48:[function(require,module,exports){
33569
+ /**
33570
+ * A filter for React.js (JSX):
33571
+ * ranames attributes like `class` and `for`
33572
+ * for proper representation in JSX
33573
+ */
33574
+ if (typeof module === 'object' && typeof define !== 'function') {
33575
+ var define = function (factory) {
33576
+ module.exports = factory(require, exports, module);
33577
+ };
33578
+ }
33579
+
33580
+ define(function(require, exports, module) {
33581
+ var attrMap = {
33582
+ 'class': 'className',
33583
+ 'for': 'htmlFor'
33584
+ };
33585
+
33586
+ return function process(tree) {
33587
+ tree.children.forEach(function(item) {
33588
+ item._attributes.forEach(function(attr) {
33589
+ if (attr.name in attrMap) {
33590
+ attr.name = attrMap[attr.name]
33591
+ }
33592
+ });
33593
+ process(item);
33594
+ });
33595
+
33596
+ return tree;
33597
+ };
33598
+ });
33599
+ },{}],49:[function(require,module,exports){
33600
+ /**
33601
+ * Module for handling filters
33602
+ */
33603
+ if (typeof module === 'object' && typeof define !== 'function') {
33604
+ var define = function (factory) {
33605
+ module.exports = factory(require, exports, module);
33606
+ };
33607
+ }
33608
+
33609
+ define(function(require, exports, module) {
33610
+ var utils = require('../utils/common');
33611
+ var profile = require('../assets/profile');
33612
+ var resources = require('../assets/resources');
33613
+
33614
+ /** List of registered filters */
33615
+ var registeredFilters = {
33616
+ html: require('./html'),
33617
+ haml: require('./haml'),
33618
+ jade: require('./jade'),
33619
+ jsx: require('./jsx'),
33620
+ slim: require('./slim'),
33621
+ xsl: require('./xsl'),
33622
+ css: require('./css'),
33623
+ bem: require('./bem'),
33624
+ c: require('./comment'),
33625
+ e: require('./escape'),
33626
+ s: require('./singleLine'),
33627
+ t: require('./trim')
33628
+ };
33629
+
33630
+ /** Filters that will be applied for unknown syntax */
33631
+ var basicFilters = 'html';
33632
+
33633
+ function list(filters) {
33634
+ if (!filters)
33635
+ return [];
33636
+
33637
+ if (typeof filters === 'string') {
33638
+ return filters.split(/[\|,]/g);
33639
+ }
33640
+
33641
+ return filters;
33642
+ }
33643
+
33644
+ return {
33645
+ /**
33646
+ * Register new filter
33647
+ * @param {String} name Filter name
33648
+ * @param {Function} fn Filter function
33649
+ */
33650
+ add: function(name, fn) {
33651
+ registeredFilters[name] = fn;
33652
+ },
33653
+
33654
+ /**
33655
+ * Apply filters for final output tree
33656
+ * @param {AbbreviationNode} tree Output tree
33657
+ * @param {Array} filters List of filters to apply. Might be a
33658
+ * <code>String</code>
33659
+ * @param {Object} profile Output profile, defined in <i>profile</i>
33660
+ * module. Filters defined it profile are not used, <code>profile</code>
33661
+ * is passed to filter function
33662
+ * @memberOf emmet.filters
33663
+ * @returns {AbbreviationNode}
33664
+ */
33665
+ apply: function(tree, filters, profileName) {
33666
+ profileName = profile.get(profileName);
33667
+
33668
+ list(filters).forEach(function(filter) {
33669
+ var name = utils.trim(filter.toLowerCase());
33670
+ if (name && name in registeredFilters) {
33671
+ tree = registeredFilters[name](tree, profileName);
33672
+ }
33673
+ });
33674
+
33675
+ return tree;
33676
+ },
33677
+
33678
+ /**
33679
+ * Composes list of filters that should be applied to a tree, based on
33680
+ * passed data
33681
+ * @param {String} syntax Syntax name ('html', 'css', etc.)
33682
+ * @param {Object} profile Output profile
33683
+ * @param {String} additionalFilters List or pipe-separated
33684
+ * string of additional filters to apply
33685
+ * @returns {Array}
33686
+ */
33687
+ composeList: function(syntax, profileName, additionalFilters) {
33688
+ profileName = profile.get(profileName);
33689
+ var filters = list(profileName.filters || resources.findItem(syntax, 'filters') || basicFilters);
33690
+
33691
+ if (profileName.extraFilters) {
33692
+ filters = filters.concat(list(profileName.extraFilters));
33693
+ }
33694
+
33695
+ if (additionalFilters) {
33696
+ filters = filters.concat(list(additionalFilters));
33697
+ }
33698
+
33699
+ if (!filters || !filters.length) {
33700
+ // looks like unknown syntax, apply basic filters
33701
+ filters = list(basicFilters);
33702
+ }
33703
+
33704
+ return filters;
33705
+ },
33706
+
33707
+ /**
33708
+ * Extracts filter list from abbreviation
33709
+ * @param {String} abbr
33710
+ * @returns {Array} Array with cleaned abbreviation and list of
33711
+ * extracted filters
33712
+ */
33713
+ extract: function(abbr) {
33714
+ var filters = '';
33715
+ abbr = abbr.replace(/\|([\w\|\-]+)$/, function(str, p1){
33716
+ filters = p1;
33717
+ return '';
33718
+ });
33719
+
33720
+ return [abbr, list(filters)];
33721
+ }
33722
+ };
33723
+ });
33724
+ },{"../assets/profile":29,"../assets/resources":31,"../utils/common":73,"./bem":40,"./comment":41,"./css":42,"./escape":43,"./haml":45,"./html":46,"./jade":47,"./jsx":48,"./singleLine":50,"./slim":51,"./trim":52,"./xsl":53}],50:[function(require,module,exports){
33725
+ /**
33726
+ * Output abbreviation on a single line (i.e. no line breaks)
33727
+ */
33728
+ if (typeof module === 'object' && typeof define !== 'function') {
33729
+ var define = function (factory) {
33730
+ module.exports = factory(require, exports, module);
33731
+ };
33732
+ }
33733
+
33734
+ define(function(require, exports, module) {
33735
+ var abbrUtils = require('../utils/abbreviation');
33736
+ var rePad = /^\s+/;
33737
+ var reNl = /[\n\r]/g;
33738
+
33739
+ return function process(tree) {
33740
+ tree.children.forEach(function(item) {
33741
+ if (!abbrUtils.isSnippet(item)) {
33742
+ // remove padding from item
33743
+ item.start = item.start.replace(rePad, '');
33744
+ item.end = item.end.replace(rePad, '');
33745
+ }
33746
+
33747
+ // remove newlines
33748
+ item.start = item.start.replace(reNl, '');
33749
+ item.end = item.end.replace(reNl, '');
33750
+ item.content = item.content.replace(reNl, '');
33751
+
33752
+ process(item);
33753
+ });
33754
+
33755
+ return tree;
33756
+ };
33757
+ });
33758
+
33759
+ },{"../utils/abbreviation":69}],51:[function(require,module,exports){
33760
+ /**
33761
+ * Filter for producing Jade code from abbreviation.
33762
+ */
33763
+ if (typeof module === 'object' && typeof define !== 'function') {
33764
+ var define = function (factory) {
33765
+ module.exports = factory(require, exports, module);
33766
+ };
33767
+ }
33768
+
33769
+ define(function(require, exports, module) {
33770
+ var utils = require('../utils/common');
33771
+ var abbrUtils = require('../utils/abbreviation');
33772
+ var formatFilter = require('./format');
33773
+ var tabStops = require('../assets/tabStops');
33774
+ var prefs = require('../assets/preferences');
33775
+ var profile = require('../assets/profile');
33776
+
33777
+ var reNl = /[\n\r]/;
33778
+ var reIndentedText = /^\s*\|/;
33779
+ var reSpace = /^\s/;
33780
+
33781
+ prefs.define('slim.attributesWrapper', 'none',
33782
+ 'Defines how attributes will be wrapped:' +
33783
+ '<ul>' +
33784
+ '<li><code>none</code> – no wrapping;</li>' +
33785
+ '<li><code>round</code> — wrap attributes with round braces;</li>' +
33786
+ '<li><code>square</code> — wrap attributes with round braces;</li>' +
33787
+ '<li><code>curly</code> — wrap attributes with curly braces.</li>' +
33788
+ '</ul>');
33789
+
33790
+ function transformClassName(className) {
33791
+ return utils.trim(className).replace(/\s+/g, '.');
33792
+ }
33793
+
33794
+ function getAttrWrapper() {
33795
+ var start = ' ', end = '';
33796
+ switch (prefs.get('slim.attributesWrapper')) {
33797
+ case 'round':
33798
+ start = '(';
33799
+ end = ')';
33800
+ break;
33801
+ case 'square':
33802
+ start = '[';
33803
+ end = ']';
33804
+ break;
33805
+ case 'curly':
33806
+ start = '{';
33807
+ end = '}';
33808
+ break;
33809
+ }
33810
+
33811
+ return {
33812
+ start: start,
33813
+ end: end
33814
+ };
33815
+ }
33816
+
33817
+ function stringifyAttrs(attrs, profile) {
33818
+ var attrQuote = profile.attributeQuote();
33819
+ var attrWrap = getAttrWrapper();
33820
+ return attrWrap.start + attrs.map(function(attr) {
33821
+ var value = attrQuote + attr.value + attrQuote;
33822
+ if (attr.isBoolean) {
33823
+ if (!attrWrap.end) {
33824
+ value = 'true';
33825
+ } else {
33826
+ return attr.name;
33827
+ }
33828
+ }
33829
+
33830
+ return attr.name + '=' + value;
33831
+ }).join(' ') + attrWrap.end;
33832
+ }
33833
+
33834
+ /**
33835
+ * Creates HAML attributes string from tag according to profile settings
33836
+ * @param {AbbreviationNode} tag
33837
+ * @param {Object} profile
33838
+ */
33839
+ function makeAttributesString(tag, profile) {
33840
+ var attrs = '';
33841
+ var otherAttrs = [];
33842
+ var attrQuote = profile.attributeQuote();
33843
+ var cursor = profile.cursor();
33844
+
33845
+ tag.attributeList().forEach(function(a) {
33846
+ var attrName = profile.attributeName(a.name);
33847
+ switch (attrName.toLowerCase()) {
33848
+ // use short notation for ID and CLASS attributes
33849
+ case 'id':
33850
+ attrs += '#' + (a.value || cursor);
33851
+ break;
33852
+ case 'class':
33853
+ attrs += '.' + transformClassName(a.value || cursor);
33854
+ break;
33855
+ // process other attributes
33856
+ default:
33857
+ otherAttrs.push({
33858
+ name: attrName,
33859
+ value: a.value || cursor,
33860
+ isBoolean: profile.isBoolean(a.name, a.value)
33861
+ });
33862
+ }
33863
+ });
33864
+
33865
+ if (otherAttrs.length) {
33866
+ attrs += stringifyAttrs(otherAttrs, profile);
33867
+ }
33868
+
33869
+ return attrs;
33870
+ }
33871
+
33872
+ function processTagContent(item) {
33873
+ if (!item.content) {
33874
+ return;
33875
+ }
33876
+
33877
+ var content = tabStops.replaceVariables(item.content, function(str, name) {
33878
+ if (name === 'nl' || name === 'newline') {
33879
+ return '\n';
33880
+ }
33881
+ return str;
33882
+ });
33883
+
33884
+ if (reNl.test(content) && !reIndentedText.test(content)) {
33885
+ // multiline content: pad it with indentation and pipe
33886
+ var pad = ' ';
33887
+ item.content = '\n| ' + utils.padString(content, pad);
33888
+ } else if (!reSpace.test(content)) {
33889
+ item.content = ' ' + content;
33890
+ }
33891
+ }
33892
+
33893
+ /**
33894
+ * Processes element with <code>tag</code> type
33895
+ * @param {AbbreviationNode} item
33896
+ * @param {OutputProfile} profile
33897
+ */
33898
+ function processTag(item, profile) {
33899
+ if (!item.parent)
33900
+ // looks like it's a root (empty) element
33901
+ return item;
33902
+
33903
+ var attrs = makeAttributesString(item, profile);
33904
+ var cursor = profile.cursor();
33905
+ var isUnary = abbrUtils.isUnary(item);
33906
+ var selfClosing = profile.self_closing_tag && isUnary ? '/' : '';
33907
+
33908
+ // define tag name
33909
+ var tagName = profile.tagName(item.name());
33910
+ if (tagName.toLowerCase() == 'div' && attrs && '([{'.indexOf(attrs.charAt(0)) == -1)
33911
+ // omit div tag
33912
+ tagName = '';
33913
+
33914
+ item.end = '';
33915
+ var start = tagName + attrs + selfClosing;
33916
+ processTagContent(item);
33917
+
33918
+ var placeholder = '%s';
33919
+ // We can't just replace placeholder with new value because
33920
+ // JavaScript will treat double $ character as a single one, assuming
33921
+ // we're using RegExp literal.
33922
+ item.start = utils.replaceSubstring(item.start, start, item.start.indexOf(placeholder), placeholder);
33923
+
33924
+ if (!item.children.length && !isUnary)
33925
+ item.start += cursor;
33926
+
33927
+ return item;
33928
+ }
33929
+
33930
+ return function process(tree, curProfile, level) {
33931
+ level = level || 0;
33932
+
33933
+ if (!level) {
33934
+ // always format with `xml` profile since
33935
+ // Slim requires all tags to be on separate lines
33936
+ tree = formatFilter(tree, profile.get('xml'));
33937
+ }
33938
+
33939
+ tree.children.forEach(function(item) {
33940
+ if (!abbrUtils.isSnippet(item)) {
33941
+ processTag(item, curProfile, level);
33942
+ }
33943
+
33944
+ process(item, curProfile, level + 1);
33945
+ });
33946
+
33947
+ return tree;
33948
+ };
33949
+ });
33950
+ },{"../assets/preferences":28,"../assets/profile":29,"../assets/tabStops":33,"../utils/abbreviation":69,"../utils/common":73,"./format":44}],52:[function(require,module,exports){
33951
+ /**
33952
+ * Trim filter: removes characters at the beginning of the text
33953
+ * content that indicates lists: numbers, #, *, -, etc.
33954
+ *
33955
+ * Useful for wrapping lists with abbreviation.
33956
+ */
33957
+ if (typeof module === 'object' && typeof define !== 'function') {
33958
+ var define = function (factory) {
33959
+ module.exports = factory(require, exports, module);
33960
+ };
33961
+ }
33962
+
33963
+ define(function(require, exports, module) {
33964
+ var prefs = require('../assets/preferences');
33965
+ prefs.define('filter.trimRegexp',
33966
+ '[\\s|\\u00a0]*[\\d|#|\\-|\*|\\u2022]+\\.?\\s*',
33967
+ 'Regular expression used to remove list markers (numbers, dashes, '
33968
+ + 'bullets, etc.) in <code>t</code> (trim) filter. The trim filter '
33969
+ + 'is useful for wrapping with abbreviation lists, pased from other '
33970
+ + 'documents (for example, Word documents).');
33971
+
33972
+ function process(tree, re) {
33973
+ tree.children.forEach(function(item) {
33974
+ if (item.content) {
33975
+ item.content = item.content.replace(re, '');
33976
+ }
33977
+
33978
+ process(item, re);
33979
+ });
33980
+
33981
+ return tree;
33982
+ }
33983
+
33984
+ return function(tree) {
33985
+ var re = new RegExp(prefs.get('filter.trimRegexp'));
33986
+ return process(tree, re);
33987
+ };
33988
+ });
33989
+
33990
+ },{"../assets/preferences":28}],53:[function(require,module,exports){
33991
+ /**
33992
+ * Filter for trimming "select" attributes from some tags that contains
33993
+ * child elements
33994
+ */
33995
+ if (typeof module === 'object' && typeof define !== 'function') {
33996
+ var define = function (factory) {
33997
+ module.exports = factory(require, exports, module);
33998
+ };
33999
+ }
34000
+
34001
+ define(function(require, exports, module) {
34002
+ var abbrUtils = require('../utils/abbreviation');
34003
+
34004
+ var tags = {
34005
+ 'xsl:variable': 1,
34006
+ 'xsl:with-param': 1
34007
+ };
34008
+
34009
+ /**
34010
+ * Removes "select" attribute from node
34011
+ * @param {AbbreviationNode} node
34012
+ */
34013
+ function trimAttribute(node) {
34014
+ node.start = node.start.replace(/\s+select\s*=\s*(['"]).*?\1/, '');
34015
+ }
34016
+
34017
+ return function process(tree) {
34018
+ tree.children.forEach(function(item) {
34019
+ if (!abbrUtils.isSnippet(item)
34020
+ && (item.name() || '').toLowerCase() in tags
34021
+ && item.children.length)
34022
+ trimAttribute(item);
34023
+ process(item);
34024
+ });
34025
+
34026
+ return tree;
34027
+ };
34028
+ });
34029
+ },{"../utils/abbreviation":69}],54:[function(require,module,exports){
34030
+ /**
34031
+ * "Lorem ipsum" text generator. Matches <code>lipsum(num)?</code> or
34032
+ * <code>lorem(num)?</code> abbreviation.
34033
+ * This code is based on Django's contribution:
34034
+ * https://code.djangoproject.com/browser/django/trunk/django/contrib/webdesign/lorem_ipsum.py
34035
+ * <br><br>
34036
+ * Examples to test:<br>
34037
+ * <code>lipsum</code> – generates 30 words text.<br>
34038
+ * <code>lipsum*6</code> – generates 6 paragraphs (autowrapped with &lt;p&gt; element) of text.<br>
34039
+ * <code>ol>lipsum10*5</code> — generates ordered list with 5 list items (autowrapped with &lt;li&gt; tag)
34040
+ * with text of 10 words on each line.<br>
34041
+ * <code>span*3>lipsum20</code> – generates 3 paragraphs of 20-words text, each wrapped with &lt;span&gt; element.
34042
+ * Each paragraph phrase is unique.
34043
+ */
34044
+ if (typeof module === 'object' && typeof define !== 'function') {
34045
+ var define = function (factory) {
34046
+ module.exports = factory(require, exports, module);
34047
+ };
34048
+ }
34049
+
34050
+ define(function(require, exports, module) {
34051
+ var prefs = require('../assets/preferences');
34052
+
34053
+ var langs = {
34054
+ en: {
34055
+ common: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipisicing', 'elit'],
34056
+ words: ['exercitationem', 'perferendis', 'perspiciatis', 'laborum', 'eveniet',
34057
+ 'sunt', 'iure', 'nam', 'nobis', 'eum', 'cum', 'officiis', 'excepturi',
34058
+ 'odio', 'consectetur', 'quasi', 'aut', 'quisquam', 'vel', 'eligendi',
34059
+ 'itaque', 'non', 'odit', 'tempore', 'quaerat', 'dignissimos',
34060
+ 'facilis', 'neque', 'nihil', 'expedita', 'vitae', 'vero', 'ipsum',
34061
+ 'nisi', 'animi', 'cumque', 'pariatur', 'velit', 'modi', 'natus',
34062
+ 'iusto', 'eaque', 'sequi', 'illo', 'sed', 'ex', 'et', 'voluptatibus',
34063
+ 'tempora', 'veritatis', 'ratione', 'assumenda', 'incidunt', 'nostrum',
34064
+ 'placeat', 'aliquid', 'fuga', 'provident', 'praesentium', 'rem',
34065
+ 'necessitatibus', 'suscipit', 'adipisci', 'quidem', 'possimus',
34066
+ 'voluptas', 'debitis', 'sint', 'accusantium', 'unde', 'sapiente',
34067
+ 'voluptate', 'qui', 'aspernatur', 'laudantium', 'soluta', 'amet',
34068
+ 'quo', 'aliquam', 'saepe', 'culpa', 'libero', 'ipsa', 'dicta',
34069
+ 'reiciendis', 'nesciunt', 'doloribus', 'autem', 'impedit', 'minima',
34070
+ 'maiores', 'repudiandae', 'ipsam', 'obcaecati', 'ullam', 'enim',
34071
+ 'totam', 'delectus', 'ducimus', 'quis', 'voluptates', 'dolores',
34072
+ 'molestiae', 'harum', 'dolorem', 'quia', 'voluptatem', 'molestias',
34073
+ 'magni', 'distinctio', 'omnis', 'illum', 'dolorum', 'voluptatum', 'ea',
34074
+ 'quas', 'quam', 'corporis', 'quae', 'blanditiis', 'atque', 'deserunt',
34075
+ 'laboriosam', 'earum', 'consequuntur', 'hic', 'cupiditate',
34076
+ 'quibusdam', 'accusamus', 'ut', 'rerum', 'error', 'minus', 'eius',
34077
+ 'ab', 'ad', 'nemo', 'fugit', 'officia', 'at', 'in', 'id', 'quos',
34078
+ 'reprehenderit', 'numquam', 'iste', 'fugiat', 'sit', 'inventore',
34079
+ 'beatae', 'repellendus', 'magnam', 'recusandae', 'quod', 'explicabo',
34080
+ 'doloremque', 'aperiam', 'consequatur', 'asperiores', 'commodi',
34081
+ 'optio', 'dolor', 'labore', 'temporibus', 'repellat', 'veniam',
34082
+ 'architecto', 'est', 'esse', 'mollitia', 'nulla', 'a', 'similique',
34083
+ 'eos', 'alias', 'dolore', 'tenetur', 'deleniti', 'porro', 'facere',
34084
+ 'maxime', 'corrupti']
34085
+ },
34086
+ sp: {
34087
+ common: ['mujer', 'uno', 'dolor', 'más', 'de', 'poder', 'mismo', 'si'],
34088
+ words: ['ejercicio', 'preferencia', 'perspicacia', 'laboral', 'paño',
34089
+ 'suntuoso', 'molde', 'namibia', 'planeador', 'mirar', 'demás', 'oficinista', 'excepción',
34090
+ 'odio', 'consecuencia', 'casi', 'auto', 'chicharra', 'velo', 'elixir',
34091
+ 'ataque', 'no', 'odio', 'temporal', 'cuórum', 'dignísimo',
34092
+ 'facilismo', 'letra', 'nihilista', 'expedición', 'alma', 'alveolar', 'aparte',
34093
+ 'león', 'animal', 'como', 'paria', 'belleza', 'modo', 'natividad',
34094
+ 'justo', 'ataque', 'séquito', 'pillo', 'sed', 'ex', 'y', 'voluminoso',
34095
+ 'temporalidad', 'verdades', 'racional', 'asunción', 'incidente', 'marejada',
34096
+ 'placenta', 'amanecer', 'fuga', 'previsor', 'presentación', 'lejos',
34097
+ 'necesariamente', 'sospechoso', 'adiposidad', 'quindío', 'pócima',
34098
+ 'voluble', 'débito', 'sintió', 'accesorio', 'falda', 'sapiencia',
34099
+ 'volutas', 'queso', 'permacultura', 'laudo', 'soluciones', 'entero',
34100
+ 'pan', 'litro', 'tonelada', 'culpa', 'libertario', 'mosca', 'dictado',
34101
+ 'reincidente', 'nascimiento', 'dolor', 'escolar', 'impedimento', 'mínima',
34102
+ 'mayores', 'repugnante', 'dulce', 'obcecado', 'montaña', 'enigma',
34103
+ 'total', 'deletéreo', 'décima', 'cábala', 'fotografía', 'dolores',
34104
+ 'molesto', 'olvido', 'paciencia', 'resiliencia', 'voluntad', 'molestias',
34105
+ 'magnífico', 'distinción', 'ovni', 'marejada', 'cerro', 'torre', 'y',
34106
+ 'abogada', 'manantial', 'corporal', 'agua', 'crepúsculo', 'ataque', 'desierto',
34107
+ 'laboriosamente', 'angustia', 'afortunado', 'alma', 'encefalograma',
34108
+ 'materialidad', 'cosas', 'o', 'renuncia', 'error', 'menos', 'conejo',
34109
+ 'abadía', 'analfabeto', 'remo', 'fugacidad', 'oficio', 'en', 'almácigo', 'vos', 'pan',
34110
+ 'represión', 'números', 'triste', 'refugiado', 'trote', 'inventor',
34111
+ 'corchea', 'repelente', 'magma', 'recusado', 'patrón', 'explícito',
34112
+ 'paloma', 'síndrome', 'inmune', 'autoinmune', 'comodidad',
34113
+ 'ley', 'vietnamita', 'demonio', 'tasmania', 'repeler', 'apéndice',
34114
+ 'arquitecto', 'columna', 'yugo', 'computador', 'mula', 'a', 'propósito',
34115
+ 'fantasía', 'alias', 'rayo', 'tenedor', 'deleznable', 'ventana', 'cara',
34116
+ 'anemia', 'corrupto']
34117
+ },
34118
+ ru: {
34119
+ common: ['далеко-далеко', 'за', 'словесными', 'горами', 'в стране', 'гласных', 'и согласных', 'живут', 'рыбные', 'тексты'],
34120
+ words: ['вдали', 'от всех', 'они', 'буквенных', 'домах', 'на берегу', 'семантика',
34121
+ 'большого', 'языкового', 'океана', 'маленький', 'ручеек', 'даль',
34122
+ 'журчит', 'по всей', 'обеспечивает', 'ее','всеми', 'необходимыми',
34123
+ 'правилами', 'эта', 'парадигматическая', 'страна', 'которой', 'жаренные',
34124
+ 'предложения', 'залетают', 'прямо', 'рот', 'даже', 'всемогущая',
34125
+ 'пунктуация', 'не', 'имеет', 'власти', 'над', 'рыбными', 'текстами',
34126
+ 'ведущими', 'безорфографичный', 'образ', 'жизни', 'однажды', 'одна',
34127
+ 'маленькая', 'строчка','рыбного', 'текста', 'имени', 'lorem', 'ipsum',
34128
+ 'решила', 'выйти', 'большой', 'мир', 'грамматики', 'великий', 'оксмокс',
34129
+ 'предупреждал', 'о', 'злых', 'запятых', 'диких', 'знаках', 'вопроса',
34130
+ 'коварных', 'точках', 'запятой', 'но', 'текст', 'дал', 'сбить',
34131
+ 'себя', 'толку', 'он', 'собрал', 'семь', 'своих', 'заглавных', 'букв',
34132
+ 'подпоясал', 'инициал', 'за', 'пояс', 'пустился', 'дорогу',
34133
+ 'взобравшись', 'первую', 'вершину', 'курсивных', 'гор', 'бросил',
34134
+ 'последний', 'взгляд', 'назад', 'силуэт', 'своего', 'родного', 'города',
34135
+ 'буквоград', 'заголовок', 'деревни', 'алфавит', 'подзаголовок', 'своего',
34136
+ 'переулка', 'грустный', 'реторический', 'вопрос', 'скатился', 'его',
34137
+ 'щеке', 'продолжил', 'свой', 'путь', 'дороге', 'встретил', 'рукопись',
34138
+ 'она', 'предупредила', 'моей', 'все', 'переписывается', 'несколько',
34139
+ 'раз', 'единственное', 'что', 'меня', 'осталось', 'это', 'приставка',
34140
+ 'возвращайся', 'ты', 'лучше', 'свою', 'безопасную', 'страну', 'послушавшись',
34141
+ 'рукописи', 'наш', 'продолжил', 'свой', 'путь', 'вскоре', 'ему',
34142
+ 'повстречался', 'коварный', 'составитель', 'рекламных', 'текстов',
34143
+ 'напоивший', 'языком', 'речью', 'заманивший', 'свое', 'агенство',
34144
+ 'которое', 'использовало', 'снова', 'снова', 'своих', 'проектах',
34145
+ 'если', 'переписали', 'то', 'живет', 'там', 'до', 'сих', 'пор']
34146
+ }
34147
+ };
34148
+
34149
+
34150
+ prefs.define('lorem.defaultLang', 'en',
34151
+ 'Default language of generated dummy text. Currently, <code>en</code>\
34152
+ and <code>ru</code> are supported, but users can add their own syntaxes\
34153
+ see <a href="http://docs.emmet.io/abbreviations/lorem-ipsum/">docs</a>.');
34154
+ prefs.define('lorem.omitCommonPart', false,
34155
+ 'Omit commonly used part (e.g. “Lorem ipsum dolor sit amet“) from generated text.');
34156
+
34157
+ /**
34158
+ * Returns random integer between <code>from</code> and <code>to</code> values
34159
+ * @param {Number} from
34160
+ * @param {Number} to
34161
+ * @returns {Number}
34162
+ */
34163
+ function randint(from, to) {
34164
+ return Math.round(Math.random() * (to - from) + from);
34165
+ }
34166
+
34167
+ /**
34168
+ * @param {Array} arr
34169
+ * @param {Number} count
34170
+ * @returns {Array}
34171
+ */
34172
+ function sample(arr, count) {
34173
+ var len = arr.length;
34174
+ var iterations = Math.min(len, count);
34175
+ var result = [];
34176
+ while (result.length < iterations) {
34177
+ var randIx = randint(0, len - 1);
34178
+ if (!~result.indexOf(randIx)) {
34179
+ result.push(randIx);
34180
+ }
34181
+ }
34182
+
34183
+ return result.map(function(ix) {
34184
+ return arr[ix];
34185
+ });
34186
+ }
34187
+
34188
+ function choice(val) {
34189
+ if (typeof val === 'string')
34190
+ return val.charAt(randint(0, val.length - 1));
34191
+
34192
+ return val[randint(0, val.length - 1)];
34193
+ }
34194
+
34195
+ function sentence(words, end) {
34196
+ if (words.length) {
34197
+ words[0] = words[0].charAt(0).toUpperCase() + words[0].substring(1);
34198
+ }
34199
+
34200
+ return words.join(' ') + (end || choice('?!...')); // more dots than question marks
34201
+ }
34202
+
34203
+ /**
34204
+ * Insert commas at randomly selected words. This function modifies values
34205
+ * inside <code>words</code> array
34206
+ * @param {Array} words
34207
+ */
34208
+ function insertCommas(words) {
34209
+ var len = words.length;
34210
+
34211
+ if (len < 2) {
34212
+ return;
34213
+ }
34214
+
34215
+ var totalCommas = 0;
34216
+ if (len > 3 && len <= 6) {
34217
+ totalCommas = randint(0, 1);
34218
+ } else if (len > 6 && len <= 12) {
34219
+ totalCommas = randint(0, 2);
34220
+ } else {
34221
+ totalCommas = randint(1, 4);
34222
+ }
34223
+
34224
+ for (var i = 0, pos, word; i < totalCommas; i++) {
34225
+ pos = randint(0, words.length - 2);
34226
+ word = words[pos];
34227
+ if (word.charAt(word.length - 1) !== ',') {
34228
+ words[pos] += ',';
34229
+ }
34230
+ }
34231
+ }
34232
+
34233
+ /**
34234
+ * Generate a paragraph of "Lorem ipsum" text
34235
+ * @param {Number} wordCount Words count in paragraph
34236
+ * @param {Boolean} startWithCommon Should paragraph start with common
34237
+ * "lorem ipsum" sentence.
34238
+ * @returns {String}
34239
+ */
34240
+ function paragraph(lang, wordCount, startWithCommon) {
34241
+ var data = langs[lang];
34242
+ if (!data) {
34243
+ return '';
34244
+ }
34245
+
34246
+ var result = [];
34247
+ var totalWords = 0;
34248
+ var words;
34249
+
34250
+ wordCount = parseInt(wordCount, 10);
34251
+
34252
+ if (startWithCommon && data.common) {
34253
+ words = data.common.slice(0, wordCount);
34254
+ if (words.length > 5) {
34255
+ words[4] += ',';
34256
+ }
34257
+ totalWords += words.length;
34258
+ result.push(sentence(words, '.'));
34259
+ }
34260
+
34261
+ while (totalWords < wordCount) {
34262
+ words = sample(data.words, Math.min(randint(2, 30), wordCount - totalWords));
34263
+ totalWords += words.length;
34264
+ insertCommas(words);
34265
+ result.push(sentence(words));
34266
+ }
34267
+
34268
+ return result.join(' ');
34269
+ }
34270
+
34271
+ return {
34272
+ /**
34273
+ * Adds new language words for Lorem Ipsum generator
34274
+ * @param {String} lang Two-letter lang definition
34275
+ * @param {Object} data Words for language. Maight be either a space-separated
34276
+ * list of words (String), Array of words or object with <code>text</code> and
34277
+ * <code>common</code> properties
34278
+ */
34279
+ addLang: function(lang, data) {
34280
+ if (typeof data === 'string') {
34281
+ data = {
34282
+ words: data.split(' ').filter(function(item) {
34283
+ return !!item;
34284
+ })
34285
+ };
34286
+ } else if (Array.isArray(data)) {
34287
+ data = {words: data};
34288
+ }
34289
+
34290
+ langs[lang] = data;
34291
+ },
34292
+ preprocessor: function(tree) {
34293
+ var re = /^(?:lorem|lipsum)([a-z]{2})?(\d*)$/i, match;
34294
+ var allowCommon = !prefs.get('lorem.omitCommonPart');
34295
+
34296
+ /** @param {AbbreviationNode} node */
34297
+ tree.findAll(function(node) {
34298
+ if (node._name && (match = node._name.match(re))) {
34299
+ var wordCound = match[2] || 30;
34300
+ var lang = match[1] || prefs.get('lorem.defaultLang') || 'en';
34301
+
34302
+ // force node name resolving if node should be repeated
34303
+ // or contains attributes. In this case, node should be outputed
34304
+ // as tag, otherwise as text-only node
34305
+ node._name = '';
34306
+ node.data('forceNameResolving', node.isRepeating() || node.attributeList().length);
34307
+ node.data('pasteOverwrites', true);
34308
+ node.data('paste', function(i) {
34309
+ return paragraph(lang, wordCound, !i && allowCommon);
34310
+ });
34311
+ }
34312
+ });
34313
+ }
34314
+ };
34315
+ });
34316
+
34317
+ },{"../assets/preferences":28}],55:[function(require,module,exports){
34318
+ /**
34319
+ * Emmet abbreviation parser.
34320
+ * Takes string abbreviation and recursively parses it into a tree. The parsed
34321
+ * tree can be transformed into a string representation with
34322
+ * <code>toString()</code> method. Note that string representation is defined
34323
+ * by custom processors (called <i>filters</i>), not by abbreviation parser
34324
+ * itself.
34325
+ *
34326
+ * This module can be extended with custom pre-/post-processors to shape-up
34327
+ * final tree or its representation. Actually, many features of abbreviation
34328
+ * engine are defined in other modules as tree processors
34329
+ */
34330
+ if (typeof module === 'object' && typeof define !== 'function') {
34331
+ var define = function (factory) {
34332
+ module.exports = factory(require, exports, module);
34333
+ };
34334
+ }
34335
+
34336
+ define(function(require, exports, module) {
34337
+ var tabStops = require('../assets/tabStops');
34338
+ var profile = require('../assets/profile');
34339
+ var filters = require('../filter/main');
34340
+ var utils = require('../utils/common');
34341
+ var abbreviationUtils = require('../utils/abbreviation');
34342
+ var stringStream = require('../assets/stringStream');
34343
+
34344
+ // pre- and post-processorcs
34345
+ var lorem = require('../generator/lorem');
34346
+ var procPastedContent = require('./processor/pastedContent');
34347
+ var procTagName = require('./processor/tagName');
34348
+ var procResourceMatcher = require('./processor/resourceMatcher');
34349
+ var procAttributes = require('./processor/attributes');
34350
+ var procHref = require('./processor/href');
34351
+
34352
+ var reValidName = /^[\w\-\$\:@\!%]+\+?$/i;
34353
+ var reWord = /[\w\-:\$@]/;
34354
+ var DEFAULT_ATTR_NAME = '%default';
34355
+
34356
+ var pairs = {
34357
+ '[': ']',
34358
+ '(': ')',
34359
+ '{': '}'
34360
+ };
34361
+
34362
+ var spliceFn = Array.prototype.splice;
34363
+
34364
+ var preprocessors = [];
34365
+ var postprocessors = [];
34366
+ var outputProcessors = [];
34367
+
34368
+ /**
34369
+ * @type AbbreviationNode
34370
+ */
34371
+ function AbbreviationNode(parent) {
34372
+ /** @type AbbreviationNode */
34373
+ this.parent = null;
34374
+ this.children = [];
34375
+ this._attributes = [];
34376
+
34377
+ /** @type String Raw abbreviation for current node */
34378
+ this.abbreviation = '';
34379
+ this.counter = 1;
34380
+ this._name = null;
34381
+ this._text = '';
34382
+ this.repeatCount = 1;
34383
+ this.hasImplicitRepeat = false;
34384
+
34385
+ /** Custom data dictionary */
34386
+ this._data = {};
34387
+
34388
+ // output properties
34389
+ this.start = '';
34390
+ this.end = '';
34391
+ this.content = '';
34392
+ this.padding = '';
34393
+ }
34394
+
34395
+ AbbreviationNode.prototype = {
34396
+ /**
34397
+ * Adds passed node as child or creates new child
34398
+ * @param {AbbreviationNode} child
34399
+ * @param {Number} position Index in children array where child should
34400
+ * be inserted
34401
+ * @return {AbbreviationNode}
34402
+ */
34403
+ addChild: function(child, position) {
34404
+ child = child || new AbbreviationNode();
34405
+ child.parent = this;
34406
+
34407
+ if (typeof position === 'undefined') {
34408
+ this.children.push(child);
34409
+ } else {
34410
+ this.children.splice(position, 0, child);
34411
+ }
34412
+
34413
+ return child;
34414
+ },
34415
+
34416
+ /**
34417
+ * Creates a deep copy of current node
34418
+ * @returns {AbbreviationNode}
34419
+ */
34420
+ clone: function() {
34421
+ var node = new AbbreviationNode();
34422
+ var attrs = ['abbreviation', 'counter', '_name', '_text', 'repeatCount', 'hasImplicitRepeat', 'start', 'end', 'content', 'padding'];
34423
+ attrs.forEach(function(a) {
34424
+ node[a] = this[a];
34425
+ }, this);
34426
+
34427
+ // clone attributes
34428
+ node._attributes = this._attributes.map(function(attr) {
34429
+ return utils.extend({}, attr);
34430
+ });
34431
+
34432
+ node._data = utils.extend({}, this._data);
34433
+
34434
+ // clone children
34435
+ node.children = this.children.map(function(child) {
34436
+ child = child.clone();
34437
+ child.parent = node;
34438
+ return child;
34439
+ });
34440
+
34441
+ return node;
34442
+ },
34443
+
34444
+ /**
34445
+ * Removes current node from parent‘s child list
34446
+ * @returns {AbbreviationNode} Current node itself
34447
+ */
34448
+ remove: function() {
34449
+ if (this.parent) {
34450
+ var ix = this.parent.children.indexOf(this);
34451
+ if (~ix) {
34452
+ this.parent.children.splice(ix, 1);
34453
+ }
34454
+ }
34455
+
34456
+ return this;
34457
+ },
34458
+
34459
+ /**
34460
+ * Replaces current node in parent‘s children list with passed nodes
34461
+ * @param {AbbreviationNode} node Replacement node or array of nodes
34462
+ */
34463
+ replace: function() {
34464
+ var parent = this.parent;
34465
+ var ix = parent.children.indexOf(this);
34466
+ var items = utils.flatten(arguments);
34467
+ spliceFn.apply(parent.children, [ix, 1].concat(items));
34468
+
34469
+ // update parent
34470
+ items.forEach(function(item) {
34471
+ item.parent = parent;
34472
+ });
34473
+ },
34474
+
34475
+ /**
34476
+ * Recursively sets <code>property</code> to <code>value</code> of current
34477
+ * node and its children
34478
+ * @param {String} name Property to update
34479
+ * @param {Object} value New property value
34480
+ */
34481
+ updateProperty: function(name, value) {
34482
+ this[name] = value;
34483
+ this.children.forEach(function(child) {
34484
+ child.updateProperty(name, value);
34485
+ });
34486
+
34487
+ return this;
34488
+ },
34489
+
34490
+ /**
34491
+ * Finds first child node that matches truth test for passed
34492
+ * <code>fn</code> function
34493
+ * @param {Function} fn
34494
+ * @returns {AbbreviationNode}
34495
+ */
34496
+ find: function(fn) {
34497
+ return this.findAll(fn, {amount: 1})[0];
34498
+ },
34499
+
34500
+ /**
34501
+ * Finds all child nodes that matches truth test for passed
34502
+ * <code>fn</code> function
34503
+ * @param {Function} fn
34504
+ * @returns {Array}
34505
+ */
34506
+ findAll: function(fn, state) {
34507
+ state = utils.extend({amount: 0, found: 0}, state || {});
34508
+
34509
+ if (typeof fn !== 'function') {
34510
+ var elemName = fn.toLowerCase();
34511
+ fn = function(item) {return item.name().toLowerCase() == elemName;};
34512
+ }
34513
+
34514
+ var result = [];
34515
+ this.children.forEach(function(child) {
34516
+ if (fn(child)) {
34517
+ result.push(child);
34518
+ state.found++;
34519
+ if (state.amount && state.found >= state.amount) {
34520
+ return;
34521
+ }
34522
+ }
34523
+
34524
+ result = result.concat(child.findAll(fn));
34525
+ });
34526
+
34527
+ return result.filter(function(item) {
34528
+ return !!item;
34529
+ });
34530
+ },
34531
+
34532
+ /**
34533
+ * Sets/gets custom data
34534
+ * @param {String} name
34535
+ * @param {Object} value
34536
+ * @returns {Object}
34537
+ */
34538
+ data: function(name, value) {
34539
+ if (arguments.length == 2) {
34540
+ this._data[name] = value;
34541
+ }
34542
+
34543
+ return this._data[name];
34544
+ },
34545
+
34546
+ /**
34547
+ * Returns name of current node
34548
+ * @returns {String}
34549
+ */
34550
+ name: function() {
34551
+ return this._name;
34552
+ },
34553
+
34554
+ /**
34555
+ * Returns list of attributes for current node
34556
+ * @returns {Array}
34557
+ */
34558
+ attributeList: function() {
34559
+ return optimizeAttributes(this._attributes.slice(0));
34560
+ },
34561
+
34562
+ /**
34563
+ * Returns or sets attribute value
34564
+ * @param {String} name Attribute name
34565
+ * @param {String} value New attribute value. `Null` value
34566
+ * will remove attribute
34567
+ * @returns {String}
34568
+ */
34569
+ attribute: function(name, value) {
34570
+ if (arguments.length == 2) {
34571
+ if (value === null) {
34572
+ // remove attribute
34573
+ var vals = this._attributes.filter(function(attr) {
34574
+ return attr.name === name;
34575
+ });
34576
+
34577
+ var that = this;
34578
+ vals.forEach(function(attr) {
34579
+ var ix = that._attributes.indexOf(attr);
34580
+ if (~ix) {
34581
+ that._attributes.splice(ix, 1);
34582
+ }
34583
+ });
34584
+
34585
+ return;
34586
+ }
34587
+
34588
+ // modify attribute
34589
+ var attrNames = this._attributes.map(function(attr) {
34590
+ return attr.name;
34591
+ });
34592
+ var ix = attrNames.indexOf(name.toLowerCase());
34593
+ if (~ix) {
34594
+ this._attributes[ix].value = value;
34595
+ } else {
34596
+ this._attributes.push({
34597
+ name: name,
34598
+ value: value
34599
+ });
34600
+ }
34601
+ }
34602
+
34603
+ return (utils.find(this.attributeList(), function(attr) {
34604
+ return attr.name == name;
34605
+ }) || {}).value;
34606
+ },
34607
+
34608
+ /**
34609
+ * Returns index of current node in parent‘s children list
34610
+ * @returns {Number}
34611
+ */
34612
+ index: function() {
34613
+ return this.parent ? this.parent.children.indexOf(this) : -1;
34614
+ },
34615
+
34616
+ /**
34617
+ * Sets how many times current element should be repeated
34618
+ * @private
34619
+ */
34620
+ _setRepeat: function(count) {
34621
+ if (count) {
34622
+ this.repeatCount = parseInt(count, 10) || 1;
34623
+ } else {
34624
+ this.hasImplicitRepeat = true;
34625
+ }
34626
+ },
34627
+
34628
+ /**
34629
+ * Sets abbreviation that belongs to current node
34630
+ * @param {String} abbr
34631
+ */
34632
+ setAbbreviation: function(abbr) {
34633
+ abbr = abbr || '';
34634
+
34635
+ var that = this;
34636
+
34637
+ // find multiplier
34638
+ abbr = abbr.replace(/\*(\d+)?$/, function(str, repeatCount) {
34639
+ that._setRepeat(repeatCount);
34640
+ return '';
34641
+ });
34642
+
34643
+ this.abbreviation = abbr;
34644
+
34645
+ var abbrText = extractText(abbr);
34646
+ if (abbrText) {
34647
+ abbr = abbrText.element;
34648
+ this.content = this._text = abbrText.text;
34649
+ }
34650
+
34651
+ var abbrAttrs = parseAttributes(abbr);
34652
+ if (abbrAttrs) {
34653
+ abbr = abbrAttrs.element;
34654
+ this._attributes = abbrAttrs.attributes;
34655
+ }
34656
+
34657
+ this._name = abbr;
34658
+
34659
+ // validate name
34660
+ if (this._name && !reValidName.test(this._name)) {
34661
+ throw new Error('Invalid abbreviation');
34662
+ }
34663
+ },
34664
+
34665
+ /**
34666
+ * Returns string representation of current node
34667
+ * @return {String}
34668
+ */
34669
+ valueOf: function() {
34670
+ var start = this.start;
34671
+ var end = this.end;
34672
+ var content = this.content;
34673
+
34674
+ // apply output processors
34675
+ var node = this;
34676
+ outputProcessors.forEach(function(fn) {
34677
+ start = fn(start, node, 'start');
34678
+ content = fn(content, node, 'content');
34679
+ end = fn(end, node, 'end');
34680
+ });
34681
+
34682
+
34683
+ var innerContent = this.children.map(function(child) {
34684
+ return child.valueOf();
34685
+ }).join('');
34686
+
34687
+ content = abbreviationUtils.insertChildContent(content, innerContent, {
34688
+ keepVariable: false
34689
+ });
34690
+
34691
+ return start + utils.padString(content, this.padding) + end;
34692
+ },
34693
+
34694
+ toString: function() {
34695
+ return this.valueOf();
34696
+ },
34697
+
34698
+ /**
34699
+ * Check if current node contains children with empty <code>expr</code>
34700
+ * property
34701
+ * @return {Boolean}
34702
+ */
34703
+ hasEmptyChildren: function() {
34704
+ return !!utils.find(this.children, function(child) {
34705
+ return child.isEmpty();
34706
+ });
34707
+ },
34708
+
34709
+ /**
34710
+ * Check if current node has implied name that should be resolved
34711
+ * @returns {Boolean}
34712
+ */
34713
+ hasImplicitName: function() {
34714
+ return !this._name && !this.isTextNode();
34715
+ },
34716
+
34717
+ /**
34718
+ * Indicates that current element is a grouping one, e.g. has no
34719
+ * representation but serves as a container for other nodes
34720
+ * @returns {Boolean}
34721
+ */
34722
+ isGroup: function() {
34723
+ return !this.abbreviation;
34724
+ },
34725
+
34726
+ /**
34727
+ * Indicates empty node (i.e. without abbreviation). It may be a
34728
+ * grouping node and should not be outputted
34729
+ * @return {Boolean}
34730
+ */
34731
+ isEmpty: function() {
34732
+ return !this.abbreviation && !this.children.length;
34733
+ },
34734
+
34735
+ /**
34736
+ * Indicates that current node should be repeated
34737
+ * @returns {Boolean}
34738
+ */
34739
+ isRepeating: function() {
34740
+ return this.repeatCount > 1 || this.hasImplicitRepeat;
34741
+ },
34742
+
34743
+ /**
34744
+ * Check if current node is a text-only node
34745
+ * @return {Boolean}
34746
+ */
34747
+ isTextNode: function() {
34748
+ return !this.name() && !this.attributeList().length;
34749
+ },
34750
+
34751
+ /**
34752
+ * Indicates whether this node may be used to build elements or snippets
34753
+ * @returns {Boolean}
34754
+ */
34755
+ isElement: function() {
34756
+ return !this.isEmpty() && !this.isTextNode();
34757
+ },
34758
+
34759
+ /**
34760
+ * Returns latest and deepest child of current tree
34761
+ * @returns {AbbreviationNode}
34762
+ */
34763
+ deepestChild: function() {
34764
+ if (!this.children.length)
34765
+ return null;
34766
+
34767
+ var deepestChild = this;
34768
+ while (deepestChild.children.length) {
34769
+ deepestChild = deepestChild.children[deepestChild.children.length - 1];
34770
+ }
34771
+
34772
+ return deepestChild;
34773
+ }
34774
+ };
34775
+
34776
+ /**
34777
+ * Returns stripped string: a string without first and last character.
34778
+ * Used for “unquoting” strings
34779
+ * @param {String} str
34780
+ * @returns {String}
34781
+ */
34782
+ function stripped(str) {
34783
+ return str.substring(1, str.length - 1);
34784
+ }
34785
+
34786
+ function consumeQuotedValue(stream, quote) {
34787
+ var ch;
34788
+ while ((ch = stream.next())) {
34789
+ if (ch === quote)
34790
+ return true;
34791
+
34792
+ if (ch == '\\')
34793
+ continue;
34794
+ }
34795
+
34796
+ return false;
34797
+ }
34798
+
34799
+ /**
34800
+ * Parses abbreviation into a tree
34801
+ * @param {String} abbr
34802
+ * @returns {AbbreviationNode}
34803
+ */
34804
+ function parseAbbreviation(abbr) {
34805
+ abbr = utils.trim(abbr);
34806
+
34807
+ var root = new AbbreviationNode();
34808
+ var context = root.addChild(), ch;
34809
+
34810
+ /** @type StringStream */
34811
+ var stream = stringStream.create(abbr);
34812
+ var loopProtector = 1000, multiplier;
34813
+ var addChild = function(child) {
34814
+ context.addChild(child);
34815
+ };
34816
+
34817
+ var consumeAbbr = function() {
34818
+ stream.start = stream.pos;
34819
+ stream.eatWhile(function(c) {
34820
+ if (c == '[' || c == '{') {
34821
+ if (stream.skipToPair(c, pairs[c])) {
34822
+ stream.backUp(1);
34823
+ return true;
34824
+ }
34825
+
34826
+ throw new Error('Invalid abbreviation: mo matching "' + pairs[c] + '" found for character at ' + stream.pos);
34827
+ }
34828
+
34829
+ if (c == '+') {
34830
+ // let's see if this is an expando marker
34831
+ stream.next();
34832
+ var isMarker = stream.eol() || ~'+>^*'.indexOf(stream.peek());
34833
+ stream.backUp(1);
34834
+ return isMarker;
34835
+ }
34836
+
34837
+ return c != '(' && isAllowedChar(c);
34838
+ });
34839
+ };
34840
+
34841
+ while (!stream.eol() && --loopProtector > 0) {
34842
+ ch = stream.peek();
34843
+
34844
+ switch (ch) {
34845
+ case '(': // abbreviation group
34846
+ stream.start = stream.pos;
34847
+ if (stream.skipToPair('(', ')')) {
34848
+ var inner = parseAbbreviation(stripped(stream.current()));
34849
+ if ((multiplier = stream.match(/^\*(\d+)?/, true))) {
34850
+ context._setRepeat(multiplier[1]);
34851
+ }
34852
+
34853
+ inner.children.forEach(addChild);
34854
+ } else {
34855
+ throw new Error('Invalid abbreviation: mo matching ")" found for character at ' + stream.pos);
34856
+ }
34857
+ break;
34858
+
34859
+ case '>': // child operator
34860
+ context = context.addChild();
34861
+ stream.next();
34862
+ break;
34863
+
34864
+ case '+': // sibling operator
34865
+ context = context.parent.addChild();
34866
+ stream.next();
34867
+ break;
34868
+
34869
+ case '^': // climb up operator
34870
+ var parent = context.parent || context;
34871
+ context = (parent.parent || parent).addChild();
34872
+ stream.next();
34873
+ break;
34874
+
34875
+ default: // consume abbreviation
34876
+ consumeAbbr();
34877
+ context.setAbbreviation(stream.current());
34878
+ stream.start = stream.pos;
34879
+ }
34880
+ }
34881
+
34882
+ if (loopProtector < 1) {
34883
+ throw new Error('Endless loop detected');
34884
+ }
34885
+
34886
+ return root;
34887
+ }
34888
+
34889
+ /**
34890
+ * Splits attribute set into a list of attributes string
34891
+ * @param {String} attrSet
34892
+ * @return {Array}
34893
+ */
34894
+ function splitAttributes(attrSet) {
34895
+ attrSet = utils.trim(attrSet);
34896
+ var parts = [];
34897
+
34898
+ // split attribute set by spaces
34899
+ var stream = stringStream(attrSet), ch;
34900
+ while ((ch = stream.next())) {
34901
+ if (ch == ' ') {
34902
+ parts.push(utils.trim(stream.current()));
34903
+ // skip spaces
34904
+ while (stream.peek() == ' ') {
34905
+ stream.next();
34906
+ }
34907
+
34908
+ stream.start = stream.pos;
34909
+ } else if (ch == '"' || ch == "'") {
34910
+ // skip values in strings
34911
+ if (!stream.skipString(ch)) {
34912
+ throw new Error('Invalid attribute set');
34913
+ }
34914
+ }
34915
+ }
34916
+
34917
+ parts.push(utils.trim(stream.current()));
34918
+ return parts;
34919
+ }
34920
+
34921
+ /**
34922
+ * Removes opening and closing quotes from given string
34923
+ * @param {String} str
34924
+ * @return {String}
34925
+ */
34926
+ function unquote(str) {
34927
+ var ch = str.charAt(0);
34928
+ if (ch == '"' || ch == "'") {
34929
+ str = str.substr(1);
34930
+ var last = str.charAt(str.length - 1);
34931
+ if (last === ch) {
34932
+ str = str.substr(0, str.length - 1);
34933
+ }
34934
+ }
34935
+
34936
+ return str;
34937
+ }
34938
+
34939
+ /**
34940
+ * Extract attributes and their values from attribute set:
34941
+ * <code>[attr col=3 title="Quoted string"]</code> (without square braces)
34942
+ * @param {String} attrSet
34943
+ * @returns {Array}
34944
+ */
34945
+ function extractAttributes(attrSet) {
34946
+ var reAttrName = /^[\w\-:\$@]+\.?$/;
34947
+ return splitAttributes(attrSet).map(function(attr) {
34948
+ // attribute name: [attr]
34949
+ if (reAttrName.test(attr)) {
34950
+ var value = '';
34951
+ if (attr.charAt(attr.length - 1) == '.') {
34952
+ // a boolean attribute
34953
+ attr = attr.substr(0, attr.length - 1);
34954
+ value = attr;
34955
+ }
34956
+ return {
34957
+ name: attr,
34958
+ value: value
34959
+ };
34960
+ }
34961
+
34962
+ // attribute with value: [name=val], [name="val"]
34963
+ if (~attr.indexOf('=')) {
34964
+ var parts = attr.split('=');
34965
+ return {
34966
+ name: parts.shift(),
34967
+ value: unquote(parts.join('='))
34968
+ };
34969
+ }
34970
+
34971
+ // looks like it’s implied attribute
34972
+ return {
34973
+ name: DEFAULT_ATTR_NAME,
34974
+ value: unquote(attr)
34975
+ };
34976
+ });
34977
+ }
34978
+
34979
+ /**
34980
+ * Parses tag attributes extracted from abbreviation. If attributes found,
34981
+ * returns object with <code>element</code> and <code>attributes</code>
34982
+ * properties
34983
+ * @param {String} abbr
34984
+ * @returns {Object} Returns <code>null</code> if no attributes found in
34985
+ * abbreviation
34986
+ */
34987
+ function parseAttributes(abbr) {
34988
+ /*
34989
+ * Example of incoming data:
34990
+ * #header
34991
+ * .some.data
34992
+ * .some.data#header
34993
+ * [attr]
34994
+ * #item[attr=Hello other="World"].class
34995
+ */
34996
+ var result = [];
34997
+ var attrMap = {'#': 'id', '.': 'class'};
34998
+ var nameEnd = null;
34999
+
35000
+ /** @type StringStream */
35001
+ var stream = stringStream.create(abbr);
35002
+ while (!stream.eol()) {
35003
+ switch (stream.peek()) {
35004
+ case '#': // id
35005
+ case '.': // class
35006
+ if (nameEnd === null)
35007
+ nameEnd = stream.pos;
35008
+
35009
+ var attrName = attrMap[stream.peek()];
35010
+
35011
+ stream.next();
35012
+ stream.start = stream.pos;
35013
+ stream.eatWhile(reWord);
35014
+ result.push({
35015
+ name: attrName,
35016
+ value: stream.current()
35017
+ });
35018
+ break;
35019
+ case '[': //begin attribute set
35020
+ if (nameEnd === null)
35021
+ nameEnd = stream.pos;
35022
+
35023
+ stream.start = stream.pos;
35024
+ if (!stream.skipToPair('[', ']')) {
35025
+ throw new Error('Invalid attribute set definition');
35026
+ }
35027
+
35028
+ result = result.concat(
35029
+ extractAttributes(stripped(stream.current()))
35030
+ );
35031
+ break;
35032
+ default:
35033
+ stream.next();
35034
+ }
35035
+ }
35036
+
35037
+ if (!result.length)
35038
+ return null;
35039
+
35040
+ return {
35041
+ element: abbr.substring(0, nameEnd),
35042
+ attributes: optimizeAttributes(result)
35043
+ };
35044
+ }
35045
+
35046
+ /**
35047
+ * Optimize attribute set: remove duplicates and merge class attributes
35048
+ * @param attrs
35049
+ */
35050
+ function optimizeAttributes(attrs) {
35051
+ // clone all attributes to make sure that original objects are
35052
+ // not modified
35053
+ attrs = attrs.map(function(attr) {
35054
+ return utils.clone(attr);
35055
+ });
35056
+
35057
+ var lookup = {};
35058
+
35059
+ return attrs.filter(function(attr) {
35060
+ if (!(attr.name in lookup)) {
35061
+ return lookup[attr.name] = attr;
35062
+ }
35063
+
35064
+ var la = lookup[attr.name];
35065
+
35066
+ if (attr.name.toLowerCase() == 'class') {
35067
+ la.value += (la.value.length ? ' ' : '') + attr.value;
35068
+ } else {
35069
+ la.value = attr.value;
35070
+ la.isImplied = !!attr.isImplied;
35071
+ }
35072
+
35073
+ return false;
35074
+ });
35075
+ }
35076
+
35077
+ /**
35078
+ * Extract text data from abbreviation: if <code>a{hello}</code> abbreviation
35079
+ * is passed, returns object <code>{element: 'a', text: 'hello'}</code>.
35080
+ * If nothing found, returns <code>null</code>
35081
+ * @param {String} abbr
35082
+ *
35083
+ */
35084
+ function extractText(abbr) {
35085
+ if (!~abbr.indexOf('{'))
35086
+ return null;
35087
+
35088
+ /** @type StringStream */
35089
+ var stream = stringStream.create(abbr);
35090
+ while (!stream.eol()) {
35091
+ switch (stream.peek()) {
35092
+ case '[':
35093
+ case '(':
35094
+ stream.skipToPair(stream.peek(), pairs[stream.peek()]); break;
35095
+
35096
+ case '{':
35097
+ stream.start = stream.pos;
35098
+ stream.skipToPair('{', '}');
35099
+ return {
35100
+ element: abbr.substring(0, stream.start),
35101
+ text: stripped(stream.current())
35102
+ };
35103
+
35104
+ default:
35105
+ stream.next();
35106
+ }
35107
+ }
35108
+ }
35109
+
35110
+ /**
35111
+ * “Un-rolls“ contents of current node: recursively replaces all repeating
35112
+ * children with their repeated clones
35113
+ * @param {AbbreviationNode} node
35114
+ * @returns {AbbreviationNode}
35115
+ */
35116
+ function unroll(node) {
35117
+ for (var i = node.children.length - 1, j, child, maxCount; i >= 0; i--) {
35118
+ child = node.children[i];
35119
+
35120
+ if (child.isRepeating()) {
35121
+ maxCount = j = child.repeatCount;
35122
+ child.repeatCount = 1;
35123
+ child.updateProperty('counter', 1);
35124
+ child.updateProperty('maxCount', maxCount);
35125
+ while (--j > 0) {
35126
+ child.parent.addChild(child.clone(), i + 1)
35127
+ .updateProperty('counter', j + 1)
35128
+ .updateProperty('maxCount', maxCount);
35129
+ }
35130
+ }
35131
+ }
35132
+
35133
+ // to keep proper 'counter' property, we need to walk
35134
+ // on children once again
35135
+ node.children.forEach(unroll);
35136
+
35137
+ return node;
35138
+ }
35139
+
35140
+ /**
35141
+ * Optimizes tree node: replaces empty nodes with their children
35142
+ * @param {AbbreviationNode} node
35143
+ * @return {AbbreviationNode}
35144
+ */
35145
+ function squash(node) {
35146
+ for (var i = node.children.length - 1; i >= 0; i--) {
35147
+ /** @type AbbreviationNode */
35148
+ var n = node.children[i];
35149
+ if (n.isGroup()) {
35150
+ n.replace(squash(n).children);
35151
+ } else if (n.isEmpty()) {
35152
+ n.remove();
35153
+ }
35154
+ }
35155
+
35156
+ node.children.forEach(squash);
35157
+
35158
+ return node;
35159
+ }
35160
+
35161
+ function isAllowedChar(ch) {
35162
+ var charCode = ch.charCodeAt(0);
35163
+ var specialChars = '#.*:$-_!@|%';
35164
+
35165
+ return (charCode > 64 && charCode < 91) // uppercase letter
35166
+ || (charCode > 96 && charCode < 123) // lowercase letter
35167
+ || (charCode > 47 && charCode < 58) // number
35168
+ || specialChars.indexOf(ch) != -1; // special character
35169
+ }
35170
+
35171
+ // XXX add counter replacer function as output processor
35172
+ outputProcessors.push(function(text, node) {
35173
+ return utils.replaceCounter(text, node.counter, node.maxCount);
35174
+ });
35175
+
35176
+ // XXX add tabstop updater
35177
+ outputProcessors.push(tabStops.abbrOutputProcessor.bind(tabStops));
35178
+
35179
+ // include default pre- and postprocessors
35180
+ [lorem, procResourceMatcher, procAttributes, procPastedContent, procTagName, procHref].forEach(function(mod) {
35181
+ if (mod.preprocessor) {
35182
+ preprocessors.push(mod.preprocessor.bind(mod));
35183
+ }
35184
+
35185
+ if (mod.postprocessor) {
35186
+ postprocessors.push(mod.postprocessor.bind(mod));
35187
+ }
35188
+ });
35189
+
35190
+ return {
35191
+ DEFAULT_ATTR_NAME: DEFAULT_ATTR_NAME,
35192
+
35193
+ /**
35194
+ * Parses abbreviation into tree with respect of groups,
35195
+ * text nodes and attributes. Each node of the tree is a single
35196
+ * abbreviation. Tree represents actual structure of the outputted
35197
+ * result
35198
+ * @memberOf abbreviationParser
35199
+ * @param {String} abbr Abbreviation to parse
35200
+ * @param {Object} options Additional options for parser and processors
35201
+ *
35202
+ * @return {AbbreviationNode}
35203
+ */
35204
+ parse: function(abbr, options) {
35205
+ options = options || {};
35206
+
35207
+ var tree = parseAbbreviation(abbr);
35208
+ var that = this;
35209
+
35210
+ if (options.contextNode) {
35211
+ // add info about context node –
35212
+ // a parent XHTML node in editor inside which abbreviation is
35213
+ // expanded
35214
+ tree._name = options.contextNode.name;
35215
+ var attrLookup = {};
35216
+ tree._attributes.forEach(function(attr) {
35217
+ attrLookup[attr.name] = attr;
35218
+ });
35219
+
35220
+ options.contextNode.attributes.forEach(function(attr) {
35221
+ if (attr.name in attrLookup) {
35222
+ attrLookup[attr.name].value = attr.value;
35223
+ } else {
35224
+ attr = utils.clone(attr);
35225
+ tree._attributes.push(attr);
35226
+ attrLookup[attr.name] = attr;
35227
+ }
35228
+ });
35229
+ }
35230
+
35231
+ // apply preprocessors
35232
+ preprocessors.forEach(function(fn) {
35233
+ fn(tree, options, that);
35234
+ });
35235
+
35236
+ if ('counter' in options) {
35237
+ tree.updateProperty('counter', options.counter);
35238
+ }
35239
+
35240
+ tree = squash(unroll(tree));
35241
+
35242
+ // apply postprocessors
35243
+ postprocessors.forEach(function(fn) {
35244
+ fn(tree, options, that);
35245
+ });
35246
+
35247
+ return tree;
35248
+ },
35249
+
35250
+ /**
35251
+ * Expands given abbreviation into a formatted code structure.
35252
+ * This is the main method that is used for expanding abbreviation
35253
+ * @param {String} abbr Abbreviation to expand
35254
+ * @param {Options} options Additional options for abbreviation
35255
+ * expanding and transformation: `syntax`, `profile`, `contextNode` etc.
35256
+ * @return {String}
35257
+ */
35258
+ expand: function(abbr, options) {
35259
+ if (!abbr) return '';
35260
+ if (typeof options == 'string') {
35261
+ throw new Error('Deprecated use of `expand` method: `options` must be object');
35262
+ }
35263
+
35264
+ options = options || {};
35265
+
35266
+ if (!options.syntax) {
35267
+ options.syntax = utils.defaultSyntax();
35268
+ }
35269
+
35270
+ var p = profile.get(options.profile, options.syntax);
35271
+ tabStops.resetTabstopIndex();
35272
+
35273
+ var data = filters.extract(abbr);
35274
+ var outputTree = this.parse(data[0], options);
35275
+
35276
+ var filtersList = filters.composeList(options.syntax, p, data[1]);
35277
+ filters.apply(outputTree, filtersList, p);
35278
+
35279
+ return outputTree.valueOf();
35280
+ },
35281
+
35282
+ AbbreviationNode: AbbreviationNode,
35283
+
35284
+ /**
35285
+ * Add new abbreviation preprocessor. <i>Preprocessor</i> is a function
35286
+ * that applies to a parsed abbreviation tree right after it get parsed.
35287
+ * The passed tree is in unoptimized state.
35288
+ * @param {Function} fn Preprocessor function. This function receives
35289
+ * two arguments: parsed abbreviation tree (<code>AbbreviationNode</code>)
35290
+ * and <code>options</code> hash that was passed to <code>parse</code>
35291
+ * method
35292
+ */
35293
+ addPreprocessor: function(fn) {
35294
+ if (!~preprocessors.indexOf(fn)) {
35295
+ preprocessors.push(fn);
35296
+ }
35297
+ },
35298
+
35299
+ /**
35300
+ * Removes registered preprocessor
35301
+ */
35302
+ removeFilter: function(fn) {
35303
+ var ix = preprocessors.indexOf(fn);
35304
+ if (~ix) {
35305
+ preprocessors.splice(ix, 1);
35306
+ }
35307
+ },
35308
+
35309
+ /**
35310
+ * Adds new abbreviation postprocessor. <i>Postprocessor</i> is a
35311
+ * functinon that applies to <i>optimized</i> parsed abbreviation tree
35312
+ * right before it returns from <code>parse()</code> method
35313
+ * @param {Function} fn Postprocessor function. This function receives
35314
+ * two arguments: parsed abbreviation tree (<code>AbbreviationNode</code>)
35315
+ * and <code>options</code> hash that was passed to <code>parse</code>
35316
+ * method
35317
+ */
35318
+ addPostprocessor: function(fn) {
35319
+ if (!~postprocessors.indexOf(fn)) {
35320
+ postprocessors.push(fn);
35321
+ }
35322
+ },
35323
+
35324
+ /**
35325
+ * Removes registered postprocessor function
35326
+ */
35327
+ removePostprocessor: function(fn) {
35328
+ var ix = postprocessors.indexOf(fn);
35329
+ if (~ix) {
35330
+ postprocessors.splice(ix, 1);
35331
+ }
35332
+ },
35333
+
35334
+ /**
35335
+ * Registers output postprocessor. <i>Output processor</i> is a
35336
+ * function that applies to output part (<code>start</code>,
35337
+ * <code>end</code> and <code>content</code>) when
35338
+ * <code>AbbreviationNode.toString()</code> method is called
35339
+ */
35340
+ addOutputProcessor: function(fn) {
35341
+ if (!~outputProcessors.indexOf(fn)) {
35342
+ outputProcessors.push(fn);
35343
+ }
35344
+ },
35345
+
35346
+ /**
35347
+ * Removes registered output processor
35348
+ */
35349
+ removeOutputProcessor: function(fn) {
35350
+ var ix = outputProcessors.indexOf(fn);
35351
+ if (~ix) {
35352
+ outputProcessors.splice(ix, 1);
35353
+ }
35354
+ },
35355
+
35356
+ /**
35357
+ * Check if passed symbol is valid symbol for abbreviation expression
35358
+ * @param {String} ch
35359
+ * @return {Boolean}
35360
+ */
35361
+ isAllowedChar: function(ch) {
35362
+ ch = String(ch); // convert Java object to JS
35363
+ return isAllowedChar(ch) || ~'>+^[](){}'.indexOf(ch);
35364
+ }
35365
+ };
35366
+ });
35367
+ },{"../assets/profile":29,"../assets/stringStream":32,"../assets/tabStops":33,"../filter/main":49,"../generator/lorem":54,"../utils/abbreviation":69,"../utils/common":73,"./processor/attributes":57,"./processor/href":58,"./processor/pastedContent":59,"./processor/resourceMatcher":60,"./processor/tagName":61}],56:[function(require,module,exports){
35368
+ if (typeof module === 'object' && typeof define !== 'function') {
35369
+ var define = function (factory) {
35370
+ module.exports = factory(require, exports, module);
35371
+ };
35372
+ }
35373
+
35374
+ define(function(require, exports, module) {
35375
+ var session = {tokens: null};
35376
+
35377
+ // walks around the source
35378
+ var walker = {
35379
+ init: function (source) {
35380
+ // this.source = source.replace(/\r\n?/g, '\n');
35381
+ this.source = source;
35382
+ this.ch = '';
35383
+ this.chnum = -1;
35384
+
35385
+ // advance
35386
+ this.nextChar();
35387
+ },
35388
+ nextChar: function () {
35389
+ return this.ch = this.source.charAt(++this.chnum);
35390
+ },
35391
+ peek: function() {
35392
+ return this.source.charAt(this.chnum + 1);
35393
+ }
35394
+ };
35395
+
35396
+ // utility helpers
35397
+ function isNameChar(c, cc) {
35398
+ cc = cc || c.charCodeAt(0);
35399
+ return (
35400
+ (cc >= 97 && cc <= 122 /* a-z */) ||
35401
+ (cc >= 65 && cc <= 90 /* A-Z */) ||
35402
+ /*
35403
+ Experimental: include cyrillic ranges
35404
+ since some letters, similar to latin ones, can
35405
+ accidentally appear in CSS tokens
35406
+ */
35407
+ (cc >= 1024 && cc <= 1279) ||
35408
+ c === '&' || /* selector placeholder (LESS, SCSS) */
35409
+ c === '_' ||
35410
+ c === '<' || /* comparisons (LESS, SCSS) */
35411
+ c === '>' ||
35412
+ c === '=' ||
35413
+ c === '-'
35414
+ );
35415
+ }
35416
+
35417
+ function isDigit(c, cc) {
35418
+ cc = cc || c.charCodeAt(0);
35419
+ return (cc >= 48 && cc <= 57);
35420
+ }
35421
+
35422
+ var isOp = (function () {
35423
+ var opsa = "{}[]()+*=.,;:>~|\\%$#@^!".split(''),
35424
+ opsmatcha = "*^|$~".split(''),
35425
+ ops = {},
35426
+ opsmatch = {},
35427
+ i = 0;
35428
+ for (; i < opsa.length; i += 1) {
35429
+ ops[opsa[i]] = true;
35430
+ }
35431
+ for (i = 0; i < opsmatcha.length; i += 1) {
35432
+ opsmatch[opsmatcha[i]] = true;
35433
+ }
35434
+ return function (ch, matchattr) {
35435
+ if (matchattr) {
35436
+ return ch in opsmatch;
35437
+ }
35438
+ return ch in ops;
35439
+ };
35440
+ }());
35441
+
35442
+ // creates token objects and pushes them to a list
35443
+ function tokener(value, type) {
35444
+ session.tokens.push({
35445
+ value: value,
35446
+ type: type || value,
35447
+ start: null,
35448
+ end: null
35449
+ });
35450
+ }
35451
+
35452
+ function getPosInfo(w) {
35453
+ var errPos = w.chnum;
35454
+ var source = w.source.replace(/\r\n?/g, '\n');
35455
+ var part = w.source.substring(0, errPos + 1).replace(/\r\n?/g, '\n');
35456
+ var lines = part.split('\n');
35457
+ var ch = (lines[lines.length - 1] || '').length;
35458
+ var fullLine = source.split('\n')[lines.length - 1] || '';
35459
+
35460
+ var chunkSize = 100;
35461
+ var offset = Math.max(0, ch - chunkSize);
35462
+ var formattedLine = fullLine.substr(offset, chunkSize * 2) + '\n';
35463
+ for (var i = 0; i < ch - offset - 1; i++) {
35464
+ formattedLine += '-';
35465
+ }
35466
+ formattedLine += '^';
35467
+
35468
+ return {
35469
+ line: lines.length,
35470
+ ch: ch,
35471
+ text: fullLine,
35472
+ hint: formattedLine
35473
+ };
35474
+ }
35475
+
35476
+ function raiseError(message) {
35477
+ var err = error(message);
35478
+ var errObj = new Error(err.message, '', err.line);
35479
+ errObj.line = err.line;
35480
+ errObj.ch = err.ch;
35481
+ errObj.name = err.name;
35482
+ errObj.hint = err.hint;
35483
+
35484
+ throw errObj;
35485
+ }
35486
+
35487
+ // oops
35488
+ function error(m) {
35489
+ var w = walker;
35490
+ var info = getPosInfo(walker);
35491
+ var tokens = session.tokens;
35492
+ session.tokens = null;
35493
+
35494
+ var message = 'CSS parsing error at line ' + info.line + ', char ' + info.ch + ': ' + m;
35495
+ message += '\n' + info.hint;
35496
+ return {
35497
+ name: "ParseError",
35498
+ message: message,
35499
+ hint: info.hint,
35500
+ line: info.line,
35501
+ ch: info.ch
35502
+ };
35503
+ }
35504
+
35505
+
35506
+ // token handlers follow for:
35507
+ // white space, comment, string, identifier, number, operator
35508
+ function white() {
35509
+ var c = walker.ch,
35510
+ token = '';
35511
+
35512
+ while (c === " " || c === "\t") {
35513
+ token += c;
35514
+ c = walker.nextChar();
35515
+ }
35516
+
35517
+ tokener(token, 'white');
35518
+
35519
+ }
35520
+
35521
+ function comment() {
35522
+ var w = walker,
35523
+ c = w.ch,
35524
+ token = c,
35525
+ cnext;
35526
+
35527
+ cnext = w.nextChar();
35528
+
35529
+ if (cnext === '/') {
35530
+ // inline comment in SCSS and LESS
35531
+ while (c && !(cnext === "\n" || cnext === "\r")) {
35532
+ token += cnext;
35533
+ c = cnext;
35534
+ cnext = w.nextChar();
35535
+ }
35536
+ } else if (cnext === '*') {
35537
+ // multiline CSS commment
35538
+ while (c && !(c === "*" && cnext === "/")) {
35539
+ token += cnext;
35540
+ c = cnext;
35541
+ cnext = w.nextChar();
35542
+ }
35543
+ } else {
35544
+ // oops, not a comment, just a /
35545
+ return tokener(token, token);
35546
+ }
35547
+
35548
+ token += cnext;
35549
+ w.nextChar();
35550
+ tokener(token, 'comment');
35551
+ }
35552
+
35553
+ function eatString() {
35554
+ var w = walker,
35555
+ c = w.ch,
35556
+ q = c,
35557
+ token = c,
35558
+ cnext;
35559
+
35560
+ c = w.nextChar();
35561
+
35562
+ while (c !== q) {
35563
+ if (c === '\n') {
35564
+ cnext = w.nextChar();
35565
+ if (cnext === "\\") {
35566
+ token += c + cnext;
35567
+ } else {
35568
+ // end of line with no \ escape = bad
35569
+ raiseError("Unterminated string");
35570
+ }
35571
+ } else {
35572
+ if (c === "\\") {
35573
+ token += c + w.nextChar();
35574
+ } else {
35575
+ token += c;
35576
+ }
35577
+ }
35578
+
35579
+ c = w.nextChar();
35580
+ }
35581
+
35582
+ token += c;
35583
+
35584
+ return token;
35585
+ }
35586
+
35587
+ function str() {
35588
+ var token = eatString();
35589
+ walker.nextChar();
35590
+ tokener(token, 'string');
35591
+ }
35592
+
35593
+ function brace() {
35594
+ var w = walker,
35595
+ c = w.ch,
35596
+ depth = 1,
35597
+ token = c,
35598
+ stop = false;
35599
+
35600
+ c = w.nextChar();
35601
+
35602
+ while (c && !stop) {
35603
+ if (c === '(') {
35604
+ depth++;
35605
+ } else if (c === ')') {
35606
+ depth--;
35607
+ if (!depth) {
35608
+ stop = true;
35609
+ }
35610
+ } else if (c === '"' || c === "'") {
35611
+ c = eatString();
35612
+ } else if (c === '') {
35613
+ raiseError("Unterminated brace");
35614
+ }
35615
+
35616
+ token += c;
35617
+ c = w.nextChar();
35618
+ }
35619
+
35620
+ tokener(token, 'brace');
35621
+ }
35622
+
35623
+ function identifier(pre) {
35624
+ var c = walker.ch;
35625
+ var token = pre ? pre + c : c;
35626
+
35627
+ c = walker.nextChar();
35628
+ var cc = c.charCodeAt(0);
35629
+ while (isNameChar(c, cc) || isDigit(c, cc)) {
35630
+ token += c;
35631
+ c = walker.nextChar();
35632
+ cc = c.charCodeAt(0);
35633
+ }
35634
+
35635
+ tokener(token, 'identifier');
35636
+ }
35637
+
35638
+ function num() {
35639
+ var w = walker,
35640
+ c = w.ch,
35641
+ token = c,
35642
+ point = token === '.',
35643
+ nondigit;
35644
+
35645
+ c = w.nextChar();
35646
+ nondigit = !isDigit(c);
35647
+
35648
+ // .2px or .classname?
35649
+ if (point && nondigit) {
35650
+ // meh, NaN, could be a class name, so it's an operator for now
35651
+ return tokener(token, '.');
35652
+ }
35653
+
35654
+ // -2px or -moz-something
35655
+ if (token === '-' && nondigit) {
35656
+ return identifier('-');
35657
+ }
35658
+
35659
+ while (c !== '' && (isDigit(c) || (!point && c === '.'))) { // not end of source && digit or first instance of .
35660
+ if (c === '.') {
35661
+ point = true;
35662
+ }
35663
+ token += c;
35664
+ c = w.nextChar();
35665
+ }
35666
+
35667
+ tokener(token, 'number');
35668
+
35669
+ }
35670
+
35671
+ function op() {
35672
+ var w = walker,
35673
+ c = w.ch,
35674
+ token = c,
35675
+ next = w.nextChar();
35676
+
35677
+ if (next === "=" && isOp(token, true)) {
35678
+ token += next;
35679
+ tokener(token, 'match');
35680
+ w.nextChar();
35681
+ return;
35682
+ }
35683
+
35684
+ tokener(token, token);
35685
+ }
35686
+
35687
+
35688
+ // call the appropriate handler based on the first character in a token suspect
35689
+ function tokenize() {
35690
+ var ch = walker.ch;
35691
+
35692
+ if (ch === " " || ch === "\t") {
35693
+ return white();
35694
+ }
35695
+
35696
+ if (ch === '/') {
35697
+ return comment();
35698
+ }
35699
+
35700
+ if (ch === '"' || ch === "'") {
35701
+ return str();
35702
+ }
35703
+
35704
+ if (ch === '(') {
35705
+ return brace();
35706
+ }
35707
+
35708
+ if (ch === '-' || ch === '.' || isDigit(ch)) { // tricky - char: minus (-1px) or dash (-moz-stuff)
35709
+ return num();
35710
+ }
35711
+
35712
+ if (isNameChar(ch)) {
35713
+ return identifier();
35714
+ }
35715
+
35716
+ if (isOp(ch)) {
35717
+ return op();
35718
+ }
35719
+
35720
+ if (ch === '\r') {
35721
+ if (walker.peek() === '\n') {
35722
+ ch += walker.nextChar();
35723
+ }
35724
+
35725
+ tokener(ch, 'line');
35726
+ walker.nextChar();
35727
+ return;
35728
+ }
35729
+
35730
+ if (ch === '\n') {
35731
+ tokener(ch, 'line');
35732
+ walker.nextChar();
35733
+ return;
35734
+ }
35735
+
35736
+ raiseError("Unrecognized character '" + ch + "'");
35737
+ }
35738
+
35739
+ return {
35740
+ /**
35741
+ * Sprits given source into tokens
35742
+ * @param {String} source
35743
+ * @returns {Array}
35744
+ */
35745
+ lex: function (source) {
35746
+ walker.init(source);
35747
+ session.tokens = [];
35748
+
35749
+ // for empty source, return single space token
35750
+ if (!source) {
35751
+ session.tokens.push(this.white());
35752
+ } else {
35753
+ while (walker.ch !== '') {
35754
+ tokenize();
35755
+ }
35756
+ }
35757
+
35758
+ var tokens = session.tokens;
35759
+ session.tokens = null;
35760
+ return tokens;
35761
+ },
35762
+
35763
+ /**
35764
+ * Tokenizes CSS source. It's like `lex()` method,
35765
+ * but also stores proper token indexes in source,
35766
+ * so it's a bit slower
35767
+ * @param {String} source
35768
+ * @returns {Array}
35769
+ */
35770
+ parse: function(source) {
35771
+ // transform tokens
35772
+ var tokens = this.lex(source), pos = 0, token;
35773
+ for (var i = 0, il = tokens.length; i < il; i++) {
35774
+ token = tokens[i];
35775
+ token.start = pos;
35776
+ token.end = (pos += token.value.length);
35777
+ }
35778
+ return tokens;
35779
+ },
35780
+
35781
+ white: function() {
35782
+ return {
35783
+ value: '',
35784
+ type: 'white',
35785
+ start: 0,
35786
+ end: 0
35787
+ };
35788
+ },
35789
+
35790
+ toSource: function(toks) {
35791
+ var i = 0, max = toks.length, src = '';
35792
+ for (; i < max; i++) {
35793
+ src += toks[i].value;
35794
+ }
35795
+ return src;
35796
+ }
35797
+ };
35798
+ });
35799
+ },{}],57:[function(require,module,exports){
35800
+ /**
35801
+ * Resolves node attribute names: moves `default` attribute value
35802
+ * from stub to real attribute.
35803
+ *
35804
+ * This resolver should be applied *after* resource matcher
35805
+ */
35806
+ if (typeof module === 'object' && typeof define !== 'function') {
35807
+ var define = function (factory) {
35808
+ module.exports = factory(require, exports, module);
35809
+ };
35810
+ }
35811
+
35812
+ define(function(require, exports, module) {
35813
+ var utils = require('../../utils/common');
35814
+
35815
+ var findDefault = function(attr) {
35816
+ return attr.isDefault;
35817
+ };
35818
+
35819
+ var findImplied = function(attr) {
35820
+ return attr.isImplied;
35821
+ };
35822
+
35823
+ var findEmpty = function(attr) {
35824
+ return !attr.value;
35825
+ };
35826
+
35827
+ function resolveDefaultAttrs(node, parser) {
35828
+ node.children.forEach(function(item) {
35829
+ var attrList = item.attributeList();
35830
+ var defaultAttrValue = item.attribute(parser.DEFAULT_ATTR_NAME);
35831
+ if (typeof defaultAttrValue !== 'undefined') {
35832
+ // remove stub attribute
35833
+ item.attribute(parser.DEFAULT_ATTR_NAME, null);
35834
+
35835
+ if (attrList.length) {
35836
+ // target for default value:
35837
+ // 1. default attribute
35838
+ // 2. implied attribute
35839
+ // 3. first empty attribute
35840
+
35841
+ // find attribute marked as default
35842
+ var defaultAttr = utils.find(attrList, findDefault)
35843
+ || utils.find(attrList, findImplied)
35844
+ || utils.find(attrList, findEmpty);
35845
+
35846
+ if (defaultAttr) {
35847
+ var oldVal = item.attribute(defaultAttr.name);
35848
+ var newVal = utils.replaceUnescapedSymbol(oldVal, '|', defaultAttrValue);
35849
+ // no replacement, e.g. default value does not contains | symbol
35850
+ if (oldVal == newVal) {
35851
+ newVal = defaultAttrValue
35852
+ }
35853
+
35854
+ item.attribute(defaultAttr.name, newVal);
35855
+ }
35856
+ }
35857
+ } else {
35858
+ // if no default attribute value, remove implied attributes
35859
+ attrList.forEach(function(attr) {
35860
+ if (attr.isImplied) {
35861
+ item.attribute(attr.name, null);
35862
+ }
35863
+ });
35864
+ }
35865
+
35866
+ resolveDefaultAttrs(item, parser);
35867
+ });
35868
+ }
35869
+
35870
+ return {
35871
+ /**
35872
+ * @param {AbbreviationNode} tree
35873
+ * @param {Object} options
35874
+ * @param {abbreviation} parser
35875
+ */
35876
+ preprocessor: function(tree, options, parser) {
35877
+ resolveDefaultAttrs(tree, parser);
35878
+ }
35879
+ };
35880
+ });
35881
+ },{"../../utils/common":73}],58:[function(require,module,exports){
35882
+ /**
35883
+ * A preptocessor for &lt;a&gt; tag: tests wrapped content
35884
+ * for common URL patterns and, if matched, inserts it as
35885
+ * `href` attribute
35886
+ */
35887
+ if (typeof module === 'object' && typeof define !== 'function') {
35888
+ var define = function (factory) {
35889
+ module.exports = factory(require, exports, module);
35890
+ };
35891
+ }
35892
+
35893
+ define(function(require, exports, module) {
35894
+ var prefs = require('../../assets/preferences');
35895
+ var utils = require('../../utils/common');
35896
+ var pc = require('./pastedContent');
35897
+
35898
+ prefs.define('href.autodetect', true,
35899
+ 'Enables or disables automatic URL recognition when wrapping\
35900
+ text with <code>&lt;a&gt;</code> tag. With this option enabled,\
35901
+ if wrapped text matches URL or e-mail pattern it will be automatically\
35902
+ inserted into <code>href</code> attribute.');
35903
+ prefs.define('href.urlPattern', '^(?:(?:https?|ftp|file)://|www\\.|ftp\\.)(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[A-Z0-9+&@#/%=~_|$])',
35904
+ 'RegExp pattern to match wrapped URLs. Matched content will be inserts\
35905
+ as-is into <code>href</code> attribute, only whitespace will be trimmed.');
35906
+
35907
+ prefs.define('href.emailPattern', '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,5}$',
35908
+ 'RegExp pattern to match wrapped e-mails. Unlike <code>href.urlPattern</code>,\
35909
+ wrapped content will be prefixed with <code>mailto:</code> in <code>href</code>\
35910
+ attribute');
35911
+
35912
+ return {
35913
+ /**
35914
+ * @param {AbbreviationNode} tree
35915
+ * @param {Object} options
35916
+ */
35917
+ postprocessor: function(tree, options) {
35918
+ if (!prefs.get('href.autodetect')) {
35919
+ return;
35920
+ }
35921
+
35922
+ var reUrl = new RegExp(prefs.get('href.urlPattern'), 'i');
35923
+ var reEmail = new RegExp(prefs.get('href.emailPattern'), 'i');
35924
+ var reProto = /^([a-z]+:)?\/\//i;
35925
+
35926
+ tree.findAll(function(item) {
35927
+ if (item.name().toLowerCase() != 'a' || item.attribute('href')) {
35928
+ return;
35929
+ }
35930
+
35931
+ var pastedContent = utils.trim(pc.pastedContent(item) || options.pastedContent);
35932
+ if (pastedContent) {
35933
+ if (reUrl.test(pastedContent)) {
35934
+ // do we have protocol?
35935
+ if (!reProto.test(pastedContent)) {
35936
+ pastedContent = 'http://' + pastedContent;
35937
+ }
35938
+
35939
+ item.attribute('href', pastedContent);
35940
+ } else if (reEmail.test(pastedContent)) {
35941
+ item.attribute('href', 'mailto:' + pastedContent);
35942
+ }
35943
+ }
35944
+ });
35945
+ }
35946
+ };
35947
+ });
35948
+ },{"../../assets/preferences":28,"../../utils/common":73,"./pastedContent":59}],59:[function(require,module,exports){
35949
+ /**
35950
+ * Pasted content abbreviation processor. A pasted content is a content that
35951
+ * should be inserted into implicitly repeated abbreviation nodes.
35952
+ * This processor powers “Wrap With Abbreviation” action
35953
+ */
35954
+ if (typeof module === 'object' && typeof define !== 'function') {
35955
+ var define = function (factory) {
35956
+ module.exports = factory(require, exports, module);
35957
+ };
35958
+ }
35959
+
35960
+ define(function(require, exports, module) {
35961
+ var utils = require('../../utils/common');
35962
+ var abbrUtils = require('../../utils/abbreviation');
35963
+ var stringStream = require('../../assets/stringStream');
35964
+ var range = require('../../assets/range');
35965
+
35966
+ var outputPlaceholder = '$#';
35967
+
35968
+ /**
35969
+ * Locates output placeholders inside text
35970
+ * @param {String} text
35971
+ * @returns {Array} Array of ranges of output placeholder in text
35972
+ */
35973
+ function locateOutputPlaceholder(text) {
35974
+ var result = [];
35975
+
35976
+ var stream = stringStream.create(text);
35977
+
35978
+ while (!stream.eol()) {
35979
+ if (stream.peek() == '\\') {
35980
+ stream.next();
35981
+ } else {
35982
+ stream.start = stream.pos;
35983
+ if (stream.match(outputPlaceholder, true)) {
35984
+ result.push(range.create(stream.start, outputPlaceholder));
35985
+ continue;
35986
+ }
35987
+ }
35988
+ stream.next();
35989
+ }
35990
+
35991
+ return result;
35992
+ }
35993
+
35994
+ /**
35995
+ * Replaces output placeholders inside <code>source</code> with
35996
+ * <code>value</code>
35997
+ * @param {String} source
35998
+ * @param {String} value
35999
+ * @returns {String}
36000
+ */
36001
+ function replaceOutputPlaceholders(source, value) {
36002
+ var ranges = locateOutputPlaceholder(source);
36003
+
36004
+ ranges.reverse().forEach(function(r) {
36005
+ source = utils.replaceSubstring(source, value, r);
36006
+ });
36007
+
36008
+ return source;
36009
+ }
36010
+
36011
+ /**
36012
+ * Check if parsed node contains output placeholder – a target where
36013
+ * pasted content should be inserted
36014
+ * @param {AbbreviationNode} node
36015
+ * @returns {Boolean}
36016
+ */
36017
+ function hasOutputPlaceholder(node) {
36018
+ if (locateOutputPlaceholder(node.content).length)
36019
+ return true;
36020
+
36021
+ // check if attributes contains placeholder
36022
+ return !!utils.find(node.attributeList(), function(attr) {
36023
+ return !!locateOutputPlaceholder(attr.value).length;
36024
+ });
36025
+ }
36026
+
36027
+ /**
36028
+ * Insert pasted content into correct positions of parsed node
36029
+ * @param {AbbreviationNode} node
36030
+ * @param {String} content
36031
+ * @param {Boolean} overwrite Overwrite node content if no value placeholders
36032
+ * found instead of appending to existing content
36033
+ */
36034
+ function insertPastedContent(node, content, overwrite) {
36035
+ var nodesWithPlaceholders = node.findAll(function(item) {
36036
+ return hasOutputPlaceholder(item);
36037
+ });
36038
+
36039
+ if (hasOutputPlaceholder(node))
36040
+ nodesWithPlaceholders.unshift(node);
36041
+
36042
+ if (nodesWithPlaceholders.length) {
36043
+ nodesWithPlaceholders.forEach(function(item) {
36044
+ item.content = replaceOutputPlaceholders(item.content, content);
36045
+ item._attributes.forEach(function(attr) {
36046
+ attr.value = replaceOutputPlaceholders(attr.value, content);
36047
+ });
36048
+ });
36049
+ } else {
36050
+ // on output placeholders in subtree, insert content in the deepest
36051
+ // child node
36052
+ var deepest = node.deepestChild() || node;
36053
+ if (overwrite) {
36054
+ deepest.content = content;
36055
+ } else {
36056
+ deepest.content = abbrUtils.insertChildContent(deepest.content, content);
36057
+ }
36058
+ }
36059
+ }
36060
+
36061
+ return {
36062
+ pastedContent: function(item) {
36063
+ var content = item.data('paste');
36064
+ if (Array.isArray(content)) {
36065
+ return content[item.counter - 1];
36066
+ } else if (typeof content === 'function') {
36067
+ return content(item.counter - 1, item.content);
36068
+ } else if (content) {
36069
+ return content;
36070
+ }
36071
+ },
36072
+
36073
+ /**
36074
+ * @param {AbbreviationNode} tree
36075
+ * @param {Object} options
36076
+ */
36077
+ preprocessor: function(tree, options) {
36078
+ if (options.pastedContent) {
36079
+ var lines = utils.splitByLines(options.pastedContent, true).map(utils.trim);
36080
+
36081
+ // set repeat count for implicitly repeated elements before
36082
+ // tree is unrolled
36083
+ tree.findAll(function(item) {
36084
+ if (item.hasImplicitRepeat) {
36085
+ item.data('paste', lines);
36086
+ return item.repeatCount = lines.length;
36087
+ }
36088
+ });
36089
+ }
36090
+ },
36091
+
36092
+ /**
36093
+ * @param {AbbreviationNode} tree
36094
+ * @param {Object} options
36095
+ */
36096
+ postprocessor: function(tree, options) {
36097
+ var that = this;
36098
+ // for each node with pasted content, update text data
36099
+ var targets = tree.findAll(function(item) {
36100
+ var pastedContent = that.pastedContent(item);
36101
+ if (pastedContent) {
36102
+ insertPastedContent(item, pastedContent, !!item.data('pasteOverwrites'));
36103
+ }
36104
+
36105
+ return !!pastedContent;
36106
+ });
36107
+
36108
+ if (!targets.length && options.pastedContent) {
36109
+ // no implicitly repeated elements, put pasted content in
36110
+ // the deepest child
36111
+ insertPastedContent(tree, options.pastedContent);
36112
+ }
36113
+ }
36114
+ };
36115
+ });
36116
+ },{"../../assets/range":30,"../../assets/stringStream":32,"../../utils/abbreviation":69,"../../utils/common":73}],60:[function(require,module,exports){
36117
+ /**
36118
+ * Processor function that matches parsed <code>AbbreviationNode</code>
36119
+ * against resources defined in <code>resource</code> module
36120
+ */
36121
+ if (typeof module === 'object' && typeof define !== 'function') {
36122
+ var define = function (factory) {
36123
+ module.exports = factory(require, exports, module);
36124
+ };
36125
+ }
36126
+
36127
+ define(function(require, exports, module) {
36128
+ var resources = require('../../assets/resources');
36129
+ var elements = require('../../assets/elements');
36130
+ var utils = require('../../utils/common');
36131
+ var abbreviationUtils = require('../../utils/abbreviation');
36132
+
36133
+ /**
36134
+ * Finds matched resources for child nodes of passed <code>node</code>
36135
+ * element. A matched resource is a reference to <i>snippets.json</i> entry
36136
+ * that describes output of parsed node
36137
+ * @param {AbbreviationNode} node
36138
+ * @param {String} syntax
36139
+ */
36140
+ function matchResources(node, syntax, parser) {
36141
+ // do a shallow copy because the children list can be modified during
36142
+ // resource matching
36143
+ node.children.slice(0).forEach(function(child) {
36144
+ var r = resources.getMatchedResource(child, syntax);
36145
+ if (typeof r === 'string') {
36146
+ r = elements.create('snippet', r);
36147
+ }
36148
+
36149
+ child.data('resource', r);
36150
+ var elemType = elements.type(r);
36151
+
36152
+ if (elemType == 'snippet') {
36153
+ var content = r.data;
36154
+ var curContent = child._text || child.content;
36155
+ if (curContent) {
36156
+ content = abbreviationUtils.insertChildContent(content, curContent);
36157
+ }
36158
+
36159
+ child.content = content;
36160
+ } else if (elemType == 'element') {
36161
+ child._name = r.name;
36162
+ if (Array.isArray(r.attributes)) {
36163
+ child._attributes = [].concat(r.attributes, child._attributes);
36164
+ }
36165
+ } else if (elemType == 'reference') {
36166
+ // it’s a reference to another abbreviation:
36167
+ // parse it and insert instead of current child
36168
+ /** @type AbbreviationNode */
36169
+ var subtree = parser.parse(r.data, {
36170
+ syntax: syntax
36171
+ });
36172
+
36173
+ // if context element should be repeated, check if we need to
36174
+ // transfer repeated element to specific child node
36175
+ if (child.repeatCount > 1) {
36176
+ var repeatedChildren = subtree.findAll(function(node) {
36177
+ return node.hasImplicitRepeat;
36178
+ });
36179
+
36180
+ if (!repeatedChildren.length) {
36181
+ repeatedChildren = subtree.children
36182
+ }
36183
+
36184
+ repeatedChildren.forEach(function(node) {
36185
+ node.repeatCount = child.repeatCount;
36186
+ node.hasImplicitRepeat = false;
36187
+ });
36188
+ }
36189
+
36190
+ // move child‘s children into the deepest child of new subtree
36191
+ var deepestChild = subtree.deepestChild();
36192
+ if (deepestChild) {
36193
+ child.children.forEach(function(c) {
36194
+ deepestChild.addChild(c);
36195
+ });
36196
+ deepestChild.content = child.content;
36197
+ }
36198
+
36199
+ // copy current attributes to children
36200
+ subtree.children.forEach(function(node) {
36201
+ child.attributeList().forEach(function(attr) {
36202
+ node.attribute(attr.name, attr.value);
36203
+ });
36204
+ });
36205
+
36206
+ child.replace(subtree.children);
36207
+ }
36208
+
36209
+ matchResources(child, syntax, parser);
36210
+ });
36211
+ }
36212
+
36213
+ return {
36214
+ preprocessor: function(tree, options, parser) {
36215
+ var syntax = options.syntax || utils.defaultSyntax();
36216
+ matchResources(tree, syntax, parser);
36217
+ }
36218
+ };
36219
+ });
36220
+ },{"../../assets/elements":24,"../../assets/resources":31,"../../utils/abbreviation":69,"../../utils/common":73}],61:[function(require,module,exports){
36221
+ /**
36222
+ * Resolves tag names in abbreviations with implied name
36223
+ */
36224
+ if (typeof module === 'object' && typeof define !== 'function') {
36225
+ var define = function (factory) {
36226
+ module.exports = factory(require, exports, module);
36227
+ };
36228
+ }
36229
+
36230
+ define(function(require, exports, module) {
36231
+ var tagName = require('../../resolver/tagName');
36232
+
36233
+ /**
36234
+ * Resolves implicit node names in parsed tree
36235
+ * @param {AbbreviationNode} tree
36236
+ */
36237
+ function resolveNodeNames(tree) {
36238
+ tree.children.forEach(function(node) {
36239
+ if (node.hasImplicitName() || node.data('forceNameResolving')) {
36240
+ node._name = tagName.resolve(node.parent.name());
36241
+ node.data('nameResolved', true);
36242
+ }
36243
+ resolveNodeNames(node);
36244
+ });
36245
+
36246
+ return tree;
36247
+ }
36248
+
36249
+ return {
36250
+ postprocessor: resolveNodeNames
36251
+ };
36252
+ });
36253
+ },{"../../resolver/tagName":67}],62:[function(require,module,exports){
36254
+ /**
36255
+ * HTML tokenizer by Marijn Haverbeke
36256
+ * http://codemirror.net/
36257
+ * @constructor
36258
+ * @memberOf __xmlParseDefine
36259
+ * @param {Function} require
36260
+ * @param {Underscore} _
36261
+ */
36262
+ if (typeof module === 'object' && typeof define !== 'function') {
36263
+ var define = function (factory) {
36264
+ module.exports = factory(require, exports, module);
36265
+ };
36266
+ }
36267
+
36268
+ define(function(require, exports, module) {
36269
+ var stringStream = require('../assets/stringStream');
36270
+
36271
+ var Kludges = {
36272
+ autoSelfClosers : {},
36273
+ implicitlyClosed : {},
36274
+ contextGrabbers : {},
36275
+ doNotIndent : {},
36276
+ allowUnquoted : true,
36277
+ allowMissing : true
36278
+ };
36279
+
36280
+ // Return variables for tokenizers
36281
+ var tagName = null, type = null;
36282
+
36283
+ function inText(stream, state) {
36284
+ function chain(parser) {
36285
+ state.tokenize = parser;
36286
+ return parser(stream, state);
36287
+ }
36288
+
36289
+ var ch = stream.next();
36290
+ if (ch == "<") {
36291
+ if (stream.eat("!")) {
36292
+ if (stream.eat("[")) {
36293
+ if (stream.match("CDATA["))
36294
+ return chain(inBlock("atom", "]]>"));
36295
+ else
36296
+ return null;
36297
+ } else if (stream.match("--"))
36298
+ return chain(inBlock("comment", "-->"));
36299
+ else if (stream.match("DOCTYPE", true, true)) {
36300
+ stream.eatWhile(/[\w\._\-]/);
36301
+ return chain(doctype(1));
36302
+ } else
36303
+ return null;
36304
+ } else if (stream.eat("?")) {
36305
+ stream.eatWhile(/[\w\._\-]/);
36306
+ state.tokenize = inBlock("meta", "?>");
36307
+ return "meta";
36308
+ } else {
36309
+ type = stream.eat("/") ? "closeTag" : "openTag";
36310
+ stream.eatSpace();
36311
+ tagName = "";
36312
+ var c;
36313
+ while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/)))
36314
+ tagName += c;
36315
+ state.tokenize = inTag;
36316
+ return "tag";
36317
+ }
36318
+ } else if (ch == "&") {
36319
+ var ok;
36320
+ if (stream.eat("#")) {
36321
+ if (stream.eat("x")) {
36322
+ ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
36323
+ } else {
36324
+ ok = stream.eatWhile(/[\d]/) && stream.eat(";");
36325
+ }
36326
+ } else {
36327
+ ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
36328
+ }
36329
+ return ok ? "atom" : "error";
36330
+ } else {
36331
+ stream.eatWhile(/[^&<]/);
36332
+ return "text";
36333
+ }
36334
+ }
36335
+
36336
+ function inTag(stream, state) {
36337
+ var ch = stream.next();
36338
+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
36339
+ state.tokenize = inText;
36340
+ type = ch == ">" ? "endTag" : "selfcloseTag";
36341
+ return "tag";
36342
+ } else if (ch == "=") {
36343
+ type = "equals";
36344
+ return null;
36345
+ } else if (/[\'\"]/.test(ch)) {
36346
+ state.tokenize = inAttribute(ch);
36347
+ return state.tokenize(stream, state);
36348
+ } else {
36349
+ stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
36350
+ return "word";
36351
+ }
36352
+ }
36353
+
36354
+ function inAttribute(quote) {
36355
+ return function(stream, state) {
36356
+ while (!stream.eol()) {
36357
+ if (stream.next() == quote) {
36358
+ state.tokenize = inTag;
36359
+ break;
36360
+ }
36361
+ }
36362
+ return "string";
36363
+ };
36364
+ }
36365
+
36366
+ function inBlock(style, terminator) {
36367
+ return function(stream, state) {
36368
+ while (!stream.eol()) {
36369
+ if (stream.match(terminator)) {
36370
+ state.tokenize = inText;
36371
+ break;
36372
+ }
36373
+ stream.next();
36374
+ }
36375
+ return style;
36376
+ };
36377
+ }
36378
+
36379
+ function doctype(depth) {
36380
+ return function(stream, state) {
36381
+ var ch;
36382
+ while ((ch = stream.next()) !== null) {
36383
+ if (ch == "<") {
36384
+ state.tokenize = doctype(depth + 1);
36385
+ return state.tokenize(stream, state);
36386
+ } else if (ch == ">") {
36387
+ if (depth == 1) {
36388
+ state.tokenize = inText;
36389
+ break;
36390
+ } else {
36391
+ state.tokenize = doctype(depth - 1);
36392
+ return state.tokenize(stream, state);
36393
+ }
36394
+ }
36395
+ }
36396
+ return "meta";
36397
+ };
36398
+ }
36399
+
36400
+ var curState = null, setStyle;
36401
+ function pass() {
36402
+ for (var i = arguments.length - 1; i >= 0; i--)
36403
+ curState.cc.push(arguments[i]);
36404
+ }
36405
+
36406
+ function cont() {
36407
+ pass.apply(null, arguments);
36408
+ return true;
36409
+ }
36410
+
36411
+ function pushContext(tagName, startOfLine) {
36412
+ var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName)
36413
+ || (curState.context && curState.context.noIndent);
36414
+ curState.context = {
36415
+ prev : curState.context,
36416
+ tagName : tagName,
36417
+ indent : curState.indented,
36418
+ startOfLine : startOfLine,
36419
+ noIndent : noIndent
36420
+ };
36421
+ }
36422
+
36423
+ function popContext() {
36424
+ if (curState.context)
36425
+ curState.context = curState.context.prev;
36426
+ }
36427
+
36428
+ function element(type) {
36429
+ if (type == "openTag") {
36430
+ curState.tagName = tagName;
36431
+ return cont(attributes, endtag(curState.startOfLine));
36432
+ } else if (type == "closeTag") {
36433
+ var err = false;
36434
+ if (curState.context) {
36435
+ if (curState.context.tagName != tagName) {
36436
+ if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
36437
+ popContext();
36438
+ }
36439
+ err = !curState.context || curState.context.tagName != tagName;
36440
+ }
36441
+ } else {
36442
+ err = true;
36443
+ }
36444
+
36445
+ if (err)
36446
+ setStyle = "error";
36447
+ return cont(endclosetag(err));
36448
+ }
36449
+ return cont();
36450
+ }
36451
+
36452
+ function endtag(startOfLine) {
36453
+ return function(type) {
36454
+ if (type == "selfcloseTag"
36455
+ || (type == "endTag" && Kludges.autoSelfClosers
36456
+ .hasOwnProperty(curState.tagName
36457
+ .toLowerCase()))) {
36458
+ maybePopContext(curState.tagName.toLowerCase());
36459
+ return cont();
36460
+ }
36461
+ if (type == "endTag") {
36462
+ maybePopContext(curState.tagName.toLowerCase());
36463
+ pushContext(curState.tagName, startOfLine);
36464
+ return cont();
36465
+ }
36466
+ return cont();
36467
+ };
36468
+ }
36469
+
36470
+ function endclosetag(err) {
36471
+ return function(type) {
36472
+ if (err)
36473
+ setStyle = "error";
36474
+ if (type == "endTag") {
36475
+ popContext();
36476
+ return cont();
36477
+ }
36478
+ setStyle = "error";
36479
+ return cont(arguments.callee);
36480
+ };
36481
+ }
36482
+
36483
+ function maybePopContext(nextTagName) {
36484
+ var parentTagName;
36485
+ while (true) {
36486
+ if (!curState.context) {
36487
+ return;
36488
+ }
36489
+ parentTagName = curState.context.tagName.toLowerCase();
36490
+ if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName)
36491
+ || !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
36492
+ return;
36493
+ }
36494
+ popContext();
36495
+ }
36496
+ }
36497
+
36498
+ function attributes(type) {
36499
+ if (type == "word") {
36500
+ setStyle = "attribute";
36501
+ return cont(attribute, attributes);
36502
+ }
36503
+ if (type == "endTag" || type == "selfcloseTag")
36504
+ return pass();
36505
+ setStyle = "error";
36506
+ return cont(attributes);
36507
+ }
36508
+
36509
+ function attribute(type) {
36510
+ if (type == "equals")
36511
+ return cont(attvalue, attributes);
36512
+ if (!Kludges.allowMissing)
36513
+ setStyle = "error";
36514
+ return (type == "endTag" || type == "selfcloseTag") ? pass()
36515
+ : cont();
36516
+ }
36517
+
36518
+ function attvalue(type) {
36519
+ if (type == "string")
36520
+ return cont(attvaluemaybe);
36521
+ if (type == "word" && Kludges.allowUnquoted) {
36522
+ setStyle = "string";
36523
+ return cont();
36524
+ }
36525
+ setStyle = "error";
36526
+ return (type == "endTag" || type == "selfCloseTag") ? pass()
36527
+ : cont();
36528
+ }
36529
+
36530
+ function attvaluemaybe(type) {
36531
+ if (type == "string")
36532
+ return cont(attvaluemaybe);
36533
+ else
36534
+ return pass();
36535
+ }
36536
+
36537
+ function startState() {
36538
+ return {
36539
+ tokenize : inText,
36540
+ cc : [],
36541
+ indented : 0,
36542
+ startOfLine : true,
36543
+ tagName : null,
36544
+ context : null
36545
+ };
36546
+ }
36547
+
36548
+ function token(stream, state) {
36549
+ if (stream.sol()) {
36550
+ state.startOfLine = true;
36551
+ state.indented = 0;
36552
+ }
36553
+
36554
+ if (stream.eatSpace())
36555
+ return null;
36556
+
36557
+ setStyle = type = tagName = null;
36558
+ var style = state.tokenize(stream, state);
36559
+ state.type = type;
36560
+ if ((style || type) && style != "comment") {
36561
+ curState = state;
36562
+ while (true) {
36563
+ var comb = state.cc.pop() || element;
36564
+ if (comb(type || style))
36565
+ break;
36566
+ }
36567
+ }
36568
+ state.startOfLine = false;
36569
+ return setStyle || style;
36570
+ }
36571
+
36572
+ return {
36573
+ /**
36574
+ * @memberOf emmet.xmlParser
36575
+ * @returns
36576
+ */
36577
+ parse: function(data, offset) {
36578
+ offset = offset || 0;
36579
+ var state = startState();
36580
+ var stream = stringStream.create(data);
36581
+ var tokens = [];
36582
+ while (!stream.eol()) {
36583
+ tokens.push({
36584
+ type: token(stream, state),
36585
+ start: stream.start + offset,
36586
+ end: stream.pos + offset
36587
+ });
36588
+ stream.start = stream.pos;
36589
+ }
36590
+
36591
+ return tokens;
36592
+ }
36593
+ };
36594
+ });
36595
+
36596
+ },{"../assets/stringStream":32}],63:[function(require,module,exports){
36597
+ /**
36598
+ * Module for working with file. Shall implement
36599
+ * IEmmetFile interface.
36600
+ *
36601
+ * Since implementation of this module depends
36602
+ * greatly on current runtime, this module must be
36603
+ * initialized with actual implementation first
36604
+ * before use. E.g.
36605
+ * require('./plugin/file')({
36606
+ * read: function() {...}
36607
+ * })
36608
+ *
36609
+ * By default, this module provides Node.JS implementation
36610
+ */
36611
+
36612
+ if (typeof module === 'object' && typeof define !== 'function') {
36613
+ var define = function (factory) {
36614
+ module.exports = factory(require, exports, module);
36615
+ };
36616
+ }
36617
+
36618
+ define(function(require, exports, module) {
36619
+ var utils = require('../utils/common');
36620
+
36621
+ // hide it from Require.JS parser
36622
+ (function(r) {
36623
+ if (typeof define === 'undefined' || !define.amd) {
36624
+ try {
36625
+ fs = r('fs');
36626
+ path = r('path');
36627
+ } catch(e) {}
36628
+ }
36629
+ })(require);
36630
+
36631
+ // module is a function that can extend itself
36632
+ module.exports = function(obj) {
36633
+ if (obj) {
36634
+ utils.extend(module.exports, obj);
36635
+ }
36636
+ };
36637
+
36638
+ function bts(bytes) {
36639
+ var out = [];
36640
+ for (var i = 0, il = bytes.length; i < il; i++) {
36641
+ out.push(String.fromCharCode(bytes[i]));
36642
+ }
36643
+ return out.join('');
36644
+ }
36645
+
36646
+ function isURL(path) {
36647
+ var re = /^https?:\/\//;
36648
+ return re.test(path);
36649
+ }
36650
+
36651
+ return utils.extend(module.exports, {
36652
+ _parseParams: function(args) {
36653
+ var params = {
36654
+ path: args[0],
36655
+ size: 0
36656
+ };
36657
+
36658
+ args = utils.toArray(args, 1);
36659
+ params.callback = args[args.length - 1];
36660
+ args = args.slice(0, args.length - 1);
36661
+ if (args.length) {
36662
+ params.size = args[0];
36663
+ }
36664
+
36665
+ return params;
36666
+ },
36667
+
36668
+ _read: function(params, callback) {
36669
+ if (isURL(params.path)) {
36670
+ var req = require(/^https:/.test(params.path) ? 'https' : 'http').get(params.path, function(res) {
36671
+ var bufs = [];
36672
+ var totalLength = 0;
36673
+ var finished = false;
36674
+ res
36675
+ .on('data', function(chunk) {
36676
+ totalLength += chunk.length;
36677
+ bufs.push(chunk);
36678
+ if (params.size && totalLength >= params.size) {
36679
+ finished = true;
36680
+ callback(null, Buffer.concat(bufs));
36681
+ req.abort();
36682
+ }
36683
+ })
36684
+ .on('end', function() {
36685
+ if (!finished) {
36686
+ finished = true;
36687
+ callback(null, Buffer.concat(bufs));
36688
+ }
36689
+ });
36690
+ }).on('error', callback);
36691
+ } else {
36692
+ if (params.size) {
36693
+ var fd = fs.openSync(params.path, 'r');
36694
+ var buf = new Buffer(params.size);
36695
+ fs.read(fd, buf, 0, params.size, null, function(err, bytesRead) {
36696
+ callback(err, buf)
36697
+ });
36698
+ } else {
36699
+ callback(null, fs.readFileSync(params.path));
36700
+ }
36701
+ }
36702
+ },
36703
+
36704
+ /**
36705
+ * Reads binary file content and return it
36706
+ * @param {String} path File's relative or absolute path
36707
+ * @return {String}
36708
+ */
36709
+ read: function(path, size, callback) {
36710
+ var params = this._parseParams(arguments);
36711
+ this._read(params, function(err, buf) {
36712
+ params.callback(err, err ? '' : bts(buf));
36713
+ });
36714
+ },
36715
+
36716
+ /**
36717
+ * Read file content and return it
36718
+ * @param {String} path File's relative or absolute path
36719
+ * @return {String}
36720
+ */
36721
+ readText: function(path, size, callback) {
36722
+ var params = this._parseParams(arguments);
36723
+ this._read(params, function(err, buf) {
36724
+ params.callback(err, err ? '' : buf.toString());
36725
+ });
36726
+ },
36727
+
36728
+ /**
36729
+ * Locate <code>file_name</code> file that relates to <code>editor_file</code>.
36730
+ * File name may be absolute or relative path
36731
+ *
36732
+ * <b>Dealing with absolute path.</b>
36733
+ * Many modern editors have a "project" support as information unit, but you
36734
+ * should not rely on project path to find file with absolute path. First,
36735
+ * it requires user to create a project before using this method (and this
36736
+ * is not very convenient). Second, project path doesn't always points to
36737
+ * to website's document root folder: it may point, for example, to an
36738
+ * upper folder which contains server-side scripts.
36739
+ *
36740
+ * For better result, you should use the following algorithm in locating
36741
+ * absolute resources:
36742
+ * 1) Get parent folder for <code>editorFile</code> as a start point
36743
+ * 2) Append required <code>fileName</code> to start point and test if
36744
+ * file exists
36745
+ * 3) If it doesn't exists, move start point one level up (to parent folder)
36746
+ * and repeat step 2.
36747
+ *
36748
+ * @param {String} editorFile
36749
+ * @param {String} fileName
36750
+ * @return {String} Returns null if <code>fileName</code> cannot be located
36751
+ */
36752
+ locateFile: function(editorFile, fileName) {
36753
+ if (isURL(fileName)) {
36754
+ return fileName;
36755
+ }
36756
+
36757
+ var dirname = editorFile, f;
36758
+ fileName = fileName.replace(/^\/+/, '');
36759
+ while (dirname && dirname !== path.dirname(dirname)) {
36760
+ dirname = path.dirname(dirname);
36761
+ f = path.join(dirname, fileName);
36762
+ if (fs.existsSync(f))
36763
+ return f;
36764
+ }
36765
+
36766
+ return '';
36767
+ },
36768
+
36769
+ /**
36770
+ * Creates absolute path by concatenating <code>parent</code> and <code>fileName</code>.
36771
+ * If <code>parent</code> points to file, its parent directory is used
36772
+ * @param {String} parent
36773
+ * @param {String} fileName
36774
+ * @return {String}
36775
+ */
36776
+ createPath: function(parent, fileName, callback) {
36777
+ var stat = fs.statSync(parent);
36778
+ if (stat && !stat.isDirectory()) {
36779
+ parent = path.dirname(parent);
36780
+ }
36781
+
36782
+ return callback(path.resolve(parent, fileName));
36783
+ },
36784
+
36785
+ /**
36786
+ * Saves <code>content</code> as <code>file</code>
36787
+ * @param {String} file File's absolute path
36788
+ * @param {String} content File content
36789
+ */
36790
+ save: function(file, content) {
36791
+ fs.writeFileSync(file, content, 'ascii');
36792
+ },
36793
+
36794
+ /**
36795
+ * Returns file extension in lower case
36796
+ * @param {String} file
36797
+ * @return {String}
36798
+ */
36799
+ getExt: function(file) {
36800
+ var m = (file || '').match(/\.([\w\-]+)$/);
36801
+ return m ? m[1].toLowerCase() : '';
36802
+ }
36803
+
36804
+ });
36805
+ });
36806
+ },{"../utils/common":73}],64:[function(require,module,exports){
36807
+ /**
36808
+ * Resolver for fast CSS typing. Handles abbreviations with the following
36809
+ * notation:<br>
36810
+ *
36811
+ * <code>(-vendor prefix)?property(value)*(!)?</code>
36812
+ *
36813
+ * <br><br>
36814
+ * <b>Abbreviation handling</b><br>
36815
+ *
36816
+ * By default, Emmet searches for matching snippet definition for provided abbreviation.
36817
+ * If snippet wasn't found, Emmet automatically generates element with
36818
+ * abbreviation's name. For example, <code>foo</code> abbreviation will generate
36819
+ * <code>&lt;foo&gt;&lt;/foo&gt;</code> output.
36820
+ * <br><br>
36821
+ * This module will capture all expanded properties and upgrade them with values,
36822
+ * vendor prefixes and !important declarations. All unmatched abbreviations will
36823
+ * be automatically transformed into <code>property-name: ${1}</code> snippets.
36824
+ *
36825
+ * <b>Vendor prefixes<b><br>
36826
+ *
36827
+ * If CSS-property is preceded with dash, resolver should output property with
36828
+ * all <i>known</i> vendor prefixes. For example, if <code>brad</code>
36829
+ * abbreviation generates <code>border-radius: ${value};</code> snippet,
36830
+ * the <code>-brad</code> abbreviation should generate:
36831
+ * <pre><code>
36832
+ * -webkit-border-radius: ${value};
36833
+ * -moz-border-radius: ${value};
36834
+ * border-radius: ${value};
36835
+ * </code></pre>
36836
+ * Note that <i>o</i> and <i>ms</i> prefixes are omitted since Opera and IE
36837
+ * supports unprefixed property.<br><br>
36838
+ *
36839
+ * Users can also provide an explicit list of one-character prefixes for any
36840
+ * CSS property. For example, <code>-wm-float</code> will produce
36841
+ *
36842
+ * <pre><code>
36843
+ * -webkit-float: ${1};
36844
+ * -moz-float: ${1};
36845
+ * float: ${1};
36846
+ * </code></pre>
36847
+ *
36848
+ * Although this example looks pointless, users can use this feature to write
36849
+ * cutting-edge properties implemented by browser vendors recently.
36850
+ */
36851
+ if (typeof module === 'object' && typeof define !== 'function') {
36852
+ var define = function (factory) {
36853
+ module.exports = factory(require, exports, module);
36854
+ };
36855
+ }
36856
+
36857
+ define(function(require, exports, module) {
36858
+ var prefs = require('../assets/preferences');
36859
+ var resources = require('../assets/resources');
36860
+ var stringStream = require('../assets/stringStream');
36861
+ var ciu = require('../assets/caniuse');
36862
+ var utils = require('../utils/common');
36863
+ var template = require('../utils/template');
36864
+ var cssEditTree = require('../editTree/css');
36865
+
36866
+ var prefixObj = {
36867
+ /** Real vendor prefix name */
36868
+ prefix: 'emmet',
36869
+
36870
+ /**
36871
+ * Indicates this prefix is obsolete and should't be used when user
36872
+ * wants to generate all-prefixed properties
36873
+ */
36874
+ obsolete: false,
36875
+
36876
+ /**
36877
+ * Returns prefixed CSS property name
36878
+ * @param {String} name Unprefixed CSS property
36879
+ */
36880
+ transformName: function(name) {
36881
+ return '-' + this.prefix + '-' + name;
36882
+ },
36883
+
36884
+ /**
36885
+ * List of unprefixed CSS properties that supported by
36886
+ * current prefix. This list is used to generate all-prefixed property
36887
+ * @returns {Array}
36888
+ */
36889
+ properties: function() {
36890
+ return getProperties('css.' + this.prefix + 'Properties') || [];
36891
+ },
36892
+
36893
+ /**
36894
+ * Check if given property is supported by current prefix
36895
+ * @param name
36896
+ */
36897
+ supports: function(name) {
36898
+ return ~this.properties().indexOf(name);
36899
+ }
36900
+ };
36901
+
36902
+
36903
+ /**
36904
+ * List of registered one-character prefixes. Key is a one-character prefix,
36905
+ * value is an <code>prefixObj</code> object
36906
+ */
36907
+ var vendorPrefixes = {};
36908
+
36909
+ var defaultValue = '${1};';
36910
+
36911
+ // XXX module preferences
36912
+ prefs.define('css.valueSeparator', ': ',
36913
+ 'Defines a symbol that should be placed between CSS property and '
36914
+ + 'value when expanding CSS abbreviations.');
36915
+ prefs.define('css.propertyEnd', ';',
36916
+ 'Defines a symbol that should be placed at the end of CSS property '
36917
+ + 'when expanding CSS abbreviations.');
36918
+
36919
+ prefs.define('stylus.valueSeparator', ' ',
36920
+ 'Defines a symbol that should be placed between CSS property and '
36921
+ + 'value when expanding CSS abbreviations in Stylus dialect.');
36922
+ prefs.define('stylus.propertyEnd', '',
36923
+ 'Defines a symbol that should be placed at the end of CSS property '
36924
+ + 'when expanding CSS abbreviations in Stylus dialect.');
36925
+
36926
+ prefs.define('sass.propertyEnd', '',
36927
+ 'Defines a symbol that should be placed at the end of CSS property '
36928
+ + 'when expanding CSS abbreviations in SASS dialect.');
36929
+
36930
+ prefs.define('css.syntaxes', 'css, less, sass, scss, stylus, styl',
36931
+ 'List of syntaxes that should be treated as CSS dialects.');
36932
+
36933
+ prefs.define('css.autoInsertVendorPrefixes', true,
36934
+ 'Automatically generate vendor-prefixed copies of expanded CSS '
36935
+ + 'property. By default, Emmet will generate vendor-prefixed '
36936
+ + 'properties only when you put dash before abbreviation '
36937
+ + '(e.g. <code>-bxsh</code>). With this option enabled, you don’t '
36938
+ + 'need dashes before abbreviations: Emmet will produce '
36939
+ + 'vendor-prefixed properties for you.');
36940
+
36941
+ prefs.define('less.autoInsertVendorPrefixes', false, 'Same as <code>css.autoInsertVendorPrefixes</code> but for LESS syntax');
36942
+ prefs.define('scss.autoInsertVendorPrefixes', false, 'Same as <code>css.autoInsertVendorPrefixes</code> but for SCSS syntax');
36943
+ prefs.define('sass.autoInsertVendorPrefixes', false, 'Same as <code>css.autoInsertVendorPrefixes</code> but for SASS syntax');
36944
+ prefs.define('stylus.autoInsertVendorPrefixes', false, 'Same as <code>css.autoInsertVendorPrefixes</code> but for Stylus syntax');
36945
+
36946
+ var descTemplate = template('A comma-separated list of CSS properties that may have '
36947
+ + '<code><%= vendor %></code> vendor prefix. This list is used to generate '
36948
+ + 'a list of prefixed properties when expanding <code>-property</code> '
36949
+ + 'abbreviations. Empty list means that all possible CSS values may '
36950
+ + 'have <code><%= vendor %></code> prefix.');
36951
+
36952
+ var descAddonTemplate = template('A comma-separated list of <em>additional</em> CSS properties '
36953
+ + 'for <code>css.<%= vendor %>Preperties</code> preference. '
36954
+ + 'You should use this list if you want to add or remove a few CSS '
36955
+ + 'properties to original set. To add a new property, simply write its name, '
36956
+ + 'to remove it, precede property with hyphen.<br>'
36957
+ + 'For example, to add <em>foo</em> property and remove <em>border-radius</em> one, '
36958
+ + 'the preference value will look like this: <code>foo, -border-radius</code>.');
36959
+
36960
+ // properties list is created from cssFeatures.html file
36961
+ var props = {
36962
+ 'webkit': 'animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-clip, background-composite, background-origin, background-size, border-fit, border-horizontal-spacing, border-image, border-vertical-spacing, box-align, box-direction, box-flex, box-flex-group, box-lines, box-ordinal-group, box-orient, box-pack, box-reflect, box-shadow, color-correction, column-break-after, column-break-before, column-break-inside, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-span, column-width, dashboard-region, font-smoothing, highlight, hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphens, line-box-contain, line-break, line-clamp, locale, margin-before-collapse, margin-after-collapse, marquee-direction, marquee-increment, marquee-repetition, marquee-style, mask-attachment, mask-box-image, mask-box-image-outset, mask-box-image-repeat, mask-box-image-slice, mask-box-image-source, mask-box-image-width, mask-clip, mask-composite, mask-image, mask-origin, mask-position, mask-repeat, mask-size, nbsp-mode, perspective, perspective-origin, rtl-ordering, text-combine, text-decorations-in-effect, text-emphasis-color, text-emphasis-position, text-emphasis-style, text-fill-color, text-orientation, text-security, text-stroke-color, text-stroke-width, transform, transition, transform-origin, transform-style, transition-delay, transition-duration, transition-property, transition-timing-function, user-drag, user-modify, user-select, writing-mode, svg-shadow, box-sizing, border-radius',
36963
+ 'moz': 'animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-inline-policy, binding, border-bottom-colors, border-image, border-left-colors, border-right-colors, border-top-colors, box-align, box-direction, box-flex, box-ordinal-group, box-orient, box-pack, box-shadow, box-sizing, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-width, float-edge, font-feature-settings, font-language-override, force-broken-image-icon, hyphens, image-region, orient, outline-radius-bottomleft, outline-radius-bottomright, outline-radius-topleft, outline-radius-topright, perspective, perspective-origin, stack-sizing, tab-size, text-blink, text-decoration-color, text-decoration-line, text-decoration-style, text-size-adjust, transform, transform-origin, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-focus, user-input, user-modify, user-select, window-shadow, background-clip, border-radius',
36964
+ 'ms': 'accelerator, backface-visibility, background-position-x, background-position-y, behavior, block-progression, box-align, box-direction, box-flex, box-line-progression, box-lines, box-ordinal-group, box-orient, box-pack, content-zoom-boundary, content-zoom-boundary-max, content-zoom-boundary-min, content-zoom-chaining, content-zoom-snap, content-zoom-snap-points, content-zoom-snap-type, content-zooming, filter, flow-from, flow-into, font-feature-settings, grid-column, grid-column-align, grid-column-span, grid-columns, grid-layer, grid-row, grid-row-align, grid-row-span, grid-rows, high-contrast-adjust, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-zone, hyphens, ime-mode, interpolation-mode, layout-flow, layout-grid, layout-grid-char, layout-grid-line, layout-grid-mode, layout-grid-type, line-break, overflow-style, perspective, perspective-origin, perspective-origin-x, perspective-origin-y, scroll-boundary, scroll-boundary-bottom, scroll-boundary-left, scroll-boundary-right, scroll-boundary-top, scroll-chaining, scroll-rails, scroll-snap-points-x, scroll-snap-points-y, scroll-snap-type, scroll-snap-x, scroll-snap-y, scrollbar-arrow-color, scrollbar-base-color, scrollbar-darkshadow-color, scrollbar-face-color, scrollbar-highlight-color, scrollbar-shadow-color, scrollbar-track-color, text-align-last, text-autospace, text-justify, text-kashida-space, text-overflow, text-size-adjust, text-underline-position, touch-action, transform, transform-origin, transform-origin-x, transform-origin-y, transform-origin-z, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-select, word-break, wrap-flow, wrap-margin, wrap-through, writing-mode',
36965
+ 'o': 'dashboard-region, animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, border-image, link, link-source, object-fit, object-position, tab-size, table-baseline, transform, transform-origin, transition, transition-delay, transition-duration, transition-property, transition-timing-function, accesskey, input-format, input-required, marquee-dir, marquee-loop, marquee-speed, marquee-style'
36966
+ };
36967
+
36968
+ Object.keys(props).forEach(function(k) {
36969
+ prefs.define('css.' + k + 'Properties', props[k], descTemplate({vendor: k}));
36970
+ prefs.define('css.' + k + 'PropertiesAddon', '', descAddonTemplate({vendor: k}));
36971
+ });
36972
+
36973
+ prefs.define('css.unitlessProperties', 'z-index, line-height, opacity, font-weight, zoom',
36974
+ 'The list of properties whose values ​​must not contain units.');
36975
+
36976
+ prefs.define('css.intUnit', 'px', 'Default unit for integer values');
36977
+ prefs.define('css.floatUnit', 'em', 'Default unit for float values');
36978
+
36979
+ prefs.define('css.keywords', 'auto, inherit, all',
36980
+ 'A comma-separated list of valid keywords that can be used in CSS abbreviations.');
36981
+
36982
+ prefs.define('css.keywordAliases', 'a:auto, i:inherit, s:solid, da:dashed, do:dotted, t:transparent',
36983
+ 'A comma-separated list of keyword aliases, used in CSS abbreviation. '
36984
+ + 'Each alias should be defined as <code>alias:keyword_name</code>.');
36985
+
36986
+ prefs.define('css.unitAliases', 'e:em, p:%, x:ex, r:rem',
36987
+ 'A comma-separated list of unit aliases, used in CSS abbreviation. '
36988
+ + 'Each alias should be defined as <code>alias:unit_value</code>.');
36989
+
36990
+ prefs.define('css.color.short', true,
36991
+ 'Should color values like <code>#ffffff</code> be shortened to '
36992
+ + '<code>#fff</code> after abbreviation with color was expanded.');
36993
+
36994
+ prefs.define('css.color.case', 'keep',
36995
+ 'Letter case of color values generated by abbreviations with color '
36996
+ + '(like <code>c#0</code>). Possible values are <code>upper</code>, '
36997
+ + '<code>lower</code> and <code>keep</code>.');
36998
+
36999
+ prefs.define('css.fuzzySearch', true,
37000
+ 'Enable fuzzy search among CSS snippet names. When enabled, every '
37001
+ + '<em>unknown</em> snippet will be scored against available snippet '
37002
+ + 'names (not values or CSS properties!). The match with best score '
37003
+ + 'will be used to resolve snippet value. For example, with this '
37004
+ + 'preference enabled, the following abbreviations are equal: '
37005
+ + '<code>ov:h</code> == <code>ov-h</code> == <code>o-h</code> == '
37006
+ + '<code>oh</code>');
37007
+
37008
+ prefs.define('css.fuzzySearchMinScore', 0.3,
37009
+ 'The minium score (from 0 to 1) that fuzzy-matched abbreviation should '
37010
+ + 'achive. Lower values may produce many false-positive matches, '
37011
+ + 'higher values may reduce possible matches.');
37012
+
37013
+ prefs.define('css.alignVendor', false,
37014
+ 'If set to <code>true</code>, all generated vendor-prefixed properties '
37015
+ + 'will be aligned by real property name.');
37016
+
37017
+
37018
+ function isNumeric(ch) {
37019
+ var code = ch && ch.charCodeAt(0);
37020
+ return (ch && ch == '.' || (code > 47 && code < 58));
37021
+ }
37022
+
37023
+ /**
37024
+ * Check if provided snippet contains only one CSS property and value.
37025
+ * @param {String} snippet
37026
+ * @returns {Boolean}
37027
+ */
37028
+ function isSingleProperty(snippet) {
37029
+ snippet = utils.trim(snippet);
37030
+
37031
+ // check if it doesn't contain a comment and a newline
37032
+ if (/\/\*|\n|\r/.test(snippet)) {
37033
+ return false;
37034
+ }
37035
+
37036
+ // check if it's a valid snippet definition
37037
+ if (!/^[a-z0-9\-]+\s*\:/i.test(snippet)) {
37038
+ return false;
37039
+ }
37040
+
37041
+ return snippet.replace(/\$\{.+?\}/g, '').split(':').length == 2;
37042
+ }
37043
+
37044
+ /**
37045
+ * Normalizes abbreviated value to final CSS one
37046
+ * @param {String} value
37047
+ * @returns {String}
37048
+ */
37049
+ function normalizeValue(value) {
37050
+ if (value.charAt(0) == '-' && !/^\-[\.\d]/.test(value)) {
37051
+ value = value.replace(/^\-+/, '');
37052
+ }
37053
+
37054
+ var ch = value.charAt(0);
37055
+ if (ch == '#') {
37056
+ return normalizeHexColor(value);
37057
+ }
37058
+
37059
+ if (ch == '$') {
37060
+ return utils.escapeText(value);
37061
+ }
37062
+
37063
+ return getKeyword(value);
37064
+ }
37065
+
37066
+ function normalizeHexColor(value) {
37067
+ var hex = value.replace(/^#+/, '') || '0';
37068
+ if (hex.toLowerCase() == 't') {
37069
+ return 'transparent';
37070
+ }
37071
+
37072
+ var opacity = '';
37073
+ hex = hex.replace(/\.(\d+)$/, function(str) {
37074
+ opacity = '0' + str;
37075
+ return '';
37076
+ });
37077
+
37078
+ var repeat = utils.repeatString;
37079
+ var color = null;
37080
+ switch (hex.length) {
37081
+ case 1:
37082
+ color = repeat(hex, 6);
37083
+ break;
37084
+ case 2:
37085
+ color = repeat(hex, 3);
37086
+ break;
37087
+ case 3:
37088
+ color = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
37089
+ break;
37090
+ case 4:
37091
+ color = hex + hex.substr(0, 2);
37092
+ break;
37093
+ case 5:
37094
+ color = hex + hex.charAt(0);
37095
+ break;
37096
+ default:
37097
+ color = hex.substr(0, 6);
37098
+ }
37099
+
37100
+ if (opacity) {
37101
+ return toRgba(color, opacity);
37102
+ }
37103
+
37104
+ // color must be shortened?
37105
+ if (prefs.get('css.color.short')) {
37106
+ var p = color.split('');
37107
+ if (p[0] == p[1] && p[2] == p[3] && p[4] == p[5]) {
37108
+ color = p[0] + p[2] + p[4];
37109
+ }
37110
+ }
37111
+
37112
+ // should transform case?
37113
+ switch (prefs.get('css.color.case')) {
37114
+ case 'upper':
37115
+ color = color.toUpperCase();
37116
+ break;
37117
+ case 'lower':
37118
+ color = color.toLowerCase();
37119
+ break;
37120
+ }
37121
+
37122
+ return '#' + color;
37123
+ }
37124
+
37125
+ /**
37126
+ * Transforms HEX color definition into RGBA one
37127
+ * @param {String} color HEX color, 6 characters
37128
+ * @param {String} opacity Opacity value
37129
+ * @return {String}
37130
+ */
37131
+ function toRgba(color, opacity) {
37132
+ var r = parseInt(color.substr(0, 2), 16);
37133
+ var g = parseInt(color.substr(2, 2), 16);
37134
+ var b = parseInt(color.substr(4, 2), 16);
37135
+
37136
+ return 'rgba(' + [r, g, b, opacity].join(', ') + ')';
37137
+ }
37138
+
37139
+ function getKeyword(name) {
37140
+ var aliases = prefs.getDict('css.keywordAliases');
37141
+ return name in aliases ? aliases[name] : name;
37142
+ }
37143
+
37144
+ function getUnit(name) {
37145
+ var aliases = prefs.getDict('css.unitAliases');
37146
+ return name in aliases ? aliases[name] : name;
37147
+ }
37148
+
37149
+ function isValidKeyword(keyword) {
37150
+ return ~prefs.getArray('css.keywords').indexOf(getKeyword(keyword));
37151
+ }
37152
+
37153
+ /**
37154
+ * Check if passed CSS property support specified vendor prefix
37155
+ * @param {String} property
37156
+ * @param {String} prefix
37157
+ */
37158
+ function hasPrefix(property, prefix) {
37159
+ var info = vendorPrefixes[prefix];
37160
+
37161
+ if (!info)
37162
+ info = utils.find(vendorPrefixes, function(data) {
37163
+ return data.prefix == prefix;
37164
+ });
37165
+
37166
+ return info && info.supports(property);
37167
+ }
37168
+
37169
+ /**
37170
+ * Finds available vendor prefixes for given CSS property.
37171
+ * Search is performed within Can I Use database and internal
37172
+ * property list
37173
+ * @param {String} property CSS property name
37174
+ * @return {Array} Array of resolved prefixes or null if
37175
+ * prefixes are not available for this property at all.
37176
+ * Empty array means prefixes are not available for current
37177
+ * user-define era
37178
+ */
37179
+ function findVendorPrefixes(property) {
37180
+ var prefixes = ciu.resolvePrefixes(property);
37181
+ if (!prefixes) {
37182
+ // Can I Use database is disabled or prefixes are not
37183
+ // available for this property
37184
+ prefixes = [];
37185
+ Object.keys(vendorPrefixes).forEach(function(key) {
37186
+ if (hasPrefix(property, key)) {
37187
+ prefixes.push(vendorPrefixes[key].prefix);
37188
+ }
37189
+ });
37190
+
37191
+ if (!prefixes.length) {
37192
+ prefixes = null;
37193
+ }
37194
+ }
37195
+
37196
+ return prefixes;
37197
+ }
37198
+
37199
+ /**
37200
+ * Search for a list of supported prefixes for CSS property. This list
37201
+ * is used to generate all-prefixed snippet
37202
+ * @param {String} property CSS property name
37203
+ * @returns {Array}
37204
+ */
37205
+ function findInternalPrefixes(property, noAutofill) {
37206
+ var result = [];
37207
+ var prefixes = findVendorPrefixes(property);
37208
+
37209
+ if (prefixes) {
37210
+ var prefixMap = {};
37211
+ Object.keys(vendorPrefixes).forEach(function(key) {
37212
+ prefixMap[vendorPrefixes[key].prefix] = key;
37213
+ });
37214
+
37215
+ result = prefixes.map(function(prefix) {
37216
+ return prefixMap[prefix];
37217
+ });
37218
+ }
37219
+
37220
+ if (!result.length && !noAutofill) {
37221
+ // add all non-obsolete prefixes
37222
+ Object.keys(vendorPrefixes).forEach(function(prefix) {
37223
+ if (!vendorPrefixes[prefix].obsolete) {
37224
+ result.push(prefix);
37225
+ }
37226
+ });
37227
+ }
37228
+
37229
+ return result;
37230
+ }
37231
+
37232
+ function addPrefix(name, obj) {
37233
+ if (typeof obj === 'string') {
37234
+ obj = {prefix: obj};
37235
+ }
37236
+
37237
+ vendorPrefixes[name] = utils.extend({}, prefixObj, obj);
37238
+ }
37239
+
37240
+ function getSyntaxPreference(name, syntax) {
37241
+ if (syntax) {
37242
+ // hacky alias for Stylus dialect
37243
+ if (syntax == 'styl') {
37244
+ syntax = 'stylus';
37245
+ }
37246
+
37247
+ var val = prefs.get(syntax + '.' + name);
37248
+ if (typeof val !== 'undefined') {
37249
+ return val;
37250
+ }
37251
+ }
37252
+
37253
+ return prefs.get('css.' + name);
37254
+ }
37255
+
37256
+ /**
37257
+ * Format CSS property according to current syntax dialect
37258
+ * @param {String} property
37259
+ * @param {String} syntax
37260
+ * @returns {String}
37261
+ */
37262
+ function formatProperty(property, syntax) {
37263
+ var ix = property.indexOf(':');
37264
+ property = property.substring(0, ix).replace(/\s+$/, '')
37265
+ + getSyntaxPreference('valueSeparator', syntax)
37266
+ + utils.trim(property.substring(ix + 1));
37267
+
37268
+ return property.replace(/\s*;\s*$/, getSyntaxPreference('propertyEnd', syntax));
37269
+ }
37270
+
37271
+ /**
37272
+ * Transforms snippet value if required. For example, this transformation
37273
+ * may add <i>!important</i> declaration to CSS property
37274
+ * @param {String} snippet
37275
+ * @param {Boolean} isImportant
37276
+ * @returns {String}
37277
+ */
37278
+ function transformSnippet(snippet, isImportant, syntax) {
37279
+ if (typeof snippet !== 'string') {
37280
+ snippet = snippet.data;
37281
+ }
37282
+
37283
+ if (!isSingleProperty(snippet)) {
37284
+ return snippet;
37285
+ }
37286
+
37287
+ if (isImportant) {
37288
+ if (~snippet.indexOf(';')) {
37289
+ snippet = snippet.split(';').join(' !important;');
37290
+ } else {
37291
+ snippet += ' !important';
37292
+ }
37293
+ }
37294
+
37295
+ return formatProperty(snippet, syntax);
37296
+ }
37297
+
37298
+ function getProperties(key) {
37299
+ var list = prefs.getArray(key);
37300
+ var addon = prefs.getArray(key + 'Addon');
37301
+ if (addon) {
37302
+ addon.forEach(function(prop) {
37303
+ if (prop.charAt(0) == '-') {
37304
+ list = utils.without(list, prop.substr(1));
37305
+ } else {
37306
+ if (prop.charAt(0) == '+')
37307
+ prop = prop.substr(1);
37308
+
37309
+ list.push(prop);
37310
+ }
37311
+ });
37312
+ }
37313
+
37314
+ return list;
37315
+ }
37316
+
37317
+ /**
37318
+ * Tries to produce properties with vendor-prefixed value
37319
+ * @param {Object} snippetObj Parsed snippet object
37320
+ * @return {Array} Array of properties with prefixed values
37321
+ */
37322
+ function resolvePrefixedValues(snippetObj, isImportant, syntax) {
37323
+ var prefixes = [];
37324
+ var lookup = {};
37325
+
37326
+ var parts = cssEditTree.findParts(snippetObj.value);
37327
+ parts.reverse();
37328
+ parts.forEach(function(p) {
37329
+ var partValue = p.substring(snippetObj.value);
37330
+ (findVendorPrefixes(partValue) || []).forEach(function(prefix) {
37331
+ if (!lookup[prefix]) {
37332
+ lookup[prefix] = snippetObj.value;
37333
+ prefixes.push(prefix);
37334
+ }
37335
+
37336
+ lookup[prefix] = utils.replaceSubstring(lookup[prefix], '-' + prefix + '-' + partValue, p);
37337
+ });
37338
+ });
37339
+
37340
+ return prefixes.map(function(prefix) {
37341
+ return transformSnippet(snippetObj.name + ':' + lookup[prefix], isImportant, syntax);
37342
+ });
37343
+ }
37344
+
37345
+
37346
+ // TODO refactor, this looks awkward now
37347
+ addPrefix('w', {
37348
+ prefix: 'webkit'
37349
+ });
37350
+ addPrefix('m', {
37351
+ prefix: 'moz'
37352
+ });
37353
+ addPrefix('s', {
37354
+ prefix: 'ms'
37355
+ });
37356
+ addPrefix('o', {
37357
+ prefix: 'o'
37358
+ });
37359
+
37360
+
37361
+ module = module || {};
37362
+ module.exports = {
37363
+ /**
37364
+ * Adds vendor prefix
37365
+ * @param {String} name One-character prefix name
37366
+ * @param {Object} obj Object describing vendor prefix
37367
+ * @memberOf cssResolver
37368
+ */
37369
+ addPrefix: addPrefix,
37370
+
37371
+ /**
37372
+ * Check if passed CSS property supports specified vendor prefix
37373
+ * @param {String} property
37374
+ * @param {String} prefix
37375
+ */
37376
+ supportsPrefix: hasPrefix,
37377
+
37378
+ resolve: function(node, syntax) {
37379
+ var cssSyntaxes = prefs.getArray('css.syntaxes');
37380
+ if (cssSyntaxes && ~cssSyntaxes.indexOf(syntax) && node.isElement()) {
37381
+ return this.expandToSnippet(node.abbreviation, syntax);
37382
+ }
37383
+
37384
+ return null;
37385
+ },
37386
+
37387
+ /**
37388
+ * Returns prefixed version of passed CSS property, only if this
37389
+ * property supports such prefix
37390
+ * @param {String} property
37391
+ * @param {String} prefix
37392
+ * @returns
37393
+ */
37394
+ prefixed: function(property, prefix) {
37395
+ return hasPrefix(property, prefix)
37396
+ ? '-' + prefix + '-' + property
37397
+ : property;
37398
+ },
37399
+
37400
+ /**
37401
+ * Returns list of all registered vendor prefixes
37402
+ * @returns {Array}
37403
+ */
37404
+ listPrefixes: function() {
37405
+ return vendorPrefixes.map(function(obj) {
37406
+ return obj.prefix;
37407
+ });
37408
+ },
37409
+
37410
+ /**
37411
+ * Returns object describing vendor prefix
37412
+ * @param {String} name
37413
+ * @returns {Object}
37414
+ */
37415
+ getPrefix: function(name) {
37416
+ return vendorPrefixes[name];
37417
+ },
37418
+
37419
+ /**
37420
+ * Removes prefix object
37421
+ * @param {String} name
37422
+ */
37423
+ removePrefix: function(name) {
37424
+ if (name in vendorPrefixes)
37425
+ delete vendorPrefixes[name];
37426
+ },
37427
+
37428
+ /**
37429
+ * Extract vendor prefixes from abbreviation
37430
+ * @param {String} abbr
37431
+ * @returns {Object} Object containing array of prefixes and clean
37432
+ * abbreviation name
37433
+ */
37434
+ extractPrefixes: function(abbr) {
37435
+ if (abbr.charAt(0) != '-') {
37436
+ return {
37437
+ property: abbr,
37438
+ prefixes: null
37439
+ };
37440
+ }
37441
+
37442
+ // abbreviation may either contain sequence of one-character prefixes
37443
+ // or just dash, meaning that user wants to produce all possible
37444
+ // prefixed properties
37445
+ var i = 1, il = abbr.length, ch;
37446
+ var prefixes = [];
37447
+
37448
+ while (i < il) {
37449
+ ch = abbr.charAt(i);
37450
+ if (ch == '-') {
37451
+ // end-sequence character found, stop searching
37452
+ i++;
37453
+ break;
37454
+ }
37455
+
37456
+ if (ch in vendorPrefixes) {
37457
+ prefixes.push(ch);
37458
+ } else {
37459
+ // no prefix found, meaning user want to produce all
37460
+ // vendor-prefixed properties
37461
+ prefixes.length = 0;
37462
+ i = 1;
37463
+ break;
37464
+ }
37465
+
37466
+ i++;
37467
+ }
37468
+
37469
+ // reached end of abbreviation and no property name left
37470
+ if (i == il -1) {
37471
+ i = 1;
37472
+ prefixes.length = 1;
37473
+ }
37474
+
37475
+ return {
37476
+ property: abbr.substring(i),
37477
+ prefixes: prefixes.length ? prefixes : 'all'
37478
+ };
37479
+ },
37480
+
37481
+ /**
37482
+ * Search for value substring in abbreviation
37483
+ * @param {String} abbr
37484
+ * @returns {String} Value substring
37485
+ */
37486
+ findValuesInAbbreviation: function(abbr, syntax) {
37487
+ syntax = syntax || 'css';
37488
+
37489
+ var i = 0, il = abbr.length, value = '', ch;
37490
+ while (i < il) {
37491
+ ch = abbr.charAt(i);
37492
+ if (isNumeric(ch) || ch == '#' || ch == '$' || (ch == '-' && isNumeric(abbr.charAt(i + 1)))) {
37493
+ value = abbr.substring(i);
37494
+ break;
37495
+ }
37496
+
37497
+ i++;
37498
+ }
37499
+
37500
+ // try to find keywords in abbreviation
37501
+ var property = abbr.substring(0, abbr.length - value.length);
37502
+ var keywords = [];
37503
+ // try to extract some commonly-used properties
37504
+ while (~property.indexOf('-') && !resources.findSnippet(syntax, property)) {
37505
+ var parts = property.split('-');
37506
+ var lastPart = parts.pop();
37507
+ if (!isValidKeyword(lastPart)) {
37508
+ break;
37509
+ }
37510
+
37511
+ keywords.unshift(lastPart);
37512
+ property = parts.join('-');
37513
+ }
37514
+
37515
+ return keywords.join('-') + value;
37516
+ },
37517
+
37518
+ parseValues: function(str) {
37519
+ /** @type StringStream */
37520
+ var stream = stringStream.create(str);
37521
+ var values = [];
37522
+ var ch = null;
37523
+
37524
+ while ((ch = stream.next())) {
37525
+ if (ch == '$') {
37526
+ stream.match(/^[^\$]+/, true);
37527
+ values.push(stream.current());
37528
+ } else if (ch == '#') {
37529
+ stream.match(/^t|[0-9a-f]+(\.\d+)?/i, true);
37530
+ values.push(stream.current());
37531
+ } else if (ch == '-') {
37532
+ if (isValidKeyword(utils.last(values)) ||
37533
+ ( stream.start && isNumeric(str.charAt(stream.start - 1)) )
37534
+ ) {
37535
+ stream.start = stream.pos;
37536
+ }
37537
+
37538
+ stream.match(/^\-?[0-9]*(\.[0-9]+)?[a-z%\.]*/, true);
37539
+ values.push(stream.current());
37540
+ } else {
37541
+ stream.match(/^[0-9]*(\.[0-9]*)?[a-z%]*/, true);
37542
+ values.push(stream.current());
37543
+ }
37544
+
37545
+ stream.start = stream.pos;
37546
+ }
37547
+
37548
+ return values
37549
+ .filter(function(item) {
37550
+ return !!item;
37551
+ })
37552
+ .map(normalizeValue);
37553
+ },
37554
+
37555
+ /**
37556
+ * Extracts values from abbreviation
37557
+ * @param {String} abbr
37558
+ * @returns {Object} Object containing array of values and clean
37559
+ * abbreviation name
37560
+ */
37561
+ extractValues: function(abbr) {
37562
+ // search for value start
37563
+ var abbrValues = this.findValuesInAbbreviation(abbr);
37564
+ if (!abbrValues) {
37565
+ return {
37566
+ property: abbr,
37567
+ values: null
37568
+ };
37569
+ }
37570
+
37571
+ return {
37572
+ property: abbr.substring(0, abbr.length - abbrValues.length).replace(/-$/, ''),
37573
+ values: this.parseValues(abbrValues)
37574
+ };
37575
+ },
37576
+
37577
+ /**
37578
+ * Normalizes value, defined in abbreviation.
37579
+ * @param {String} value
37580
+ * @param {String} property
37581
+ * @returns {String}
37582
+ */
37583
+ normalizeValue: function(value, property) {
37584
+ property = (property || '').toLowerCase();
37585
+ var unitlessProps = prefs.getArray('css.unitlessProperties');
37586
+ return value.replace(/^(\-?[0-9\.]+)([a-z]*)$/, function(str, val, unit) {
37587
+ if (!unit && (val == '0' || ~unitlessProps.indexOf(property)))
37588
+ return val;
37589
+
37590
+ if (!unit)
37591
+ return val.replace(/\.$/, '') + prefs.get(~val.indexOf('.') ? 'css.floatUnit' : 'css.intUnit');
37592
+
37593
+ return val + getUnit(unit);
37594
+ });
37595
+ },
37596
+
37597
+ /**
37598
+ * Expands abbreviation into a snippet
37599
+ * @param {String} abbr Abbreviation name to expand
37600
+ * @param {String} value Abbreviation value
37601
+ * @param {String} syntax Currect syntax or dialect. Default is 'css'
37602
+ * @returns {Object} Array of CSS properties and values or predefined
37603
+ * snippet (string or element)
37604
+ */
37605
+ expand: function(abbr, value, syntax) {
37606
+ syntax = syntax || 'css';
37607
+ var autoInsertPrefixes = prefs.get(syntax + '.autoInsertVendorPrefixes');
37608
+
37609
+ // check if snippet should be transformed to !important
37610
+ var isImportant = /^(.+)\!$/.test(abbr);
37611
+ if (isImportant) {
37612
+ abbr = RegExp.$1;
37613
+ }
37614
+
37615
+ // check if we have abbreviated resource
37616
+ var snippet = resources.findSnippet(syntax, abbr);
37617
+ if (snippet && !autoInsertPrefixes) {
37618
+ return transformSnippet(snippet, isImportant, syntax);
37619
+ }
37620
+
37621
+ // no abbreviated resource, parse abbreviation
37622
+ var prefixData = this.extractPrefixes(abbr);
37623
+ var valuesData = this.extractValues(prefixData.property);
37624
+ var abbrData = utils.extend(prefixData, valuesData);
37625
+
37626
+ if (!snippet) {
37627
+ snippet = resources.findSnippet(syntax, abbrData.property);
37628
+ } else {
37629
+ abbrData.values = null;
37630
+ }
37631
+
37632
+ if (!snippet && prefs.get('css.fuzzySearch')) {
37633
+ // let’s try fuzzy search
37634
+ snippet = resources.fuzzyFindSnippet(syntax, abbrData.property, parseFloat(prefs.get('css.fuzzySearchMinScore')));
37635
+ }
37636
+
37637
+ if (!snippet) {
37638
+ if (!abbrData.property) {
37639
+ return null;
37640
+ }
37641
+ snippet = abbrData.property + ':' + defaultValue;
37642
+ } else if (typeof snippet !== 'string') {
37643
+ snippet = snippet.data;
37644
+ }
37645
+
37646
+ if (!isSingleProperty(snippet)) {
37647
+ return snippet;
37648
+ }
37649
+
37650
+ var snippetObj = this.splitSnippet(snippet);
37651
+ var result = [];
37652
+ if (!value && abbrData.values) {
37653
+ value = abbrData.values.map(function(val) {
37654
+ return this.normalizeValue(val, snippetObj.name);
37655
+ }, this).join(' ') + ';';
37656
+ }
37657
+
37658
+ snippetObj.value = value || snippetObj.value;
37659
+
37660
+ var prefixes = abbrData.prefixes == 'all' || (!abbrData.prefixes && autoInsertPrefixes)
37661
+ ? findInternalPrefixes(snippetObj.name, autoInsertPrefixes && abbrData.prefixes != 'all')
37662
+ : abbrData.prefixes;
37663
+
37664
+
37665
+ var names = [], propName;
37666
+ (prefixes || []).forEach(function(p) {
37667
+ if (p in vendorPrefixes) {
37668
+ propName = vendorPrefixes[p].transformName(snippetObj.name);
37669
+ names.push(propName);
37670
+ result.push(transformSnippet(propName + ':' + snippetObj.value,
37671
+ isImportant, syntax));
37672
+ }
37673
+ });
37674
+
37675
+ // put the original property
37676
+ result.push(transformSnippet(snippetObj.name + ':' + snippetObj.value, isImportant, syntax));
37677
+ names.push(snippetObj.name);
37678
+
37679
+ result = resolvePrefixedValues(snippetObj, isImportant, syntax).concat(result);
37680
+
37681
+ if (prefs.get('css.alignVendor')) {
37682
+ var pads = utils.getStringsPads(names);
37683
+ result = result.map(function(prop, i) {
37684
+ return pads[i] + prop;
37685
+ });
37686
+ }
37687
+
37688
+ return result;
37689
+ },
37690
+
37691
+ /**
37692
+ * Same as <code>expand</code> method but transforms output into
37693
+ * Emmet snippet
37694
+ * @param {String} abbr
37695
+ * @param {String} syntax
37696
+ * @returns {String}
37697
+ */
37698
+ expandToSnippet: function(abbr, syntax) {
37699
+ var snippet = this.expand(abbr, null, syntax);
37700
+ if (snippet === null) {
37701
+ return null;
37702
+ }
37703
+
37704
+ if (Array.isArray(snippet)) {
37705
+ return snippet.join('\n');
37706
+ }
37707
+
37708
+ if (typeof snippet !== 'string') {
37709
+ return snippet.data;
37710
+ }
37711
+
37712
+ return snippet + '';
37713
+ },
37714
+
37715
+ /**
37716
+ * Split snippet into a CSS property-value pair
37717
+ * @param {String} snippet
37718
+ */
37719
+ splitSnippet: function(snippet) {
37720
+ snippet = utils.trim(snippet);
37721
+ if (snippet.indexOf(':') == -1) {
37722
+ return {
37723
+ name: snippet,
37724
+ value: defaultValue
37725
+ };
37726
+ }
37727
+
37728
+ var pair = snippet.split(':');
37729
+
37730
+ return {
37731
+ name: utils.trim(pair.shift()),
37732
+ // replace ${0} tabstop to produce valid vendor-prefixed values
37733
+ // where possible
37734
+ value: utils.trim(pair.join(':')).replace(/^(\$\{0\}|\$0)(\s*;?)$/, '${1}$2')
37735
+ };
37736
+ },
37737
+
37738
+ getSyntaxPreference: getSyntaxPreference,
37739
+ transformSnippet: transformSnippet,
37740
+ vendorPrefixes: findVendorPrefixes
37741
+ };
37742
+
37743
+ return module.exports;
37744
+ });
37745
+ },{"../assets/caniuse":23,"../assets/preferences":28,"../assets/resources":31,"../assets/stringStream":32,"../editTree/css":37,"../utils/common":73,"../utils/template":77}],65:[function(require,module,exports){
37746
+ /**
37747
+ * 'Expand Abbreviation' handler that parses gradient definition from under
37748
+ * cursor and updates CSS rule with vendor-prefixed values.
37749
+ */
37750
+ if (typeof module === 'object' && typeof define !== 'function') {
37751
+ var define = function (factory) {
37752
+ module.exports = factory(require, exports, module);
37753
+ };
37754
+ }
37755
+
37756
+ define(function(require, exports, module) {
37757
+ var prefs = require('../assets/preferences');
37758
+ var resources = require('../assets/resources');
37759
+ var utils = require('../utils/common');
37760
+ var stringStream = require('../assets/stringStream');
37761
+ var cssResolver = require('./css');
37762
+ var range = require('../assets/range');
37763
+ var cssEditTree = require('../editTree/css');
37764
+ var editorUtils = require('../utils/editor');
37765
+ var linearGradient = require('./gradient/linear');
37766
+
37767
+ var cssSyntaxes = ['css', 'less', 'sass', 'scss', 'stylus', 'styl'];
37768
+
37769
+ // XXX define preferences
37770
+ prefs.define('css.gradient.prefixes', 'webkit, moz, o',
37771
+ 'A comma-separated list of vendor-prefixes for which values should '
37772
+ + 'be generated.');
37773
+
37774
+ prefs.define('css.gradient.oldWebkit', false,
37775
+ 'Generate gradient definition for old Webkit implementations');
37776
+
37777
+ prefs.define('css.gradient.omitDefaultDirection', true,
37778
+ 'Do not output default direction definition in generated gradients.');
37779
+
37780
+ prefs.define('css.gradient.defaultProperty', 'background-image',
37781
+ 'When gradient expanded outside CSS value context, it will produce '
37782
+ + 'properties with this name.');
37783
+
37784
+ prefs.define('css.gradient.fallback', false,
37785
+ 'With this option enabled, CSS gradient generator will produce '
37786
+ + '<code>background-color</code> property with gradient first color '
37787
+ + 'as fallback for old browsers.');
37788
+
37789
+ /**
37790
+ * Resolves property name (abbreviation): searches for snippet definition in
37791
+ * 'resources' and returns new name of matched property
37792
+ */
37793
+ function resolvePropertyName(name, syntax) {
37794
+ var snippet = resources.findSnippet(syntax, name);
37795
+
37796
+ if (!snippet && prefs.get('css.fuzzySearch')) {
37797
+ var minScore = parseFloat(prefs.get('css.fuzzySearchMinScore'));
37798
+ snippet = resources.fuzzyFindSnippet(syntax, name, minScore);
37799
+ }
37800
+
37801
+ if (snippet) {
37802
+ if (typeof snippet !== 'string') {
37803
+ snippet = snippet.data;
37804
+ }
37805
+
37806
+ return cssResolver.splitSnippet(snippet).name;
37807
+ }
37808
+ }
37809
+
37810
+ /**
37811
+ * Returns vendor prefixes for given gradient type
37812
+ * @param {String} type Gradient type (currently, 'linear-gradient'
37813
+ * is the only supported value)
37814
+ * @return {Array}
37815
+ */
37816
+ function getGradientPrefixes(type) {
37817
+ var prefixes = cssResolver.vendorPrefixes(type);
37818
+ if (!prefixes) {
37819
+ // disabled Can I Use, fallback to property list
37820
+ prefixes = prefs.getArray('css.gradient.prefixes');
37821
+ }
37822
+
37823
+ return prefixes || [];
37824
+ }
37825
+
37826
+ function getPrefixedNames(type) {
37827
+ var prefixes = getGradientPrefixes(type);
37828
+ var names = prefixes
37829
+ ? prefixes.map(function(p) {
37830
+ return '-' + p + '-' + type;
37831
+ })
37832
+ : [];
37833
+
37834
+ names.push(type);
37835
+
37836
+ return names;
37837
+ }
37838
+
37839
+ /**
37840
+ * Returns list of CSS properties with gradient
37841
+ * @param {Array} gradient List of gradient objects
37842
+ * @param {CSSEditElement} property Original CSS property
37843
+ * @returns {Array}
37844
+ */
37845
+ function getPropertiesForGradient(gradients, property) {
37846
+ var props = [];
37847
+ var propertyName = property.name();
37848
+ var omitDir = prefs.get('css.gradient.omitDefaultDirection');
37849
+
37850
+ if (prefs.get('css.gradient.fallback') && ~propertyName.toLowerCase().indexOf('background')) {
37851
+ props.push({
37852
+ name: 'background-color',
37853
+ value: '${1:' + gradients[0].gradient.colorStops[0].color + '}'
37854
+ });
37855
+ }
37856
+
37857
+ var value = property.value();
37858
+ getGradientPrefixes('linear-gradient').forEach(function(prefix) {
37859
+ var name = cssResolver.prefixed(propertyName, prefix);
37860
+ if (prefix == 'webkit' && prefs.get('css.gradient.oldWebkit')) {
37861
+ try {
37862
+ props.push({
37863
+ name: name,
37864
+ value: insertGradientsIntoCSSValue(gradients, value, {
37865
+ prefix: prefix,
37866
+ oldWebkit: true,
37867
+ omitDefaultDirection: omitDir
37868
+ })
37869
+ });
37870
+ } catch(e) {}
37871
+ }
37872
+
37873
+ props.push({
37874
+ name: name,
37875
+ value: insertGradientsIntoCSSValue(gradients, value, {
37876
+ prefix: prefix,
37877
+ omitDefaultDirection: omitDir
37878
+ })
37879
+ });
37880
+ });
37881
+
37882
+ return props.sort(function(a, b) {
37883
+ return b.name.length - a.name.length;
37884
+ });
37885
+ }
37886
+
37887
+ /**
37888
+ * Replaces old gradient definitions in given CSS property value
37889
+ * with new ones, preserving original formatting
37890
+ * @param {Array} gradients List of CSS gradients
37891
+ * @param {String} value Original CSS value
37892
+ * @param {Object} options Options for gradient’s stringify() method
37893
+ * @return {String}
37894
+ */
37895
+ function insertGradientsIntoCSSValue(gradients, value, options) {
37896
+ // gradients *should* passed in order they actually appear in CSS property
37897
+ // iterate over it in backward direction to preserve gradient locations
37898
+ options = options || {};
37899
+ gradients = utils.clone(gradients);
37900
+ gradients.reverse().forEach(function(item, i) {
37901
+ var suffix = !i && options.placeholder ? options.placeholder : '';
37902
+ var str = options.oldWebkit ? item.gradient.stringifyOldWebkit(options) : item.gradient.stringify(options);
37903
+ value = utils.replaceSubstring(value, str + suffix, item.matchedPart);
37904
+ });
37905
+
37906
+ return value;
37907
+ }
37908
+
37909
+ /**
37910
+ * Returns list of properties with the same meaning
37911
+ * (e.g. vendor-prefixed + original name)
37912
+ * @param {String} property CSS property name
37913
+ * @return {Array}
37914
+ */
37915
+ function similarPropertyNames(property) {
37916
+ if (typeof property !== 'string') {
37917
+ property = property.name();
37918
+ }
37919
+
37920
+ var similarProps = (cssResolver.vendorPrefixes(property) || []).map(function(prefix) {
37921
+ return '-' + prefix + '-' + property;
37922
+ });
37923
+ similarProps.push(property);
37924
+ return similarProps;
37925
+ }
37926
+
37927
+ /**
37928
+ * Pastes gradient definition into CSS rule with correct vendor-prefixes
37929
+ * @param {EditElement} property Matched CSS property
37930
+ * @param {Array} gradients List of gradients to insert
37931
+ */
37932
+ function pasteGradient(property, gradients) {
37933
+ var rule = property.parent;
37934
+ var alignVendor = prefs.get('css.alignVendor');
37935
+ var omitDir = prefs.get('css.gradient.omitDefaultDirection');
37936
+
37937
+ // we may have aligned gradient definitions: find the smallest value
37938
+ // separator
37939
+ var sep = property.styleSeparator;
37940
+ var before = property.styleBefore;
37941
+
37942
+ // first, remove all properties within CSS rule with the same name and
37943
+ // gradient definition
37944
+ rule.getAll(similarPropertyNames(property)).forEach(function(item) {
37945
+ if (item != property && /gradient/i.test(item.value())) {
37946
+ if (item.styleSeparator.length < sep.length) {
37947
+ sep = item.styleSeparator;
37948
+ }
37949
+ if (item.styleBefore.length < before.length) {
37950
+ before = item.styleBefore;
37951
+ }
37952
+ rule.remove(item);
37953
+ }
37954
+ });
37955
+
37956
+ if (alignVendor) {
37957
+ // update prefix
37958
+ if (before != property.styleBefore) {
37959
+ var fullRange = property.fullRange();
37960
+ rule._updateSource(before, fullRange.start, fullRange.start + property.styleBefore.length);
37961
+ property.styleBefore = before;
37962
+ }
37963
+
37964
+ // update separator value
37965
+ if (sep != property.styleSeparator) {
37966
+ rule._updateSource(sep, property.nameRange().end, property.valueRange().start);
37967
+ property.styleSeparator = sep;
37968
+ }
37969
+ }
37970
+
37971
+ var value = property.value();
37972
+
37973
+ // create list of properties to insert
37974
+ var propsToInsert = getPropertiesForGradient(gradients, property);
37975
+
37976
+ // align prefixed values
37977
+ if (alignVendor) {
37978
+ var names = [], values = [];
37979
+ propsToInsert.forEach(function(item) {
37980
+ names.push(item.name);
37981
+ values.push(item.value);
37982
+ });
37983
+ values.push(property.value());
37984
+ names.push(property.name());
37985
+
37986
+ var valuePads = utils.getStringsPads(values.map(function(v) {
37987
+ return v.substring(0, v.indexOf('('));
37988
+ }));
37989
+
37990
+ var namePads = utils.getStringsPads(names);
37991
+ property.name(namePads[namePads.length - 1] + property.name());
37992
+
37993
+ propsToInsert.forEach(function(prop, i) {
37994
+ prop.name = namePads[i] + prop.name;
37995
+ prop.value = valuePads[i] + prop.value;
37996
+ });
37997
+
37998
+ property.value(valuePads[valuePads.length - 1] + property.value());
37999
+ }
38000
+
38001
+ // put vendor-prefixed definitions before current rule
38002
+ propsToInsert.forEach(function(prop) {
38003
+ rule.add(prop.name, prop.value, rule.indexOf(property));
38004
+ });
38005
+
38006
+ // put vanilla-clean gradient definition into current rule
38007
+ property.value(insertGradientsIntoCSSValue(gradients, value, {
38008
+ placeholder: '${2}',
38009
+ omitDefaultDirection: omitDir
38010
+ }));
38011
+ }
38012
+
38013
+ /**
38014
+ * Validates caret position relatively to located gradients
38015
+ * in CSS rule. In other words, it checks if it’s safe to
38016
+ * expand gradients for current caret position or not.
38017
+ *
38018
+ * See issue https://github.com/sergeche/emmet-sublime/issues/411
38019
+ *
38020
+ * @param {Array} gradients List of parsed gradients
38021
+ * @param {Number} caretPos Current caret position
38022
+ * @param {String} syntax Current document syntax
38023
+ * @return {Boolean}
38024
+ */
38025
+ function isValidCaretPosition(gradients, caretPos, syntax) {
38026
+ syntax = syntax || 'css';
38027
+ if (syntax == 'css' || syntax == 'less' || syntax == 'scss') {
38028
+ return true;
38029
+ }
38030
+
38031
+ var offset = gradients.property.valueRange(true).start;
38032
+ var parts = gradients.gradients;
38033
+
38034
+ // in case of preprocessors where properties are separated with
38035
+ // newlines, make sure there’s no gradient definition past
38036
+ // current caret position.
38037
+ for (var i = parts.length - 1; i >= 0; i--) {
38038
+ if (parts[i].matchedPart.start + offset >= caretPos) {
38039
+ return false;
38040
+ }
38041
+ }
38042
+
38043
+ return true;
38044
+ }
38045
+
38046
+ module = module || {};
38047
+ return module.exports = {
38048
+ /**
38049
+ * Search for gradient definitions inside CSS property value
38050
+ * @returns {Array} Array of matched gradients
38051
+ */
38052
+ findGradients: function(cssProp) {
38053
+ var value = cssProp.value();
38054
+ var gradients = [];
38055
+ var that = this;
38056
+ cssProp.valueParts().forEach(function(part) {
38057
+ var partValue = part.substring(value);
38058
+ if (linearGradient.isLinearGradient(partValue)) {
38059
+ var gradient = linearGradient.parse(partValue);
38060
+ if (gradient) {
38061
+ gradients.push({
38062
+ gradient: gradient,
38063
+ matchedPart: part
38064
+ });
38065
+ }
38066
+ }
38067
+ });
38068
+
38069
+ return gradients.length ? gradients : null;
38070
+ },
38071
+
38072
+ /**
38073
+ * Returns list of gradients found in CSS property
38074
+ * of given CSS code in specified (caret) position
38075
+ * @param {String} css CSS code snippet
38076
+ * @param {Number} pos Character index where to start searching for CSS property
38077
+ * @return {Array}
38078
+ */
38079
+ gradientsFromCSSProperty: function(css, pos) {
38080
+ var cssProp = cssEditTree.propertyFromPosition(css, pos);
38081
+ if (cssProp) {
38082
+ var grd = this.findGradients(cssProp);
38083
+ if (grd) {
38084
+ return {
38085
+ property: cssProp,
38086
+ gradients: grd
38087
+ };
38088
+ }
38089
+ }
38090
+
38091
+ return null;
38092
+ },
38093
+
38094
+ /**
38095
+ * Handler for “Expand Abbreviation” action
38096
+ * @param {IEmmetEditor} editor
38097
+ * @param {String} syntax
38098
+ * @param {String} profile
38099
+ * return {Boolean}
38100
+ */
38101
+ expandAbbreviationHandler: function(editor, syntax, profile) {
38102
+ var info = editorUtils.outputInfo(editor, syntax, profile);
38103
+ if (!~cssSyntaxes.indexOf(info.syntax)) {
38104
+ return false;
38105
+ }
38106
+
38107
+ // let's see if we are expanding gradient definition
38108
+ var caret = editor.getCaretPos();
38109
+ var content = info.content;
38110
+ var gradients = this.gradientsFromCSSProperty(content, caret);
38111
+ if (gradients) {
38112
+ if (!isValidCaretPosition(gradients, caret, info.syntax)) {
38113
+ return false;
38114
+ }
38115
+
38116
+ var cssProperty = gradients.property;
38117
+ var cssRule = cssProperty.parent;
38118
+ var ruleStart = cssRule.options.offset || 0;
38119
+ var ruleEnd = ruleStart + cssRule.toString().length;
38120
+
38121
+ // Handle special case:
38122
+ // user wrote gradient definition between existing CSS
38123
+ // properties and did not finished it with semicolon.
38124
+ // In this case, we have semicolon right after gradient
38125
+ // definition and re-parse rule again
38126
+ if (/[\n\r]/.test(cssProperty.value())) {
38127
+ // insert semicolon at the end of gradient definition
38128
+ var insertPos = cssProperty.valueRange(true).start + utils.last(gradients.gradients).matchedPart.end;
38129
+ content = utils.replaceSubstring(content, ';', insertPos);
38130
+
38131
+ var _gradients = this.gradientsFromCSSProperty(content, caret);
38132
+ if (_gradients) {
38133
+ gradients = _gradients;
38134
+ cssProperty = gradients.property;
38135
+ cssRule = cssProperty.parent;
38136
+ }
38137
+ }
38138
+
38139
+ // make sure current property has terminating semicolon
38140
+ cssProperty.end(';');
38141
+
38142
+ // resolve CSS property name
38143
+ var resolvedName = resolvePropertyName(cssProperty.name(), syntax);
38144
+ if (resolvedName) {
38145
+ cssProperty.name(resolvedName);
38146
+ }
38147
+
38148
+ pasteGradient(cssProperty, gradients.gradients);
38149
+ editor.replaceContent(cssRule.toString(), ruleStart, ruleEnd, true);
38150
+ return true;
38151
+ }
38152
+
38153
+ return this.expandGradientOutsideValue(editor, syntax);
38154
+ },
38155
+
38156
+ /**
38157
+ * Tries to expand gradient outside CSS value
38158
+ * @param {IEmmetEditor} editor
38159
+ * @param {String} syntax
38160
+ */
38161
+ expandGradientOutsideValue: function(editor, syntax) {
38162
+ var propertyName = prefs.get('css.gradient.defaultProperty');
38163
+ var omitDir = prefs.get('css.gradient.omitDefaultDirection');
38164
+
38165
+ if (!propertyName) {
38166
+ return false;
38167
+ }
38168
+
38169
+ // assuming that gradient definition is written on new line,
38170
+ // do a simplified parsing
38171
+ var content = String(editor.getContent());
38172
+ /** @type Range */
38173
+ var lineRange = range.create(editor.getCurrentLineRange());
38174
+
38175
+ // get line content and adjust range with padding
38176
+ var line = lineRange.substring(content)
38177
+ .replace(/^\s+/, function(pad) {
38178
+ lineRange.start += pad.length;
38179
+ return '';
38180
+ })
38181
+ .replace(/\s+$/, function(pad) {
38182
+ lineRange.end -= pad.length;
38183
+ return '';
38184
+ });
38185
+
38186
+ // trick parser: make it think that we’re parsing actual CSS property
38187
+ var fakeCSS = 'a{' + propertyName + ': ' + line + ';}';
38188
+ var gradients = this.gradientsFromCSSProperty(fakeCSS, fakeCSS.length - 2);
38189
+ if (gradients) {
38190
+ var props = getPropertiesForGradient(gradients.gradients, gradients.property);
38191
+ props.push({
38192
+ name: gradients.property.name(),
38193
+ value: insertGradientsIntoCSSValue(gradients.gradients, gradients.property.value(), {
38194
+ placeholder: '${2}',
38195
+ omitDefaultDirection: omitDir
38196
+ })
38197
+ });
38198
+
38199
+ var sep = cssResolver.getSyntaxPreference('valueSeparator', syntax);
38200
+ var end = cssResolver.getSyntaxPreference('propertyEnd', syntax);
38201
+
38202
+ if (prefs.get('css.alignVendor')) {
38203
+ var pads = utils.getStringsPads(props.map(function(prop) {
38204
+ return prop.value.substring(0, prop.value.indexOf('('));
38205
+ }));
38206
+ props.forEach(function(prop, i) {
38207
+ prop.value = pads[i] + prop.value;
38208
+ });
38209
+ }
38210
+
38211
+ props = props.map(function(item) {
38212
+ return item.name + sep + item.value + end;
38213
+ });
38214
+
38215
+ editor.replaceContent(props.join('\n'), lineRange.start, lineRange.end);
38216
+ return true;
38217
+ }
38218
+
38219
+ return false;
38220
+ },
38221
+
38222
+ /**
38223
+ * Handler for “Reflect CSS Value“ action
38224
+ * @param {String} property
38225
+ */
38226
+ reflectValueHandler: function(property) {
38227
+ var o