npm2gem 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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);