npm2gem 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +241 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +4 -0
  7. data/CODE_OF_CONDUCT.md +111 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +102 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +7 -0
  14. data/exe/npm2gem +8 -0
  15. data/lib/npm2gem/cli.rb +56 -0
  16. data/lib/npm2gem/config.rb +21 -0
  17. data/lib/npm2gem/exception.rb +4 -0
  18. data/lib/npm2gem/file_copier.rb +65 -0
  19. data/lib/npm2gem/gem_version_updater.rb +42 -0
  20. data/lib/npm2gem/npm_install.rb +36 -0
  21. data/lib/npm2gem/version.rb +3 -0
  22. data/lib/npm2gem/version_updaters/base_file_updater.rb +29 -0
  23. data/lib/npm2gem/version_updaters/gemspec_updater.rb +12 -0
  24. data/lib/npm2gem/version_updaters/version_file_updater.rb +18 -0
  25. data/lib/npm2gem.rb +5 -0
  26. data/npm2gem.gemspec +31 -0
  27. data/spec/cli_spec.rb +22 -0
  28. data/spec/config_spec.rb +40 -0
  29. data/spec/dummy/Gemfile +4 -0
  30. data/spec/dummy/README.md +7 -0
  31. data/spec/dummy/Rakefile +6 -0
  32. data/spec/dummy/dummy.gemspec +31 -0
  33. data/spec/dummy/lib/dummy/version.rb +3 -0
  34. data/spec/dummy/lib/dummy.rb +8 -0
  35. data/spec/dummy/node_modules/bootstrap/CHANGELOG.md +5 -0
  36. data/spec/dummy/node_modules/bootstrap/Gruntfile.js +533 -0
  37. data/spec/dummy/node_modules/bootstrap/LICENSE +21 -0
  38. data/spec/dummy/node_modules/bootstrap/README.md +139 -0
  39. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap-theme.css +587 -0
  40. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap-theme.css.map +1 -0
  41. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap-theme.min.css +6 -0
  42. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap-theme.min.css.map +1 -0
  43. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap.css +6760 -0
  44. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap.css.map +1 -0
  45. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap.min.css +6 -0
  46. data/spec/dummy/node_modules/bootstrap/dist/css/bootstrap.min.css.map +1 -0
  47. data/spec/dummy/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.eot +0 -0
  48. data/spec/dummy/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.svg +288 -0
  49. data/spec/dummy/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  50. data/spec/dummy/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff +0 -0
  51. data/spec/dummy/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
  52. data/spec/dummy/node_modules/bootstrap/dist/js/bootstrap.js +2363 -0
  53. data/spec/dummy/node_modules/bootstrap/dist/js/bootstrap.min.js +7 -0
  54. data/spec/dummy/node_modules/bootstrap/dist/js/npm.js +13 -0
  55. data/spec/dummy/node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  56. data/spec/dummy/node_modules/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
  57. data/spec/dummy/node_modules/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  58. data/spec/dummy/node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  59. data/spec/dummy/node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  60. data/spec/dummy/node_modules/bootstrap/grunt/bs-commonjs-generator.js +30 -0
  61. data/spec/dummy/node_modules/bootstrap/grunt/bs-glyphicons-data-generator.js +42 -0
  62. data/spec/dummy/node_modules/bootstrap/grunt/bs-lessdoc-parser.js +237 -0
  63. data/spec/dummy/node_modules/bootstrap/grunt/bs-raw-files-generator.js +44 -0
  64. data/spec/dummy/node_modules/bootstrap/grunt/configBridge.json +46 -0
  65. data/spec/dummy/node_modules/bootstrap/grunt/sauce_browsers.yml +82 -0
  66. data/spec/dummy/node_modules/bootstrap/js/affix.js +162 -0
  67. data/spec/dummy/node_modules/bootstrap/js/alert.js +94 -0
  68. data/spec/dummy/node_modules/bootstrap/js/button.js +120 -0
  69. data/spec/dummy/node_modules/bootstrap/js/carousel.js +237 -0
  70. data/spec/dummy/node_modules/bootstrap/js/collapse.js +211 -0
  71. data/spec/dummy/node_modules/bootstrap/js/dropdown.js +165 -0
  72. data/spec/dummy/node_modules/bootstrap/js/modal.js +337 -0
  73. data/spec/dummy/node_modules/bootstrap/js/popover.js +108 -0
  74. data/spec/dummy/node_modules/bootstrap/js/scrollspy.js +172 -0
  75. data/spec/dummy/node_modules/bootstrap/js/tab.js +155 -0
  76. data/spec/dummy/node_modules/bootstrap/js/tooltip.js +514 -0
  77. data/spec/dummy/node_modules/bootstrap/js/transition.js +59 -0
  78. data/spec/dummy/node_modules/bootstrap/less/alerts.less +73 -0
  79. data/spec/dummy/node_modules/bootstrap/less/badges.less +66 -0
  80. data/spec/dummy/node_modules/bootstrap/less/bootstrap.less +56 -0
  81. data/spec/dummy/node_modules/bootstrap/less/breadcrumbs.less +26 -0
  82. data/spec/dummy/node_modules/bootstrap/less/button-groups.less +244 -0
  83. data/spec/dummy/node_modules/bootstrap/less/buttons.less +166 -0
  84. data/spec/dummy/node_modules/bootstrap/less/carousel.less +270 -0
  85. data/spec/dummy/node_modules/bootstrap/less/close.less +34 -0
  86. data/spec/dummy/node_modules/bootstrap/less/code.less +69 -0
  87. data/spec/dummy/node_modules/bootstrap/less/component-animations.less +33 -0
  88. data/spec/dummy/node_modules/bootstrap/less/dropdowns.less +216 -0
  89. data/spec/dummy/node_modules/bootstrap/less/forms.less +613 -0
  90. data/spec/dummy/node_modules/bootstrap/less/glyphicons.less +305 -0
  91. data/spec/dummy/node_modules/bootstrap/less/grid.less +84 -0
  92. data/spec/dummy/node_modules/bootstrap/less/input-groups.less +171 -0
  93. data/spec/dummy/node_modules/bootstrap/less/jumbotron.less +54 -0
  94. data/spec/dummy/node_modules/bootstrap/less/labels.less +64 -0
  95. data/spec/dummy/node_modules/bootstrap/less/list-group.less +130 -0
  96. data/spec/dummy/node_modules/bootstrap/less/media.less +66 -0
  97. data/spec/dummy/node_modules/bootstrap/less/mixins/alerts.less +14 -0
  98. data/spec/dummy/node_modules/bootstrap/less/mixins/background-variant.less +9 -0
  99. data/spec/dummy/node_modules/bootstrap/less/mixins/border-radius.less +18 -0
  100. data/spec/dummy/node_modules/bootstrap/less/mixins/buttons.less +65 -0
  101. data/spec/dummy/node_modules/bootstrap/less/mixins/center-block.less +7 -0
  102. data/spec/dummy/node_modules/bootstrap/less/mixins/clearfix.less +22 -0
  103. data/spec/dummy/node_modules/bootstrap/less/mixins/forms.less +85 -0
  104. data/spec/dummy/node_modules/bootstrap/less/mixins/gradients.less +59 -0
  105. data/spec/dummy/node_modules/bootstrap/less/mixins/grid-framework.less +91 -0
  106. data/spec/dummy/node_modules/bootstrap/less/mixins/grid.less +122 -0
  107. data/spec/dummy/node_modules/bootstrap/less/mixins/hide-text.less +21 -0
  108. data/spec/dummy/node_modules/bootstrap/less/mixins/image.less +33 -0
  109. data/spec/dummy/node_modules/bootstrap/less/mixins/labels.less +12 -0
  110. data/spec/dummy/node_modules/bootstrap/less/mixins/list-group.less +30 -0
  111. data/spec/dummy/node_modules/bootstrap/less/mixins/nav-divider.less +10 -0
  112. data/spec/dummy/node_modules/bootstrap/less/mixins/nav-vertical-align.less +9 -0
  113. data/spec/dummy/node_modules/bootstrap/less/mixins/opacity.less +8 -0
  114. data/spec/dummy/node_modules/bootstrap/less/mixins/pagination.less +24 -0
  115. data/spec/dummy/node_modules/bootstrap/less/mixins/panels.less +24 -0
  116. data/spec/dummy/node_modules/bootstrap/less/mixins/progress-bar.less +10 -0
  117. data/spec/dummy/node_modules/bootstrap/less/mixins/reset-filter.less +8 -0
  118. data/spec/dummy/node_modules/bootstrap/less/mixins/reset-text.less +18 -0
  119. data/spec/dummy/node_modules/bootstrap/less/mixins/resize.less +6 -0
  120. data/spec/dummy/node_modules/bootstrap/less/mixins/responsive-visibility.less +15 -0
  121. data/spec/dummy/node_modules/bootstrap/less/mixins/size.less +10 -0
  122. data/spec/dummy/node_modules/bootstrap/less/mixins/tab-focus.less +9 -0
  123. data/spec/dummy/node_modules/bootstrap/less/mixins/table-row.less +28 -0
  124. data/spec/dummy/node_modules/bootstrap/less/mixins/text-emphasis.less +9 -0
  125. data/spec/dummy/node_modules/bootstrap/less/mixins/text-overflow.less +8 -0
  126. data/spec/dummy/node_modules/bootstrap/less/mixins/vendor-prefixes.less +227 -0
  127. data/spec/dummy/node_modules/bootstrap/less/mixins.less +40 -0
  128. data/spec/dummy/node_modules/bootstrap/less/modals.less +150 -0
  129. data/spec/dummy/node_modules/bootstrap/less/navbar.less +660 -0
  130. data/spec/dummy/node_modules/bootstrap/less/navs.less +242 -0
  131. data/spec/dummy/node_modules/bootstrap/less/normalize.less +424 -0
  132. data/spec/dummy/node_modules/bootstrap/less/pager.less +54 -0
  133. data/spec/dummy/node_modules/bootstrap/less/pagination.less +89 -0
  134. data/spec/dummy/node_modules/bootstrap/less/panels.less +271 -0
  135. data/spec/dummy/node_modules/bootstrap/less/popovers.less +131 -0
  136. data/spec/dummy/node_modules/bootstrap/less/print.less +101 -0
  137. data/spec/dummy/node_modules/bootstrap/less/progress-bars.less +87 -0
  138. data/spec/dummy/node_modules/bootstrap/less/responsive-embed.less +35 -0
  139. data/spec/dummy/node_modules/bootstrap/less/responsive-utilities.less +194 -0
  140. data/spec/dummy/node_modules/bootstrap/less/scaffolding.less +161 -0
  141. data/spec/dummy/node_modules/bootstrap/less/tables.less +234 -0
  142. data/spec/dummy/node_modules/bootstrap/less/theme.less +291 -0
  143. data/spec/dummy/node_modules/bootstrap/less/thumbnails.less +36 -0
  144. data/spec/dummy/node_modules/bootstrap/less/tooltip.less +101 -0
  145. data/spec/dummy/node_modules/bootstrap/less/type.less +302 -0
  146. data/spec/dummy/node_modules/bootstrap/less/utilities.less +55 -0
  147. data/spec/dummy/node_modules/bootstrap/less/variables.less +869 -0
  148. data/spec/dummy/node_modules/bootstrap/less/wells.less +29 -0
  149. data/spec/dummy/node_modules/bootstrap/package.json +138 -0
  150. data/spec/dummy/vendor/assets/javascripts/bootstrap.js +2363 -0
  151. data/spec/dummy/vendor/assets/stylesheets/bootstrap-theme.css +587 -0
  152. data/spec/dummy/vendor/assets/stylesheets/bootstrap.css +6760 -0
  153. data/spec/file_copier_spec.rb +45 -0
  154. data/spec/gem_version_updater_spec.rb +45 -0
  155. data/spec/npm2gem_spec.rb +7 -0
  156. data/spec/npm_install_spec.rb +22 -0
  157. data/spec/spec_helper.rb +26 -0
  158. metadata +403 -0
@@ -0,0 +1,237 @@
1
+ /*!
2
+ * Bootstrap Grunt task for parsing Less docstrings
3
+ * http://getbootstrap.com
4
+ * Copyright 2014-2015 Twitter, Inc.
5
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ var Markdown = require('markdown-it');
11
+
12
+ function markdown2html(markdownString) {
13
+ var md = new Markdown();
14
+
15
+ // the slice removes the <p>...</p> wrapper output by Markdown processor
16
+ return md.render(markdownString.trim()).slice(3, -5);
17
+ }
18
+
19
+
20
+ /*
21
+ Mini-language:
22
+ //== This is a normal heading, which starts a section. Sections group variables together.
23
+ //## Optional description for the heading
24
+
25
+ //=== This is a subheading.
26
+
27
+ //** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `<html>` stuff.
28
+ @foo: #fff;
29
+
30
+ //-- This is a heading for a section whose variables shouldn't be customizable
31
+
32
+ All other lines are ignored completely.
33
+ */
34
+
35
+
36
+ var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/;
37
+ var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/;
38
+ var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/;
39
+ var SECTION_DOCSTRING = /^[/]{2}#{2}(.+)$/;
40
+ var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]*);[ ]*$/;
41
+ var VAR_DOCSTRING = /^[/]{2}[*]{2}(.+)$/;
42
+
43
+ function Section(heading, customizable) {
44
+ this.heading = heading.trim();
45
+ this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
46
+ this.customizable = customizable;
47
+ this.docstring = null;
48
+ this.subsections = [];
49
+ }
50
+
51
+ Section.prototype.addSubSection = function (subsection) {
52
+ this.subsections.push(subsection);
53
+ };
54
+
55
+ function SubSection(heading) {
56
+ this.heading = heading.trim();
57
+ this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
58
+ this.variables = [];
59
+ }
60
+
61
+ SubSection.prototype.addVar = function (variable) {
62
+ this.variables.push(variable);
63
+ };
64
+
65
+ function VarDocstring(markdownString) {
66
+ this.html = markdown2html(markdownString);
67
+ }
68
+
69
+ function SectionDocstring(markdownString) {
70
+ this.html = markdown2html(markdownString);
71
+ }
72
+
73
+ function Variable(name, defaultValue) {
74
+ this.name = name;
75
+ this.defaultValue = defaultValue;
76
+ this.docstring = null;
77
+ }
78
+
79
+ function Tokenizer(fileContent) {
80
+ this._lines = fileContent.split('\n');
81
+ this._next = undefined;
82
+ }
83
+
84
+ Tokenizer.prototype.unshift = function (token) {
85
+ if (this._next !== undefined) {
86
+ throw new Error('Attempted to unshift twice!');
87
+ }
88
+ this._next = token;
89
+ };
90
+
91
+ Tokenizer.prototype._shift = function () {
92
+ // returning null signals EOF
93
+ // returning undefined means the line was ignored
94
+ if (this._next !== undefined) {
95
+ var result = this._next;
96
+ this._next = undefined;
97
+ return result;
98
+ }
99
+ if (this._lines.length <= 0) {
100
+ return null;
101
+ }
102
+ var line = this._lines.shift();
103
+ var match = null;
104
+ match = SUBSECTION_HEADING.exec(line);
105
+ if (match !== null) {
106
+ return new SubSection(match[1]);
107
+ }
108
+ match = CUSTOMIZABLE_HEADING.exec(line);
109
+ if (match !== null) {
110
+ return new Section(match[1], true);
111
+ }
112
+ match = UNCUSTOMIZABLE_HEADING.exec(line);
113
+ if (match !== null) {
114
+ return new Section(match[1], false);
115
+ }
116
+ match = SECTION_DOCSTRING.exec(line);
117
+ if (match !== null) {
118
+ return new SectionDocstring(match[1]);
119
+ }
120
+ match = VAR_DOCSTRING.exec(line);
121
+ if (match !== null) {
122
+ return new VarDocstring(match[1]);
123
+ }
124
+ var commentStart = line.lastIndexOf('//');
125
+ var varLine = commentStart === -1 ? line : line.slice(0, commentStart);
126
+ match = VAR_ASSIGNMENT.exec(varLine);
127
+ if (match !== null) {
128
+ return new Variable(match[1], match[2]);
129
+ }
130
+ return undefined;
131
+ };
132
+
133
+ Tokenizer.prototype.shift = function () {
134
+ while (true) {
135
+ var result = this._shift();
136
+ if (result === undefined) {
137
+ continue;
138
+ }
139
+ return result;
140
+ }
141
+ };
142
+
143
+ function Parser(fileContent) {
144
+ this._tokenizer = new Tokenizer(fileContent);
145
+ }
146
+
147
+ Parser.prototype.parseFile = function () {
148
+ var sections = [];
149
+ while (true) {
150
+ var section = this.parseSection();
151
+ if (section === null) {
152
+ if (this._tokenizer.shift() !== null) {
153
+ throw new Error('Unexpected unparsed section of file remains!');
154
+ }
155
+ return sections;
156
+ }
157
+ sections.push(section);
158
+ }
159
+ };
160
+
161
+ Parser.prototype.parseSection = function () {
162
+ var section = this._tokenizer.shift();
163
+ if (section === null) {
164
+ return null;
165
+ }
166
+ if (!(section instanceof Section)) {
167
+ throw new Error('Expected section heading; got: ' + JSON.stringify(section));
168
+ }
169
+ var docstring = this._tokenizer.shift();
170
+ if (docstring instanceof SectionDocstring) {
171
+ section.docstring = docstring;
172
+ } else {
173
+ this._tokenizer.unshift(docstring);
174
+ }
175
+ this.parseSubSections(section);
176
+
177
+ return section;
178
+ };
179
+
180
+ Parser.prototype.parseSubSections = function (section) {
181
+ while (true) {
182
+ var subsection = this.parseSubSection();
183
+ if (subsection === null) {
184
+ if (section.subsections.length === 0) {
185
+ // Presume an implicit initial subsection
186
+ subsection = new SubSection('');
187
+ this.parseVars(subsection);
188
+ } else {
189
+ break;
190
+ }
191
+ }
192
+ section.addSubSection(subsection);
193
+ }
194
+
195
+ if (section.subsections.length === 1 && !section.subsections[0].heading && section.subsections[0].variables.length === 0) {
196
+ // Ignore lone empty implicit subsection
197
+ section.subsections = [];
198
+ }
199
+ };
200
+
201
+ Parser.prototype.parseSubSection = function () {
202
+ var subsection = this._tokenizer.shift();
203
+ if (subsection instanceof SubSection) {
204
+ this.parseVars(subsection);
205
+ return subsection;
206
+ }
207
+ this._tokenizer.unshift(subsection);
208
+ return null;
209
+ };
210
+
211
+ Parser.prototype.parseVars = function (subsection) {
212
+ while (true) {
213
+ var variable = this.parseVar();
214
+ if (variable === null) {
215
+ return;
216
+ }
217
+ subsection.addVar(variable);
218
+ }
219
+ };
220
+
221
+ Parser.prototype.parseVar = function () {
222
+ var docstring = this._tokenizer.shift();
223
+ if (!(docstring instanceof VarDocstring)) {
224
+ this._tokenizer.unshift(docstring);
225
+ docstring = null;
226
+ }
227
+ var variable = this._tokenizer.shift();
228
+ if (variable instanceof Variable) {
229
+ variable.docstring = docstring;
230
+ return variable;
231
+ }
232
+ this._tokenizer.unshift(variable);
233
+ return null;
234
+ };
235
+
236
+
237
+ module.exports = Parser;
@@ -0,0 +1,44 @@
1
+ /*!
2
+ * Bootstrap Grunt task for generating raw-files.min.js for the Customizer
3
+ * http://getbootstrap.com
4
+ * Copyright 2014-2015 Twitter, Inc.
5
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ var fs = require('fs');
11
+ var btoa = require('btoa');
12
+ var glob = require('glob');
13
+
14
+ function getFiles(type) {
15
+ var files = {};
16
+ var recursive = type === 'less';
17
+ var globExpr = recursive ? '/**/*' : '/*';
18
+ glob.sync(type + globExpr)
19
+ .filter(function (path) {
20
+ return type === 'fonts' ? true : new RegExp('\\.' + type + '$').test(path);
21
+ })
22
+ .forEach(function (fullPath) {
23
+ var relativePath = fullPath.replace(/^[^/]+\//, '');
24
+ files[relativePath] = type === 'fonts' ? btoa(fs.readFileSync(fullPath)) : fs.readFileSync(fullPath, 'utf8');
25
+ });
26
+ return 'var __' + type + ' = ' + JSON.stringify(files) + '\n';
27
+ }
28
+
29
+ module.exports = function generateRawFilesJs(grunt, banner) {
30
+ if (!banner) {
31
+ banner = '';
32
+ }
33
+ var dirs = ['js', 'less', 'fonts'];
34
+ var files = banner + dirs.map(getFiles).reduce(function (combined, file) {
35
+ return combined + file;
36
+ }, '');
37
+ var rawFilesJs = 'docs/assets/js/raw-files.min.js';
38
+ try {
39
+ fs.writeFileSync(rawFilesJs, files);
40
+ } catch (err) {
41
+ grunt.fail.warn(err);
42
+ }
43
+ grunt.log.writeln('File ' + rawFilesJs.cyan + ' created.');
44
+ };
@@ -0,0 +1,46 @@
1
+ {
2
+ "paths": {
3
+ "customizerJs": [
4
+ "../assets/js/vendor/autoprefixer.js",
5
+ "../assets/js/vendor/less.min.js",
6
+ "../assets/js/vendor/jszip.min.js",
7
+ "../assets/js/vendor/uglify.min.js",
8
+ "../assets/js/vendor/Blob.js",
9
+ "../assets/js/vendor/FileSaver.js",
10
+ "../assets/js/raw-files.min.js",
11
+ "../assets/js/src/customizer.js"
12
+ ],
13
+ "docsJs": [
14
+ "../assets/js/vendor/holder.min.js",
15
+ "../assets/js/vendor/ZeroClipboard.min.js",
16
+ "../assets/js/vendor/anchor.js",
17
+ "../assets/js/src/application.js"
18
+ ]
19
+ },
20
+ "config": {
21
+ "autoprefixerBrowsers": [
22
+ "Android 2.3",
23
+ "Android >= 4",
24
+ "Chrome >= 20",
25
+ "Firefox >= 24",
26
+ "Explorer >= 8",
27
+ "iOS >= 6",
28
+ "Opera >= 12",
29
+ "Safari >= 6"
30
+ ],
31
+ "jqueryCheck": [
32
+ "if (typeof jQuery === 'undefined') {",
33
+ " throw new Error('Bootstrap\\'s JavaScript requires jQuery')",
34
+ "}\n"
35
+ ],
36
+ "jqueryVersionCheck": [
37
+ "+function ($) {",
38
+ " 'use strict';",
39
+ " var version = $.fn.jquery.split(' ')[0].split('.')",
40
+ " if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {",
41
+ " throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')",
42
+ " }",
43
+ "}(jQuery);\n\n"
44
+ ]
45
+ }
46
+ }
@@ -0,0 +1,82 @@
1
+ [
2
+ # Docs: https://saucelabs.com/docs/platforms/webdriver
3
+
4
+ {
5
+ browserName: "safari",
6
+ platform: "OS X 10.10"
7
+ },
8
+ {
9
+ browserName: "chrome",
10
+ platform: "OS X 10.10"
11
+ },
12
+ {
13
+ browserName: "firefox",
14
+ platform: "OS X 10.10"
15
+ },
16
+
17
+ # Mac Opera not currently supported by Sauce Labs
18
+
19
+ {
20
+ browserName: "internet explorer",
21
+ version: "11",
22
+ platform: "Windows 8.1"
23
+ },
24
+ {
25
+ browserName: "internet explorer",
26
+ version: "10",
27
+ platform: "Windows 8"
28
+ },
29
+ {
30
+ browserName: "internet explorer",
31
+ version: "9",
32
+ platform: "Windows 7"
33
+ },
34
+ {
35
+ browserName: "internet explorer",
36
+ version: "8",
37
+ platform: "Windows 7"
38
+ },
39
+
40
+ # { # Unofficial
41
+ # browserName: "internet explorer",
42
+ # version: "7",
43
+ # platform: "Windows XP"
44
+ # },
45
+
46
+ {
47
+ browserName: "chrome",
48
+ platform: "Windows 8.1"
49
+ },
50
+ {
51
+ browserName: "firefox",
52
+ platform: "Windows 8.1"
53
+ },
54
+
55
+ # Win Opera 15+ not currently supported by Sauce Labs
56
+
57
+ {
58
+ browserName: "iphone",
59
+ platform: "OS X 10.10",
60
+ version: "8.2"
61
+ },
62
+
63
+ # iOS Chrome not currently supported by Sauce Labs
64
+
65
+ # Linux (unofficial)
66
+ {
67
+ browserName: "chrome",
68
+ platform: "Linux"
69
+ },
70
+ {
71
+ browserName: "firefox",
72
+ platform: "Linux"
73
+ }
74
+
75
+ # Android Chrome not currently supported by Sauce Labs
76
+
77
+ # { # Android Browser (super-unofficial)
78
+ # browserName: "android",
79
+ # version: "4.0",
80
+ # platform: "Linux"
81
+ # }
82
+ ]
@@ -0,0 +1,162 @@
1
+ /* ========================================================================
2
+ * Bootstrap: affix.js v3.3.6
3
+ * http://getbootstrap.com/javascript/#affix
4
+ * ========================================================================
5
+ * Copyright 2011-2015 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // AFFIX CLASS DEFINITION
14
+ // ======================
15
+
16
+ var Affix = function (element, options) {
17
+ this.options = $.extend({}, Affix.DEFAULTS, options)
18
+
19
+ this.$target = $(this.options.target)
20
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
21
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
22
+
23
+ this.$element = $(element)
24
+ this.affixed = null
25
+ this.unpin = null
26
+ this.pinnedOffset = null
27
+
28
+ this.checkPosition()
29
+ }
30
+
31
+ Affix.VERSION = '3.3.6'
32
+
33
+ Affix.RESET = 'affix affix-top affix-bottom'
34
+
35
+ Affix.DEFAULTS = {
36
+ offset: 0,
37
+ target: window
38
+ }
39
+
40
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
41
+ var scrollTop = this.$target.scrollTop()
42
+ var position = this.$element.offset()
43
+ var targetHeight = this.$target.height()
44
+
45
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
46
+
47
+ if (this.affixed == 'bottom') {
48
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
49
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
50
+ }
51
+
52
+ var initializing = this.affixed == null
53
+ var colliderTop = initializing ? scrollTop : position.top
54
+ var colliderHeight = initializing ? targetHeight : height
55
+
56
+ if (offsetTop != null && scrollTop <= offsetTop) return 'top'
57
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
58
+
59
+ return false
60
+ }
61
+
62
+ Affix.prototype.getPinnedOffset = function () {
63
+ if (this.pinnedOffset) return this.pinnedOffset
64
+ this.$element.removeClass(Affix.RESET).addClass('affix')
65
+ var scrollTop = this.$target.scrollTop()
66
+ var position = this.$element.offset()
67
+ return (this.pinnedOffset = position.top - scrollTop)
68
+ }
69
+
70
+ Affix.prototype.checkPositionWithEventLoop = function () {
71
+ setTimeout($.proxy(this.checkPosition, this), 1)
72
+ }
73
+
74
+ Affix.prototype.checkPosition = function () {
75
+ if (!this.$element.is(':visible')) return
76
+
77
+ var height = this.$element.height()
78
+ var offset = this.options.offset
79
+ var offsetTop = offset.top
80
+ var offsetBottom = offset.bottom
81
+ var scrollHeight = Math.max($(document).height(), $(document.body).height())
82
+
83
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
84
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
85
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
86
+
87
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
88
+
89
+ if (this.affixed != affix) {
90
+ if (this.unpin != null) this.$element.css('top', '')
91
+
92
+ var affixType = 'affix' + (affix ? '-' + affix : '')
93
+ var e = $.Event(affixType + '.bs.affix')
94
+
95
+ this.$element.trigger(e)
96
+
97
+ if (e.isDefaultPrevented()) return
98
+
99
+ this.affixed = affix
100
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
101
+
102
+ this.$element
103
+ .removeClass(Affix.RESET)
104
+ .addClass(affixType)
105
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
106
+ }
107
+
108
+ if (affix == 'bottom') {
109
+ this.$element.offset({
110
+ top: scrollHeight - height - offsetBottom
111
+ })
112
+ }
113
+ }
114
+
115
+
116
+ // AFFIX PLUGIN DEFINITION
117
+ // =======================
118
+
119
+ function Plugin(option) {
120
+ return this.each(function () {
121
+ var $this = $(this)
122
+ var data = $this.data('bs.affix')
123
+ var options = typeof option == 'object' && option
124
+
125
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
126
+ if (typeof option == 'string') data[option]()
127
+ })
128
+ }
129
+
130
+ var old = $.fn.affix
131
+
132
+ $.fn.affix = Plugin
133
+ $.fn.affix.Constructor = Affix
134
+
135
+
136
+ // AFFIX NO CONFLICT
137
+ // =================
138
+
139
+ $.fn.affix.noConflict = function () {
140
+ $.fn.affix = old
141
+ return this
142
+ }
143
+
144
+
145
+ // AFFIX DATA-API
146
+ // ==============
147
+
148
+ $(window).on('load', function () {
149
+ $('[data-spy="affix"]').each(function () {
150
+ var $spy = $(this)
151
+ var data = $spy.data()
152
+
153
+ data.offset = data.offset || {}
154
+
155
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
156
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
157
+
158
+ Plugin.call($spy, data)
159
+ })
160
+ })
161
+
162
+ }(jQuery);
@@ -0,0 +1,94 @@
1
+ /* ========================================================================
2
+ * Bootstrap: alert.js v3.3.6
3
+ * http://getbootstrap.com/javascript/#alerts
4
+ * ========================================================================
5
+ * Copyright 2011-2015 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // ALERT CLASS DEFINITION
14
+ // ======================
15
+
16
+ var dismiss = '[data-dismiss="alert"]'
17
+ var Alert = function (el) {
18
+ $(el).on('click', dismiss, this.close)
19
+ }
20
+
21
+ Alert.VERSION = '3.3.6'
22
+
23
+ Alert.TRANSITION_DURATION = 150
24
+
25
+ Alert.prototype.close = function (e) {
26
+ var $this = $(this)
27
+ var selector = $this.attr('data-target')
28
+
29
+ if (!selector) {
30
+ selector = $this.attr('href')
31
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
32
+ }
33
+
34
+ var $parent = $(selector)
35
+
36
+ if (e) e.preventDefault()
37
+
38
+ if (!$parent.length) {
39
+ $parent = $this.closest('.alert')
40
+ }
41
+
42
+ $parent.trigger(e = $.Event('close.bs.alert'))
43
+
44
+ if (e.isDefaultPrevented()) return
45
+
46
+ $parent.removeClass('in')
47
+
48
+ function removeElement() {
49
+ // detach from parent, fire event then clean up data
50
+ $parent.detach().trigger('closed.bs.alert').remove()
51
+ }
52
+
53
+ $.support.transition && $parent.hasClass('fade') ?
54
+ $parent
55
+ .one('bsTransitionEnd', removeElement)
56
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
57
+ removeElement()
58
+ }
59
+
60
+
61
+ // ALERT PLUGIN DEFINITION
62
+ // =======================
63
+
64
+ function Plugin(option) {
65
+ return this.each(function () {
66
+ var $this = $(this)
67
+ var data = $this.data('bs.alert')
68
+
69
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
70
+ if (typeof option == 'string') data[option].call($this)
71
+ })
72
+ }
73
+
74
+ var old = $.fn.alert
75
+
76
+ $.fn.alert = Plugin
77
+ $.fn.alert.Constructor = Alert
78
+
79
+
80
+ // ALERT NO CONFLICT
81
+ // =================
82
+
83
+ $.fn.alert.noConflict = function () {
84
+ $.fn.alert = old
85
+ return this
86
+ }
87
+
88
+
89
+ // ALERT DATA-API
90
+ // ==============
91
+
92
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
93
+
94
+ }(jQuery);