├── .gitignore
├── .travis.yml
├── Gruntfile.js
├── LICENSE
├── README.md
├── dashboards
├── chronix-grafana-csv-file-example.json
└── chronix-grafana-default-dashboard.json
├── dist
├── README.md
├── config-controller.js
├── config-controller.js.map
├── datasource.js
├── datasource.js.map
├── img
│ ├── logo.png
│ └── screenshot.png
├── module.js
├── module.js.map
├── partials
│ ├── config.html
│ └── query.editor.html
├── plugin.json
├── query-controller.js
└── query-controller.js.map
├── img
├── logo.png
└── screenshot.png
├── package.json
├── plugin.json
├── src
├── config-controller.js
├── datasource.js
├── module.js
├── partials
│ ├── config.html
│ └── query.editor.html
└── query-controller.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12 | hs_err_pid*
13 |
14 | .idea
15 |
16 | grafana-*
17 |
18 | node_modules
19 | npm-debug-log
20 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: node
3 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 |
3 | require('load-grunt-tasks')(grunt);
4 |
5 | grunt.initConfig({
6 |
7 | clean: ['dist'],
8 |
9 | copy: {
10 | srcAssets: {
11 | cwd: 'src',
12 | expand: true,
13 | src: ['**/*', '!**/*.js'],
14 | dest: 'dist'
15 | },
16 | pluginAssets: {
17 | cwd: '.',
18 | expand: true,
19 | src: ['plugin.json', 'README.md', 'img/**/*'],
20 | dest: 'dist'
21 | }
22 | },
23 |
24 | babel: {
25 | options: {
26 | sourceMap: true,
27 | presets: ['es2015'],
28 | plugins: ['transform-es2015-modules-systemjs', 'transform-es2015-for-of']
29 | },
30 | dist: {
31 | files: [{
32 | cwd: 'src',
33 | expand: true,
34 | src: ['**/*.js'],
35 | dest: 'dist',
36 | ext: '.js'
37 | }]
38 | }
39 | },
40 |
41 | watch: {
42 | src: {
43 | files: ['src/**/*.js'],
44 | tasks: ['babel'],
45 | options: {
46 | spawn: false,
47 | atBegin: true
48 | }
49 | },
50 | srcAssets: {
51 | files: ['**/*', '!**/*.js'],
52 | tasks: ['copy:srcAssets'],
53 | options: {
54 | spawn: false,
55 | atBegin: true
56 | }
57 | },
58 | pluginAssets: {
59 | files: ['plugin.json', 'README.md', 'img/**/*'],
60 | tasks: ['copy:pluginAssets'],
61 | options: {
62 | spawn: false,
63 | atBegin: true
64 | }
65 | }
66 | }
67 |
68 | });
69 |
70 | grunt.registerTask('default', ['clean', 'copy', 'babel']);
71 |
72 | grunt.registerTask('test', 'stub for tests', function () {
73 | grunt.log.ok();
74 | });
75 |
76 | };
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://gitter.im/ChronixDB/chronix.grafana?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2 | [](https://travis-ci.org/ChronixDB/chronix.grafana)
3 | [](https://dependencyci.com/github/ChronixDB/chronix.grafana)
4 | [](LICENSE)
5 |
6 | # Chronix Grafana Datasource Plugin
7 |
8 | This is a "datasource" plugin that lets you use time series from [Chronix-Server](https://github.com/ChronixDB/chronix.server)
9 | and visualize them with [Grafana](https://grafana.net/).
10 |
11 | It works with Grafana > 3.X.X.
12 |
13 | 
14 |
15 | ## Features
16 |
17 | The plugin supports all the native implemented aggregations, transformations, and analyses of Chronix-Server.
18 | We will provide more details soon ;-)
19 |
20 | ## Usage
21 |
22 | Currently, the plugin is only available at the chronix github repository. It is planned to release the plugin within
23 | the app store of grafana.
24 |
25 | To use the plugin, simply clone this repository into your Grafana installation's `{inst-dir}/data/plugins/` directory.
26 |
27 | Optionally, you can download and start from the example dashboard:
28 |
29 | 1. Download and extract the latest [chronix.server](https://github.com/ChronixDB/chronix.server/releases/latest) and start it by cd'ing into the extracted directory and running `bin/solr start`.
30 | 2. Download and extract the latest *importer.zip* from the latest [chronix.examples](https://github.com/ChronixDB/chronix.examples/releases/latest) release and run it by cd'ing into the extracted folder and running `./import`.
31 | 3. Create a datasource called *Chronix* that points to http://localhost:8983/solr/chronix (no credentials needed).
32 | 4. Import the example dashboard(s) from 'dashboards' into your running Grafana.
33 |
34 | ## Contributing
35 |
36 | Is there anything missing? Do you have ideas for new features or improvements? You are highly welcome to contribute
37 | your improvements to the Chronix projects. All you have to do is to fork this repository, improve the code and issue a
38 | pull request.
39 |
40 | ## Developing the plugin
41 |
42 | ### Basics
43 |
44 | * All actual code sources live in `src` and can be written in ES6 / ES2015 - this allows us to use proper imports,
45 | exports and all the other syntactic goodies.
46 | * The `dist` folder is actually checked into git, too. We do this so that Grafana auto-detects the dist folder and uses
47 | it even if you just cloned the repository into Grafana (as described above).
48 | * This means that whenever you're changing something in `src`, you really should run the build at least once so that the
49 | contents of `dist` are "in sync", too, when you're committing / pushing / issuing a PR.
50 |
51 | ### Set up (only needs to be done once)
52 |
53 | Use a command prompt that provides NodeJS and NPM. In it, simply run
54 |
55 | npm install
56 |
57 | to install all (dev-) dependencies for the build.
58 |
59 | ### Changing stuff
60 |
61 | To run the build once in order to re-create the `dist` folder, run
62 |
63 | npm run build
64 |
65 | If you want the build to watch your `src` files and auto-run whenever you hit save, run
66 |
67 | npm run watch
68 |
69 | (you can end the watcher by pressing CTRL+C in that command prompt)
70 |
71 | ## Maintainer
72 |
73 | Florian Lautenschlager @flolaut
74 |
75 | ## License
76 |
77 | This software is provided under the Apache License, Version 2.0 license.
78 |
79 | See the [LICENSE](LICENSE) file for details.
80 |
--------------------------------------------------------------------------------
/dashboards/chronix-grafana-csv-file-example.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 3,
3 | "title": "Chronix-Dashboard",
4 | "tags": [],
5 | "style": "dark",
6 | "timezone": "browser",
7 | "editable": true,
8 | "hideControls": false,
9 | "sharedCrosshair": false,
10 | "rows": [
11 | {
12 | "collapse": false,
13 | "editable": true,
14 | "height": "300px",
15 | "panels": [
16 | {
17 | "aliasColors": {},
18 | "bars": false,
19 | "datasource": null,
20 | "downsampling": "avg",
21 | "editable": true,
22 | "error": false,
23 | "fill": 1,
24 | "grid": {
25 | "threshold1": null,
26 | "threshold1Color": "rgba(216, 200, 27, 0.27)",
27 | "threshold2": null,
28 | "threshold2Color": "rgba(234, 112, 112, 0.22)"
29 | },
30 | "height": "250px",
31 | "id": 1,
32 | "isNew": true,
33 | "legend": {
34 | "alignAsTable": false,
35 | "avg": true,
36 | "current": false,
37 | "max": false,
38 | "min": true,
39 | "rightSide": false,
40 | "show": true,
41 | "total": true,
42 | "values": true
43 | },
44 | "lines": true,
45 | "linewidth": 2,
46 | "links": [],
47 | "nullPointMode": "connected",
48 | "percentage": false,
49 | "pointradius": 5,
50 | "points": false,
51 | "renderer": "flot",
52 | "seriesOverrides": [],
53 | "span": 12,
54 | "stack": false,
55 | "steppedLine": false,
56 | "targets": [
57 | {
58 | "alias": "Load-One",
59 | "downsampling": "avg",
60 | "errors": {},
61 | "groupBy": {
62 | "timeInterval": "1s"
63 | },
64 | "hide": false,
65 | "horAggregator": {
66 | "factor": "1",
67 | "percentile": "0.75",
68 | "samplingRate": "1s",
69 | "unit": "millisecond"
70 | },
71 | "metric": "metric:*Load*one",
72 | "refId": "A"
73 | },
74 | {
75 | "alias": "Load-Five",
76 | "downsampling": "avg",
77 | "errors": {},
78 | "groupBy": {
79 | "timeInterval": "1s"
80 | },
81 | "horAggregator": {
82 | "factor": "1",
83 | "percentile": "0.75",
84 | "samplingRate": "1s",
85 | "unit": "millisecond"
86 | },
87 | "metric": "metric:*Load*five",
88 | "refId": "B"
89 | },
90 | {
91 | "alias": "Load-Ten",
92 | "downsampling": "avg",
93 | "errors": {},
94 | "groupBy": {
95 | "timeInterval": "1s"
96 | },
97 | "horAggregator": {
98 | "factor": "1",
99 | "percentile": "0.75",
100 | "samplingRate": "1s",
101 | "unit": "millisecond"
102 | },
103 | "metric": "metric:*Load*fifteen",
104 | "refId": "C"
105 | }
106 | ],
107 | "timeFrom": null,
108 | "timeShift": null,
109 | "title": "System CPU: One / Five / Fifteen Minutes",
110 | "tooltip": {
111 | "msResolution": true,
112 | "shared": true,
113 | "sort": 0,
114 | "value_type": "cumulative"
115 | },
116 | "transparent": false,
117 | "type": "graph",
118 | "xaxis": {
119 | "show": true
120 | },
121 | "yaxes": [
122 | {
123 | "format": "short",
124 | "label": "Load",
125 | "logBase": 1,
126 | "max": null,
127 | "min": null,
128 | "show": true
129 | },
130 | {
131 | "format": "ms",
132 | "label": "Time",
133 | "logBase": 1,
134 | "max": null,
135 | "min": null,
136 | "show": false
137 | }
138 | ]
139 | }
140 | ],
141 | "showTitle": true,
142 | "title": "System Load"
143 | },
144 | {
145 | "collapse": false,
146 | "editable": true,
147 | "height": "300px",
148 | "panels": [
149 | {
150 | "aliasColors": {},
151 | "bars": false,
152 | "datasource": null,
153 | "downsampling": "avg",
154 | "editable": true,
155 | "error": false,
156 | "fill": 1,
157 | "grid": {
158 | "threshold1": null,
159 | "threshold1Color": "rgba(216, 200, 27, 0.27)",
160 | "threshold2": null,
161 | "threshold2Color": "rgba(234, 112, 112, 0.22)"
162 | },
163 | "id": 2,
164 | "isNew": true,
165 | "legend": {
166 | "avg": false,
167 | "current": false,
168 | "max": false,
169 | "min": false,
170 | "show": true,
171 | "total": false,
172 | "values": false
173 | },
174 | "lines": true,
175 | "linewidth": 2,
176 | "links": [],
177 | "nullPointMode": "connected",
178 | "percentage": false,
179 | "pointradius": 5,
180 | "points": false,
181 | "renderer": "flot",
182 | "seriesOverrides": [],
183 | "span": 12,
184 | "stack": false,
185 | "steppedLine": false,
186 | "targets": [
187 | {
188 | "alias": "Memory",
189 | "downsampling": "avg",
190 | "errors": {},
191 | "groupBy": {
192 | "timeInterval": "1s"
193 | },
194 | "horAggregator": {
195 | "factor": "1",
196 | "percentile": "0.75",
197 | "samplingRate": "1s",
198 | "unit": "millisecond"
199 | },
200 | "metric": "metric:*Memory/HeapMemoryUsage/used",
201 | "refId": "A"
202 | },
203 | {
204 | "downsampling": "avg",
205 | "errors": {},
206 | "groupBy": {
207 | "timeInterval": "1s"
208 | },
209 | "horAggregator": {
210 | "factor": "1",
211 | "percentile": "0.75",
212 | "samplingRate": "1s",
213 | "unit": "millisecond"
214 | },
215 | "metric": "metric:*Memory/HeapMemoryUsage/init",
216 | "refId": "B"
217 | },
218 | {
219 | "downsampling": "avg",
220 | "errors": {},
221 | "groupBy": {
222 | "timeInterval": "1s"
223 | },
224 | "horAggregator": {
225 | "factor": "1",
226 | "percentile": "0.75",
227 | "samplingRate": "1s",
228 | "unit": "millisecond"
229 | },
230 | "metric": "metric:*Memory/HeapMemoryUsage/committed",
231 | "refId": "C"
232 | }
233 | ],
234 | "timeFrom": null,
235 | "timeShift": null,
236 | "title": "Heap Memory",
237 | "tooltip": {
238 | "msResolution": true,
239 | "shared": true,
240 | "sort": 0,
241 | "value_type": "cumulative"
242 | },
243 | "type": "graph",
244 | "xaxis": {
245 | "show": true
246 | },
247 | "yaxes": [
248 | {
249 | "format": "bytes",
250 | "label": null,
251 | "logBase": 1,
252 | "max": null,
253 | "min": null,
254 | "show": true
255 | },
256 | {
257 | "format": "short",
258 | "label": null,
259 | "logBase": 1,
260 | "max": null,
261 | "min": null,
262 | "show": false
263 | }
264 | ]
265 | }
266 | ],
267 | "title": "New row"
268 | },
269 | {
270 | "collapse": false,
271 | "editable": true,
272 | "height": "250px",
273 | "panels": [
274 | {
275 | "addFilterTagMode": false,
276 | "aliasColors": {},
277 | "bars": false,
278 | "datasource": null,
279 | "downsampling": "avg",
280 | "editable": true,
281 | "error": false,
282 | "fill": 1,
283 | "grid": {
284 | "threshold1": null,
285 | "threshold1Color": "rgba(216, 200, 27, 0.27)",
286 | "threshold2": null,
287 | "threshold2Color": "rgba(234, 112, 112, 0.22)"
288 | },
289 | "id": 3,
290 | "isNew": true,
291 | "legend": {
292 | "avg": false,
293 | "current": false,
294 | "max": false,
295 | "min": false,
296 | "show": true,
297 | "total": false,
298 | "values": false
299 | },
300 | "lines": true,
301 | "linewidth": 2,
302 | "links": [],
303 | "nullPointMode": "connected",
304 | "percentage": false,
305 | "pointradius": 5,
306 | "points": false,
307 | "renderer": "flot",
308 | "seriesOverrides": [],
309 | "span": 12,
310 | "stack": false,
311 | "steppedLine": false,
312 | "targets": [
313 | {
314 | "downsampling": "avg",
315 | "errors": {},
316 | "groupBy": {
317 | "timeInterval": "1s"
318 | },
319 | "horAggregator": {
320 | "factor": "1",
321 | "percentile": "0.75",
322 | "samplingRate": "1s",
323 | "unit": "millisecond"
324 | },
325 | "metric": "metric:*duration",
326 | "refId": "A",
327 | "tags": {}
328 | }
329 | ],
330 | "timeFrom": null,
331 | "timeShift": null,
332 | "title": "Garbage Colleciton",
333 | "tooltip": {
334 | "msResolution": true,
335 | "shared": true,
336 | "sort": 0,
337 | "value_type": "cumulative"
338 | },
339 | "type": "graph",
340 | "xaxis": {
341 | "show": true
342 | },
343 | "yaxes": [
344 | {
345 | "format": "ms",
346 | "label": null,
347 | "logBase": 1,
348 | "max": null,
349 | "min": null,
350 | "show": true
351 | },
352 | {
353 | "format": "short",
354 | "label": null,
355 | "logBase": 1,
356 | "max": null,
357 | "min": null,
358 | "show": true
359 | }
360 | ]
361 | }
362 | ],
363 | "title": "New row"
364 | }
365 | ],
366 | "time": {
367 | "from": "2016-03-09T22:40:09.521Z",
368 | "to": "2016-03-10T13:24:42.454Z"
369 | },
370 | "timepicker": {
371 | "refresh_intervals": [
372 | "5s",
373 | "10s",
374 | "30s",
375 | "1m",
376 | "5m",
377 | "15m",
378 | "30m",
379 | "1h",
380 | "2h",
381 | "1d"
382 | ],
383 | "time_options": [
384 | "5m",
385 | "15m",
386 | "1h",
387 | "6h",
388 | "12h",
389 | "24h",
390 | "2d",
391 | "7d",
392 | "30d"
393 | ]
394 | },
395 | "templating": {
396 | "list": []
397 | },
398 | "annotations": {
399 | "list": []
400 | },
401 | "refresh": false,
402 | "schemaVersion": 12,
403 | "version": 2,
404 | "links": [],
405 | "gnetId": null
406 | }
--------------------------------------------------------------------------------
/dashboards/chronix-grafana-default-dashboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "title": "Chronix Grafana Default Dashboard",
4 | "tags": [],
5 | "style": "dark",
6 | "timezone": "browser",
7 | "editable": true,
8 | "hideControls": false,
9 | "sharedCrosshair": false,
10 | "rows": [
11 | {
12 | "collapse": false,
13 | "editable": true,
14 | "height": "250px",
15 | "panels": [
16 | {
17 | "aliasColors": {},
18 | "bars": false,
19 | "datasource": "Chronix",
20 | "downsampling": "avg",
21 | "editable": true,
22 | "error": false,
23 | "fill": 1,
24 | "grid": {
25 | "threshold1": null,
26 | "threshold1Color": "rgba(216, 200, 27, 0.27)",
27 | "threshold2": null,
28 | "threshold2Color": "rgba(234, 112, 112, 0.22)"
29 | },
30 | "id": 1,
31 | "isNew": true,
32 | "legend": {
33 | "avg": false,
34 | "current": false,
35 | "max": false,
36 | "min": false,
37 | "show": true,
38 | "total": false,
39 | "values": false
40 | },
41 | "lines": true,
42 | "linewidth": 2,
43 | "links": [],
44 | "nullPointMode": "connected",
45 | "percentage": false,
46 | "pointradius": 5,
47 | "points": false,
48 | "renderer": "flot",
49 | "seriesOverrides": [],
50 | "span": 12,
51 | "stack": false,
52 | "steppedLine": false,
53 | "targets": [
54 | {
55 | "downsampling": "avg",
56 | "errors": {},
57 | "horAggregator": {
58 | "factor": "1",
59 | "percentile": "0.75",
60 | "samplingRate": "1s",
61 | "unit": "millisecond"
62 | },
63 | "metric": "*Load*",
64 | "refId": "A"
65 | }
66 | ],
67 | "timeFrom": null,
68 | "timeShift": null,
69 | "title": "Chronix Grafana Default",
70 | "tooltip": {
71 | "msResolution": true,
72 | "shared": true,
73 | "sort": 0,
74 | "value_type": "cumulative"
75 | },
76 | "type": "graph",
77 | "xaxis": {
78 | "show": true
79 | },
80 | "yaxes": [
81 | {
82 | "format": "short",
83 | "label": null,
84 | "logBase": 1,
85 | "max": null,
86 | "min": null,
87 | "show": true
88 | },
89 | {
90 | "format": "short",
91 | "label": null,
92 | "logBase": 1,
93 | "max": null,
94 | "min": null,
95 | "show": true
96 | }
97 | ]
98 | }
99 | ],
100 | "title": "Row"
101 | }
102 | ],
103 | "time": {
104 | "from": "2013-08-25T13:13:51.327Z",
105 | "to": "2013-09-02T16:38:22.691Z"
106 | },
107 | "timepicker": {
108 | "refresh_intervals": [
109 | "5s",
110 | "10s",
111 | "30s",
112 | "1m",
113 | "5m",
114 | "15m",
115 | "30m",
116 | "1h",
117 | "2h",
118 | "1d"
119 | ],
120 | "time_options": [
121 | "5m",
122 | "15m",
123 | "1h",
124 | "6h",
125 | "12h",
126 | "24h",
127 | "2d",
128 | "7d",
129 | "30d"
130 | ]
131 | },
132 | "templating": {
133 | "list": []
134 | },
135 | "annotations": {
136 | "list": []
137 | },
138 | "refresh": false,
139 | "schemaVersion": 12,
140 | "version": 4,
141 | "links": [],
142 | "gnetId": null
143 | }
--------------------------------------------------------------------------------
/dist/README.md:
--------------------------------------------------------------------------------
1 | [](https://gitter.im/ChronixDB/chronix.grafana?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2 | [](https://travis-ci.org/ChronixDB/chronix.grafana)
3 | [](https://dependencyci.com/github/ChronixDB/chronix.grafana)
4 | [](LICENSE)
5 |
6 | # Chronix Grafana Datasource Plugin
7 |
8 | This is a "datasource" plugin that lets you use time series from [Chronix-Server](https://github.com/ChronixDB/chronix.server)
9 | and visualize them with [Grafana](https://grafana.net/).
10 |
11 | It works with Grafana > 3.X.X.
12 |
13 | 
14 |
15 | ## Features
16 |
17 | The plugin supports all the native implemented aggregations, transformations, and analyses of Chronix-Server.
18 | We will provide more details soon ;-)
19 |
20 | ## Usage
21 |
22 | Currently, the plugin is only available at the chronix github repository. It is planned to release the plugin within
23 | the app store of grafana.
24 |
25 | To use the plugin, simply clone this repository into your Grafana installation's `{inst-dir}/data/plugins/` directory.
26 |
27 | Optionally, you can download and start from the example dashboard:
28 |
29 | 1. Download the latest [Chronix-Server](https://github.com/ChronixDB/chronix.server/releases/download/0.3/chronix-0.3.zip)
30 | 2. Import the dashboard from 'dashboards' into your running Grafana
31 | 3. Download and execute the [csv importer](https://github.com/ChronixDB/chronix.examples/releases/download/0.3/importer.zip) after the Chronix-Server has started
32 |
33 | ## Contributing
34 |
35 | Is there anything missing? Do you have ideas for new features or improvements? You are highly welcome to contribute
36 | your improvements to the Chronix projects. All you have to do is to fork this repository, improve the code and issue a
37 | pull request.
38 |
39 | ## Developing the plugin
40 |
41 | ### Basics
42 |
43 | * All actual code sources live in `src` and can be written in ES6 / ES2015 - this allows us to use proper imports,
44 | exports and all the other syntactic goodies.
45 | * The `dist` folder is actually checked into git, too. We do this so that Grafana auto-detects the dist folder and uses
46 | it even if you just cloned the repository into Grafana (as described above).
47 | * This means that whenever you're changing something in `src`, you really should run the build at least once so that the
48 | contents of `dist` are "in sync", too, when you're committing / pushing / issuing a PR.
49 |
50 | ### Set up (only needs to be done once)
51 |
52 | Use a command prompt that provides NodeJS and NPM. In it, simply run
53 |
54 | npm install
55 |
56 | to install all (dev-) dependencies for the build.
57 |
58 | ### Changing stuff
59 |
60 | To run the build once in order to re-create the `dist` folder, run
61 |
62 | npm run build
63 |
64 | If you want the build to watch your `src` files and auto-run whenever you hit save, run
65 |
66 | npm run watch
67 |
68 | (you can end the watcher by pressing CTRL+C in that command prompt)
69 |
70 | ## Maintainer
71 |
72 | Florian Lautenschlager @flolaut
73 |
74 | ## License
75 |
76 | This software is provided under the Apache License, Version 2.0 license.
77 |
78 | See the [LICENSE](LICENSE) file for details.
79 |
--------------------------------------------------------------------------------
/dist/config-controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | System.register([], function (_export, _context) {
4 | "use strict";
5 |
6 | var ChronixConfigController;
7 |
8 | function _classCallCheck(instance, Constructor) {
9 | if (!(instance instanceof Constructor)) {
10 | throw new TypeError("Cannot call a class as a function");
11 | }
12 | }
13 |
14 | return {
15 | setters: [],
16 | execute: function () {
17 | _export('ChronixConfigController', ChronixConfigController = function ChronixConfigController() {
18 | _classCallCheck(this, ChronixConfigController);
19 | });
20 |
21 | _export('ChronixConfigController', ChronixConfigController);
22 |
23 | ChronixConfigController.templateUrl = 'partials/config.html';
24 | }
25 | };
26 | });
27 | //# sourceMappingURL=config-controller.js.map
28 |
--------------------------------------------------------------------------------
/dist/config-controller.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["../src/config-controller.js"],"names":["ChronixConfigController","templateUrl"],"mappings":";;;;;;;;;;;;;;;;yCAAaA,uB;;;;;;AAEbA,8BAAwBC,WAAxB,GAAsC,sBAAtC","file":"config-controller.js","sourcesContent":["export class ChronixConfigController {}\r\n\r\nChronixConfigController.templateUrl = 'partials/config.html';\r\n"]}
--------------------------------------------------------------------------------
/dist/datasource.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | System.register(['lodash'], function (_export, _context) {
4 | "use strict";
5 |
6 | var _, _createClass, requiredFields, ChronixDbDatasource;
7 |
8 | function _classCallCheck(instance, Constructor) {
9 | if (!(instance instanceof Constructor)) {
10 | throw new TypeError("Cannot call a class as a function");
11 | }
12 | }
13 |
14 | function escapeTag(name) {
15 | return name.indexOf('.') !== -1 ? '"' + name + '"' : name;
16 | }
17 |
18 | function toTagQueryString(tag, tagName) {
19 | return tagName + ':(' + tag.map(escapeTag).join(' OR ') + ')';
20 | }
21 |
22 | function toTargetQueryString(target) {
23 | if (!target.tags || Object.keys(target.tags).length === 0) {
24 | // simple name-only
25 | return target.name;
26 | }
27 |
28 | // create strings for each tag
29 | var targetQueryStrings = _(target.tags).map(toTagQueryString);
30 |
31 | return '(' + target.name + ' AND ' + targetQueryStrings.join(' AND ') + ')';
32 | }
33 |
34 | function toTargetJoinString(target) {
35 | if (!target.attributes || Object.keys(target.attributes).length === 0) {
36 | return "name";
37 | }
38 | // create strings for each tag
39 | return _(target.attributes).join(',') + ",name,type";
40 | }
41 |
42 | return {
43 | setters: [function (_lodash) {
44 | _ = _lodash.default;
45 | }],
46 | execute: function () {
47 | _createClass = function () {
48 | function defineProperties(target, props) {
49 | for (var i = 0; i < props.length; i++) {
50 | var descriptor = props[i];
51 | descriptor.enumerable = descriptor.enumerable || false;
52 | descriptor.configurable = true;
53 | if ("value" in descriptor) descriptor.writable = true;
54 | Object.defineProperty(target, descriptor.key, descriptor);
55 | }
56 | }
57 |
58 | return function (Constructor, protoProps, staticProps) {
59 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
60 | if (staticProps) defineProperties(Constructor, staticProps);
61 | return Constructor;
62 | };
63 | }();
64 |
65 | requiredFields = ["data", "start", "end", "_version_", "id", "name", "type"];
66 |
67 | _export('ChronixDbDatasource', ChronixDbDatasource = function () {
68 | function ChronixDbDatasource(instanceSettings, $q, backendSrv, templateSrv) {
69 | _classCallCheck(this, ChronixDbDatasource);
70 |
71 | this.type = instanceSettings.type;
72 | this.url = instanceSettings.url;
73 | this.name = instanceSettings.name;
74 | this.$q = $q;
75 | this.backendSrv = backendSrv;
76 | this.templateSrv = templateSrv;
77 | }
78 |
79 | //region Required Grafana Datasource methods
80 |
81 | _createClass(ChronixDbDatasource, [{
82 | key: 'query',
83 | value: function query(options) {
84 | // get the start and the end and multiply it with 1000 to get millis since 1970
85 | var start = options.range.from.unix() * 1000;
86 | var end = options.range.to.unix() * 1000;
87 | var targets = options.targets;
88 |
89 | return this.rawQuery(targets, start, end).then(this.extractTimeSeries);
90 | }
91 | }, {
92 | key: 'testDatasource',
93 | value: function testDatasource() {
94 | var options = {
95 | url: this.url + '/select?q=%7B!lucene%7D*%3A*&rows=0',
96 | method: 'GET'
97 | };
98 | var successMessage = {
99 | status: "success",
100 | message: "Connection to Chronix established",
101 | title: "Success"
102 | };
103 | var errorMessage = this.$q.reject({
104 | status: "error",
105 | message: "Connection to Chronix failed",
106 | title: "Error"
107 | });
108 |
109 | // perform the actual call...
110 | return this.backendSrv.datasourceRequest(options)
111 | // ... check if the response is technically successful ...
112 | .then(function (response) {
113 | return response && response.status === 200;
114 | })
115 | // ... and respond appropriately
116 | .then(function (success) {
117 | return success ? successMessage : errorMessage;
118 | })
119 | // ... and react appropriately, too, when the call somehow didn't work
120 | .catch(function (error) {
121 | return errorMessage;
122 | });
123 | }
124 | }, {
125 | key: 'findTimeSeriesByNames',
126 | value: function findTimeSeriesByNames(tsName) {
127 | var emptyResult = this.$q.when([]);
128 |
129 | if (!tsName || tsName === '*') {
130 | // no "*" accepted from the user
131 | return emptyResult;
132 | }
133 |
134 | if (tsName.indexOf('*') === -1) {
135 | // append an "*" at the end if the user didn't already provide one
136 | tsName = tsName + '*';
137 | }
138 |
139 | var options = {
140 | //do a facet query
141 | url: this.url + '/select?facet.field=name&facet=on&facet.mincount=1&q=name:' + tsName + '&rows=0&wt=json',
142 | method: 'GET'
143 | };
144 |
145 | return this.backendSrv.datasourceRequest(options).then(function (response) {
146 | return response && response.data && response.data.facet_counts && response.data.facet_counts.facet_fields && response.data.facet_counts.facet_fields.name;
147 | }).then(function (nameFields) {
148 | // somehow no valid response => empty array
149 | if (!nameFields) {
150 | console.log('could not find any matching time series for "' + tsName + '"');
151 | return emptyResult;
152 | }
153 |
154 | // take only the names, not the counts
155 | return nameFields.filter(function (unused, index) {
156 | return index % 2 === 0;
157 | })
158 | // and provide them as objects with the "text" property
159 | .map(function (text) {
160 | return { text: text };
161 | });
162 | })
163 | // if the request itself failed
164 | .catch(function (error) {
165 | return emptyResult;
166 | });
167 | }
168 | }, {
169 | key: 'rawQuery',
170 | value: function rawQuery(targets, start, end) {
171 | // create strings for each target
172 | var targetsQueryStrings = _(targets).map(toTargetQueryString);
173 |
174 | var query = 'name:(' + targetsQueryStrings.join(' OR ') + ')' + ' AND start:' + start + ' AND end:' + end;
175 |
176 | var joinquery = _(targets).map(toTargetJoinString);
177 |
178 | //At this point we have to query chronix
179 | var RAW_QUERY_BASE = '/select?fl=dataAsJson&wt=json';
180 | var RAW_QUERY_JOIN = '&cj=' + joinquery;
181 | var RAW_QUERY_FILTER_FUNCTION = ''; //'&cf=metric{vector:0.1}';
182 | var RAW_QUERY_BASE_WITH_FILTER = RAW_QUERY_BASE + RAW_QUERY_FILTER_FUNCTION + RAW_QUERY_JOIN + '&q=';
183 |
184 | console.log("Chronix Query: " + RAW_QUERY_BASE_WITH_FILTER + query);
185 |
186 | var options = {
187 | method: 'GET',
188 | url: this.url + RAW_QUERY_BASE_WITH_FILTER + query
189 | };
190 |
191 | return this.backendSrv.datasourceRequest(options).then(function (response) {
192 | return [targets, response];
193 | });
194 | }
195 | }, {
196 | key: 'extractTimeSeries',
197 | value: function extractTimeSeries(targetsResponse) {
198 | var response = targetsResponse[1];
199 |
200 | if (response.data === undefined) {
201 | return { data: [] };
202 | }
203 | var dataset = response.data.response.docs;
204 |
205 | var tsPoints = {};
206 |
207 | for (var i = 0; i < dataset.length; i++) {
208 | var currentDataSet = dataset[i];
209 | var currentTimeSeries = currentDataSet.name;
210 |
211 | if (!(currentTimeSeries in tsPoints)) {
212 | tsPoints[currentTimeSeries] = [];
213 | }
214 |
215 | var jsonData = JSON.parse(currentDataSet.dataAsJson);
216 |
217 | var timestamps = jsonData[0];
218 | var values = jsonData[1];
219 |
220 | //add them
221 | for (var j = 0; j < timestamps.length; j++) {
222 | tsPoints[currentTimeSeries].push([values[j], timestamps[j]]);
223 | }
224 | }
225 |
226 | var ret = [];
227 | for (var key in tsPoints) {
228 | ret.push({ target: key, datapoints: tsPoints[key] });
229 | }
230 | return { data: ret };
231 | }
232 | }, {
233 | key: 'suggestAttributes',
234 | value: function suggestAttributes() {
235 | var options = {
236 | method: 'GET',
237 | url: this.url + '/admin/luke?numTerms=0&wt=json'
238 | };
239 |
240 | return this.backendSrv.datasourceRequest(options).then(this.mapToTextValue);
241 | }
242 | }, {
243 | key: 'mapToTextValue',
244 | value: function mapToTextValue(result) {
245 | var fields = result.data.fields;
246 |
247 | var stringFields = [];
248 | //Iterate over the returned fields
249 | for (var property in fields) {
250 | if (fields.hasOwnProperty(property)) {
251 | if (requiredFields.indexOf(property.toLowerCase()) == -1) {
252 | stringFields.push(property);
253 | }
254 | }
255 | }
256 | return _.map(stringFields, function (name) {
257 | return { text: name };
258 | });
259 | }
260 | }, {
261 | key: 'suggestAttributesValues',
262 | value: function suggestAttributesValues(name, attribute) {
263 | var options = {
264 | method: 'GET',
265 | url: this.url + '/select?facet.field=' + attribute + '&facet=on&q=name:' + name + '&rows=0&wt=json'
266 | };
267 |
268 | return this.backendSrv.datasourceRequest(options).then(this.mapValueToText);
269 | }
270 | }, {
271 | key: 'mapValueToText',
272 | value: function mapValueToText(result) {
273 | var fields = result.data.facet_counts.facet_fields;
274 |
275 | var field;
276 | //Iterate over the returned fields
277 | for (var property in fields) {
278 | if (fields.hasOwnProperty(property)) {
279 | field = property;
280 | }
281 | }
282 |
283 | var pairs = [];
284 | var values = fields[field];
285 |
286 | //Build pairs
287 | for (var i = 0; i < values.length; i++) {
288 | pairs.push([values[i], values[++i]]);
289 | }
290 |
291 | return _.map(pairs, function (pair) {
292 | return { text: pair[0], value: pair[1] };
293 | });
294 | }
295 | }]);
296 |
297 | return ChronixDbDatasource;
298 | }());
299 |
300 | _export('ChronixDbDatasource', ChronixDbDatasource);
301 | }
302 | };
303 | });
304 | //# sourceMappingURL=datasource.js.map
305 |
--------------------------------------------------------------------------------
/dist/datasource.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["../src/datasource.js"],"names":["escapeTag","name","indexOf","toTagQueryString","tag","tagName","map","join","toTargetQueryString","target","tags","Object","keys","length","targetQueryStrings","_","toTargetJoinString","attributes","requiredFields","ChronixDbDatasource","instanceSettings","$q","backendSrv","templateSrv","type","url","options","start","range","from","unix","end","to","targets","rawQuery","then","extractTimeSeries","method","successMessage","status","message","title","errorMessage","reject","datasourceRequest","response","success","catch","tsName","emptyResult","when","data","facet_counts","facet_fields","nameFields","console","log","filter","unused","index","text","targetsQueryStrings","query","joinquery","RAW_QUERY_BASE","RAW_QUERY_JOIN","RAW_QUERY_FILTER_FUNCTION","RAW_QUERY_BASE_WITH_FILTER","targetsResponse","undefined","dataset","docs","tsPoints","i","currentDataSet","currentTimeSeries","jsonData","JSON","parse","dataAsJson","timestamps","values","j","push","ret","key","datapoints","mapToTextValue","result","fields","stringFields","property","hasOwnProperty","toLowerCase","attribute","mapValueToText","field","pairs","pair","value"],"mappings":"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","file":"datasource.js","sourcesContent":["import _ from 'lodash';\r\n\r\nfunction escapeTag(name) {\r\n return name.indexOf('.') !== -1 ? `\"${name}\"` : name;\r\n}\r\n\r\nfunction toTagQueryString(tag, tagName) {\r\n return tagName + ':(' + tag.map(escapeTag).join(' OR ') + ')'\r\n}\r\n\r\nfunction toTargetQueryString(target) {\r\n if (!target.tags || Object.keys(target.tags).length === 0) {\r\n // simple name-only\r\n return target.name;\r\n }\r\n\r\n // create strings for each tag\r\n const targetQueryStrings = _(target.tags).map(toTagQueryString);\r\n\r\n return '(' + target.name + ' AND ' + targetQueryStrings.join(' AND ') + ')';\r\n}\r\n\r\nfunction toTargetJoinString(target) {\r\n if (!target.attributes || Object.keys(target.attributes).length === 0) {\r\n return \"name\";\r\n }\r\n // create strings for each tag\r\n return _(target.attributes).join(',') + \",name,type\";\r\n}\r\n\r\nvar requiredFields = [\"data\", \"start\", \"end\", \"_version_\", \"id\", \"name\", \"type\"];\r\n\r\nexport class ChronixDbDatasource {\r\n\r\n constructor(instanceSettings, $q, backendSrv, templateSrv) {\r\n this.type = instanceSettings.type;\r\n this.url = instanceSettings.url;\r\n this.name = instanceSettings.name;\r\n this.$q = $q;\r\n this.backendSrv = backendSrv;\r\n this.templateSrv = templateSrv;\r\n }\r\n\r\n //region Required Grafana Datasource methods\r\n\r\n query(options) {\r\n // get the start and the end and multiply it with 1000 to get millis since 1970\r\n var start = options.range.from.unix() * 1000;\r\n var end = options.range.to.unix() * 1000;\r\n var targets = options.targets;\r\n\r\n return this.rawQuery(targets, start, end).then(this.extractTimeSeries);\r\n }\r\n\r\n /**\r\n * Attempts to connect to the URL entered by the user and responds with a promise to either a \"success\" or an\r\n * \"error\" message.\r\n */\r\n testDatasource() {\r\n const options = {\r\n url: `${this.url}/select?q=%7B!lucene%7D*%3A*&rows=0`,\r\n method: 'GET'\r\n };\r\n const successMessage = {\r\n status: \"success\",\r\n message: \"Connection to Chronix established\",\r\n title: \"Success\"\r\n };\r\n const errorMessage = this.$q.reject({\r\n status: \"error\",\r\n message: \"Connection to Chronix failed\",\r\n title: \"Error\"\r\n });\r\n\r\n // perform the actual call...\r\n return this.backendSrv.datasourceRequest(options)\r\n // ... check if the response is technically successful ...\r\n .then(response => response && response.status === 200)\r\n // ... and respond appropriately\r\n .then(success => success ? successMessage : errorMessage)\r\n // ... and react appropriately, too, when the call somehow didn't work\r\n .catch(error => errorMessage);\r\n }\r\n\r\n /**\r\n *\r\n */\r\n findTimeSeriesByNames(tsName) {\r\n const emptyResult = this.$q.when([]);\r\n\r\n if (!tsName || tsName === '*') {\r\n // no \"*\" accepted from the user\r\n return emptyResult;\r\n }\r\n\r\n if (tsName.indexOf('*') === -1) {\r\n // append an \"*\" at the end if the user didn't already provide one\r\n tsName = tsName + '*';\r\n }\r\n\r\n const options = {\r\n //do a facet query\r\n url: `${this.url}/select?facet.field=name&facet=on&facet.mincount=1&q=name:${tsName}&rows=0&wt=json`,\r\n method: 'GET'\r\n };\r\n\r\n return this.backendSrv.datasourceRequest(options)\r\n .then(response => response && response.data && response.data.facet_counts && response.data.facet_counts.facet_fields && response.data.facet_counts.facet_fields.name)\r\n .then((nameFields) => {\r\n // somehow no valid response => empty array\r\n if (!nameFields) {\r\n console.log(`could not find any matching time series for \"${tsName}\"`);\r\n return emptyResult;\r\n }\r\n\r\n // take only the names, not the counts\r\n return nameFields\r\n .filter((unused, index) => index % 2 === 0)\r\n // and provide them as objects with the \"text\" property\r\n .map(text => ({text}));\r\n })\r\n // if the request itself failed\r\n .catch(error => emptyResult);\r\n }\r\n\r\n //endregion\r\n\r\n rawQuery(targets, start, end) {\r\n // create strings for each target\r\n var targetsQueryStrings = _(targets).map(toTargetQueryString);\r\n\r\n var query = 'name:(' + targetsQueryStrings.join(' OR ') + ')'\r\n + ' AND start:' + start\r\n + ' AND end:' + end;\r\n\r\n var joinquery = _(targets).map(toTargetJoinString);\r\n\r\n //At this point we have to query chronix\r\n var RAW_QUERY_BASE = '/select?fl=dataAsJson&wt=json';\r\n var RAW_QUERY_JOIN = '&cj=' + joinquery;\r\n var RAW_QUERY_FILTER_FUNCTION = '';//'&cf=metric{vector:0.1}';\r\n var RAW_QUERY_BASE_WITH_FILTER = RAW_QUERY_BASE + RAW_QUERY_FILTER_FUNCTION + RAW_QUERY_JOIN + '&q=';\r\n\r\n console.log(\"Chronix Query: \" + RAW_QUERY_BASE_WITH_FILTER + query);\r\n\r\n var options = {\r\n method: 'GET',\r\n url: this.url + RAW_QUERY_BASE_WITH_FILTER + query\r\n };\r\n\r\n return this.backendSrv.datasourceRequest(options).then(function (response) {\r\n return [targets, response];\r\n });\r\n }\r\n\r\n extractTimeSeries(targetsResponse) {\r\n var response = targetsResponse[1];\r\n\r\n if (response.data === undefined) {\r\n return {data: []};\r\n }\r\n var dataset = response.data.response.docs;\r\n\r\n var tsPoints = {};\r\n\r\n for (var i = 0; i < dataset.length; i++) {\r\n var currentDataSet = dataset[i];\r\n var currentTimeSeries = currentDataSet.name;\r\n\r\n if (!(currentTimeSeries in tsPoints)) {\r\n tsPoints[currentTimeSeries] = [];\r\n }\r\n\r\n var jsonData = JSON.parse(currentDataSet.dataAsJson);\r\n\r\n var timestamps = jsonData[0];\r\n var values = jsonData[1];\r\n\r\n //add them\r\n for (var j = 0; j < timestamps.length; j++) {\r\n tsPoints[currentTimeSeries].push([values[j], timestamps[j]]);\r\n }\r\n\r\n }\r\n\r\n var ret = [];\r\n for (var key in tsPoints) {\r\n ret.push({target: key, datapoints: tsPoints[key]});\r\n }\r\n return {data: ret};\r\n }\r\n\r\n /**\r\n * Gets the available fields / attributes\r\n */\r\n suggestAttributes() {\r\n var options = {\r\n method: 'GET',\r\n url: this.url + '/admin/luke?numTerms=0&wt=json'\r\n };\r\n\r\n return this.backendSrv.datasourceRequest(options).then(this.mapToTextValue);\r\n }\r\n\r\n mapToTextValue(result) {\r\n var fields = result.data.fields;\r\n\r\n var stringFields = [];\r\n //Iterate over the returned fields\r\n for (var property in fields) {\r\n if (fields.hasOwnProperty(property)) {\r\n if (requiredFields.indexOf(property.toLowerCase()) == -1) {\r\n stringFields.push(property)\r\n }\r\n }\r\n }\r\n return _.map(stringFields, (name) => {\r\n return {text: name};\r\n });\r\n }\r\n\r\n /**\r\n * Gets the available values for the attributes.\r\n *\r\n * @param name The name to get the available attributes.\r\n * @param attribute The attribute.\r\n */\r\n suggestAttributesValues(name, attribute) {\r\n var options = {\r\n method: 'GET',\r\n url: this.url + '/select?facet.field=' + attribute + '&facet=on&q=name:' + name + '&rows=0&wt=json'\r\n };\r\n\r\n return this.backendSrv.datasourceRequest(options).then(this.mapValueToText);\r\n }\r\n\r\n mapValueToText(result) {\r\n var fields = result.data.facet_counts.facet_fields;\r\n\r\n var field;\r\n //Iterate over the returned fields\r\n for (var property in fields) {\r\n if (fields.hasOwnProperty(property)) {\r\n field = property;\r\n }\r\n }\r\n\r\n var pairs = [];\r\n var values = fields[field];\r\n\r\n //Build pairs\r\n for (var i = 0; i < values.length; i++) {\r\n pairs.push([values[i], values[++i]]);\r\n }\r\n\r\n return _.map(pairs, (pair) => {\r\n return {text: pair[0], value: pair[1]};\r\n });\r\n }\r\n\r\n}\r\n"]}
--------------------------------------------------------------------------------
/dist/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChronixDB/chronix.grafana/f0fa8361fbf97f9fc860c8fb4e830dfd2e65a9d8/dist/img/logo.png
--------------------------------------------------------------------------------
/dist/img/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChronixDB/chronix.grafana/f0fa8361fbf97f9fc860c8fb4e830dfd2e65a9d8/dist/img/screenshot.png
--------------------------------------------------------------------------------
/dist/module.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | System.register(['./datasource', './query-controller', './config-controller'], function (_export, _context) {
4 | "use strict";
5 |
6 | var ChronixDbDatasource, ChronixDbQueryController, ChronixConfigController;
7 | return {
8 | setters: [function (_datasource) {
9 | ChronixDbDatasource = _datasource.ChronixDbDatasource;
10 | }, function (_queryController) {
11 | ChronixDbQueryController = _queryController.ChronixDbQueryController;
12 | }, function (_configController) {
13 | ChronixConfigController = _configController.ChronixConfigController;
14 | }],
15 | execute: function () {
16 | _export('Datasource', ChronixDbDatasource);
17 |
18 | _export('QueryCtrl', ChronixDbQueryController);
19 |
20 | _export('ConfigCtrl', ChronixConfigController);
21 | }
22 | };
23 | });
24 | //# sourceMappingURL=module.js.map
25 |
--------------------------------------------------------------------------------
/dist/module.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["../src/module.js"],"names":["ChronixDbDatasource","ChronixDbQueryController","ChronixConfigController"],"mappings":";;;;;;;;AAASA,+B,eAAAA,mB;;AACAC,oC,oBAAAA,wB;;AACAC,mC,qBAAAA,uB;;;kCAGLF,mB;;iCACAC,wB;;kCACAC,uB","file":"module.js","sourcesContent":["import { ChronixDbDatasource } from './datasource';\r\nimport { ChronixDbQueryController } from './query-controller';\r\nimport { ChronixConfigController } from './config-controller';\r\n\r\nexport {\r\n ChronixDbDatasource as Datasource,\r\n ChronixDbQueryController as QueryCtrl,\r\n ChronixConfigController as ConfigCtrl\r\n};\r\n"]}
--------------------------------------------------------------------------------
/dist/partials/config.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/dist/partials/query.editor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Time Series
7 |
8 |
Name:
9 |
25 |
26 |
27 |
28 |
Attributes
29 |
30 |
31 |
32 |
{{ key }} = {{ value }}
33 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
Attribute key:
49 |
50 |
59 |
60 |
61 |
62 |
Attribute value:
63 |
64 |
73 |
74 |
75 |
83 |
84 |
85 |
86 |
87 |
88 |
Join by
89 |
90 |
91 |
97 |
98 |
99 |
104 |
105 |
106 |
107 |
108 |
Join type:
109 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/dist/plugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "datasource",
3 | "name": "Chronix",
4 | "id": "chronix",
5 | "info": {
6 | "description": "Datasource plugin for Chronix",
7 | "author": {
8 | "name": "QAware",
9 | "url": "http://www.chronix.io"
10 | },
11 | "keywords": [
12 | "chronix",
13 | "chronixdb",
14 | "apache solr",
15 | "solr",
16 | "time series",
17 | "timeseries",
18 | "time-series"
19 | ],
20 | "logos": {
21 | "small": "img/logo.png",
22 | "large": "img/logo.png"
23 | },
24 | "links": [
25 | {
26 | "name": "Home Page",
27 | "url": "http://www.chronix.io"
28 | },
29 | {
30 | "name": "GitHub",
31 | "url": "https://github.com/ChronixDB/chronix.grafana"
32 | },
33 | {
34 | "name": "Issues",
35 | "url": "https://github.com/ChronixDB/chronix.grafana/issues"
36 | },
37 | {
38 | "name": "License",
39 | "url": "https://github.com/ChronixDB/chronix.grafana/blob/master/LICENSE"
40 | }
41 | ],
42 | "screenshots": [
43 | {
44 | "name": "ChronixDB in Grafana",
45 | "path": "img/screenshot.png"
46 | }
47 | ],
48 | "version": "0.4.0",
49 | "updated": "2016-11-05"
50 | },
51 | "metrics": true,
52 | "annotations": false,
53 | "dependencies": {
54 | "grafanaVersion": "3.x.x",
55 | "plugins": []
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/dist/query-controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | System.register(['app/plugins/sdk', 'lodash'], function (_export, _context) {
4 | "use strict";
5 |
6 | var QueryCtrl, _, _createClass, ChronixDbQueryController;
7 |
8 | function _classCallCheck(instance, Constructor) {
9 | if (!(instance instanceof Constructor)) {
10 | throw new TypeError("Cannot call a class as a function");
11 | }
12 | }
13 |
14 | function _possibleConstructorReturn(self, call) {
15 | if (!self) {
16 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
17 | }
18 |
19 | return call && (typeof call === "object" || typeof call === "function") ? call : self;
20 | }
21 |
22 | function _inherits(subClass, superClass) {
23 | if (typeof superClass !== "function" && superClass !== null) {
24 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
25 | }
26 |
27 | subClass.prototype = Object.create(superClass && superClass.prototype, {
28 | constructor: {
29 | value: subClass,
30 | enumerable: false,
31 | writable: true,
32 | configurable: true
33 | }
34 | });
35 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
36 | }
37 |
38 | function isInt(n) {
39 | return parseInt(n) % 1 === 0;
40 | }
41 |
42 | return {
43 | setters: [function (_appPluginsSdk) {
44 | QueryCtrl = _appPluginsSdk.QueryCtrl;
45 | }, function (_lodash) {
46 | _ = _lodash.default;
47 | }],
48 | execute: function () {
49 | _createClass = function () {
50 | function defineProperties(target, props) {
51 | for (var i = 0; i < props.length; i++) {
52 | var descriptor = props[i];
53 | descriptor.enumerable = descriptor.enumerable || false;
54 | descriptor.configurable = true;
55 | if ("value" in descriptor) descriptor.writable = true;
56 | Object.defineProperty(target, descriptor.key, descriptor);
57 | }
58 | }
59 |
60 | return function (Constructor, protoProps, staticProps) {
61 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
62 | if (staticProps) defineProperties(Constructor, staticProps);
63 | return Constructor;
64 | };
65 | }();
66 |
67 | _export('ChronixDbQueryController', ChronixDbQueryController = function (_QueryCtrl) {
68 | _inherits(ChronixDbQueryController, _QueryCtrl);
69 |
70 | function ChronixDbQueryController($scope, $injector) {
71 | _classCallCheck(this, ChronixDbQueryController);
72 |
73 | var _this = _possibleConstructorReturn(this, (ChronixDbQueryController.__proto__ || Object.getPrototypeOf(ChronixDbQueryController)).call(this, $scope, $injector));
74 |
75 | _this.panel.stack = false;
76 |
77 | if (!_this.panel.downsampling) {
78 | _this.panel.downsampling = 'avg';
79 | }
80 |
81 | if (!_this.target.downsampling) {
82 | _this.target.downsampling = _this.panel.downsampling;
83 | _this.target.sampling = _this.panel.sampling;
84 | }
85 |
86 | /**
87 | * Is called if someone types something into a key field of an attribute.
88 | */
89 | _this.suggestAttributes = function (query, callback) {
90 | _this.datasource.suggestAttributes().then(_this.getTextValues.bind(_this)).then(callback);
91 | };
92 |
93 | /**
94 | * Is called if someone types something into a value field of an attribute.
95 | */
96 | _this.suggestTagValues = function (query, callback) {
97 | _this.datasource.suggestAttributesValues(_this.target.name, _this.target.currentTagKey).then(_this.getTextValues.bind(_this)).then(callback);
98 | };
99 |
100 | /**
101 | * Is called if someone types something into a key field of an attribute.
102 | */
103 | _this.suggestTagAttributes = function (query, callback) {
104 | _this.datasource.suggestAttributes(query).then(_this.getTextValues.bind(_this)).then(callback);
105 | };
106 |
107 | _this.suggestMetrics = function (query, callback) {
108 | _this.datasource.findTimeSeriesByNames(query).then(_this.getTextValues.bind(_this)).then(callback);
109 | };
110 |
111 | _this.validateTarget();
112 |
113 | _this.getCollapsedText = function () {
114 | return 'Expand to configure Chronix Query data source';
115 | };
116 | return _this;
117 | }
118 |
119 | _createClass(ChronixDbQueryController, [{
120 | key: 'validateTarget',
121 | value: function validateTarget() {
122 | var errs = {};
123 |
124 | if (!this.target.name) {
125 | errs.name = "You must supply a time series name.";
126 | }
127 |
128 | try {
129 | if (this.target.sampling) {
130 | this.datasource.convertToChronixInterval(this.target.sampling);
131 | }
132 | } catch (err) {
133 | errs.sampling = err.message;
134 | }
135 |
136 | this.target.errors = errs;
137 | }
138 | }, {
139 | key: 'targetBlur',
140 | value: function targetBlur() {
141 | this.validateTarget();
142 |
143 | if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
144 | this.oldTarget = angular.copy(this.target);
145 | this.panelCtrl.refresh();
146 | }
147 | }
148 | }, {
149 | key: 'getTextValues',
150 | value: function getTextValues(metricFindResult) {
151 | return _.map(metricFindResult, function (value) {
152 | return value.text;
153 | });
154 | }
155 | }, {
156 | key: 'addJoinByAttribute',
157 | value: function addJoinByAttribute(query, callback) {
158 | console.info("add join by attribute is called for " + query);
159 |
160 | this.datasource.suggestAttributes(query).then(this.getTextValues.bind(this)).then(callback);
161 | }
162 | }, {
163 | key: 'validateJoinAttributes',
164 | value: function validateJoinAttributes() {
165 | console.info("validateJoinAttributes is called");
166 | this.target.errors.attributes = null;
167 | if (!this.target.currentAttributeKey) {
168 | this.target.errors.attributes = "You must specify a tag name and value.";
169 | }
170 | }
171 | }, {
172 | key: 'removeJoinByAttribute',
173 | value: function removeJoinByAttribute(attribute) {
174 | console.info("removeJoinByAttribute is called for " + attribute);
175 |
176 | var index = this.target.attributes.indexOf(attribute);
177 |
178 | this.target.attributes.splice(index, 1);
179 |
180 | if (_.size(this.target.attributes) === 0) {
181 | this.target.attributes = null;
182 | }
183 | this.targetBlur();
184 | }
185 | }, {
186 | key: 'addJoinByAttribute',
187 | value: function addJoinByAttribute() {
188 | console.info("addJoinByAttribute is called");
189 | if (!this.panel.addJoinAttributeMode) {
190 | this.panel.addJoinAttributeMode = true;
191 | this.validateJoinAttributes();
192 | return;
193 | }
194 |
195 | if (!this.target.attributes) {
196 | this.target.attributes = [];
197 | }
198 |
199 | this.validateJoinAttributes();
200 | if (!this.target.errors.attributes) {
201 | this.target.attributes.push(this.target.currentAttributeKey);
202 | this.target.currentAttributeKey = '';
203 |
204 | this.targetBlur();
205 | }
206 |
207 | this.panel.addJoinAttributeMode = false;
208 | }
209 | }, {
210 | key: 'addFilterTag',
211 | value: function addFilterTag() {
212 | if (!this.panel.addFilterTagMode) {
213 | this.panel.addFilterTagMode = true;
214 | this.validateFilterTag();
215 | return;
216 | }
217 |
218 | if (!this.target.tags) {
219 | this.target.tags = {};
220 | }
221 |
222 | this.validateFilterTag();
223 | if (!this.target.errors.tags) {
224 | if (!_.has(this.target.tags, this.target.currentTagKey)) {
225 | this.target.tags[this.target.currentTagKey] = [];
226 | }
227 | this.target.tags[this.target.currentTagKey].push(this.target.currentTagValue);
228 | this.target.currentTagKey = '';
229 | this.target.currentTagValue = '';
230 | this.targetBlur();
231 | }
232 |
233 | this.panel.addFilterTagMode = false;
234 | }
235 | }, {
236 | key: 'removeFilterTag',
237 | value: function removeFilterTag(key) {
238 | delete this.target.tags[key];
239 | if (_.size(this.target.tags) === 0) {
240 | this.target.tags = null;
241 | }
242 | this.targetBlur();
243 | }
244 | }, {
245 | key: 'validateFilterTag',
246 | value: function validateFilterTag() {
247 | this.target.errors.tags = null;
248 | if (!this.target.currentTagKey || !this.target.currentTagValue) {
249 | this.target.errors.tags = "You must specify a tag name and value.";
250 | }
251 | }
252 | }, {
253 | key: 'addGroupBy',
254 | value: function addGroupBy() {
255 | if (!this.panel.addGroupByMode) {
256 | this.target.currentGroupByType = 'tag';
257 | this.panel.addGroupByMode = true;
258 | this.panel.isTagGroupBy = true;
259 | this.validateGroupBy();
260 | return;
261 | }
262 | this.validateGroupBy();
263 | // nb: if error is found, means that user clicked on cross : cancels input
264 |
265 | if (_.isEmpty(this.target.errors.groupBy)) {
266 | if (this.panel.isTagGroupBy) {
267 | if (!this.target.groupByTags) {
268 | this.target.groupByTags = [];
269 | }
270 | if (!_.contains(this.target.groupByTags, this.target.groupBy.tagKey)) {
271 | this.target.groupByTags.push(this.target.groupBy.tagKey);
272 | this.targetBlur();
273 | }
274 | this.target.groupBy.tagKey = '';
275 | } else {
276 | if (!this.target.nonTagGroupBys) {
277 | this.target.nonTagGroupBys = [];
278 | }
279 | var groupBy = {
280 | name: this.target.currentGroupByType
281 | };
282 | if (this.panel.isValueGroupBy) {
283 | groupBy.range_size = this.target.groupBy.valueRange;
284 | } else if (this.panel.isTimeGroupBy) {
285 | groupBy.range_size = this.target.groupBy.timeInterval;
286 | groupBy.group_count = this.target.groupBy.groupCount;
287 | }
288 | this.target.nonTagGroupBys.push(groupBy);
289 | }
290 | this.targetBlur();
291 | }
292 |
293 | this.panel.isTagGroupBy = false;
294 | this.panel.isValueGroupBy = false;
295 | this.panel.isTimeGroupBy = false;
296 | this.panel.addGroupByMode = false;
297 | }
298 | }, {
299 | key: 'removeGroupByTag',
300 | value: function removeGroupByTag(index) {
301 | this.target.groupByTags.splice(index, 1);
302 | if (_.size(this.target.groupByTags) === 0) {
303 | this.target.groupByTags = null;
304 | }
305 | this.targetBlur();
306 | }
307 | }, {
308 | key: 'removeNonTagGroupBy',
309 | value: function removeNonTagGroupBy(index) {
310 | this.target.nonTagGroupBys.splice(index, 1);
311 | if (_.size(this.target.nonTagGroupBys) === 0) {
312 | this.target.nonTagGroupBys = null;
313 | }
314 | this.targetBlur();
315 | }
316 | }, {
317 | key: 'changeGroupByInput',
318 | value: function changeGroupByInput() {
319 | this.panel.isTagGroupBy = this.target.currentGroupByType === 'tag';
320 | this.panel.isValueGroupBy = this.target.currentGroupByType === 'value';
321 | this.panel.isTimeGroupBy = this.target.currentGroupByType === 'time';
322 | this.validateGroupBy();
323 | }
324 | }, {
325 | key: 'getValuesOfGroupBy',
326 | value: function getValuesOfGroupBy(groupBy) {
327 | return _.values(groupBy);
328 | }
329 | }, {
330 | key: 'validateGroupBy',
331 | value: function validateGroupBy() {
332 | delete this.target.errors.groupBy;
333 | var errors = {};
334 | this.panel.isGroupByValid = true;
335 | if (this.panel.isTagGroupBy) {
336 | if (!this.target.groupBy.tagKey) {
337 | this.panel.isGroupByValid = false;
338 | errors.tagKey = 'You must supply a tag name';
339 | }
340 | }
341 |
342 | if (this.panel.isValueGroupBy) {
343 | if (!this.target.groupBy.valueRange || !isInt(this.target.groupBy.valueRange)) {
344 | errors.valueRange = "Range must be an integer";
345 | this.isGroupByValid = false;
346 | }
347 | }
348 |
349 | if (this.panel.isTimeGroupBy) {
350 | try {
351 | this.datasource.convertToChronixInterval(this.target.groupBy.timeInterval);
352 | } catch (err) {
353 | errors.timeInterval = err.message;
354 | this.isGroupByValid = false;
355 | }
356 | if (!this.target.groupBy.groupCount || !isInt(this.target.groupBy.groupCount)) {
357 | errors.groupCount = "Group count must be an integer";
358 | this.isGroupByValid = false;
359 | }
360 | }
361 |
362 | if (!_.isEmpty(errors)) {
363 | this.target.errors.groupBy = errors;
364 | }
365 | }
366 | }, {
367 | key: 'addHorizontalAggregator',
368 | value: function addHorizontalAggregator() {
369 | if (!this.panel.addHorizontalAggregatorMode) {
370 | this.panel.addHorizontalAggregatorMode = true;
371 | this.target.currentHorizontalAggregatorName = 'avg';
372 | this.panel.hasSamplingRate = true;
373 | this.validateHorizontalAggregator();
374 | return;
375 | }
376 |
377 | this.validateHorizontalAggregator();
378 | // nb: if error is found, means that user clicked on cross : cancels input
379 | if (_.isEmpty(this.target.errors.horAggregator)) {
380 | if (!this.target.horizontalAggregators) {
381 | this.target.horizontalAggregators = [];
382 | }
383 | var aggregator = {
384 | name: this.target.currentHorizontalAggregatorName
385 | };
386 | if (this.panel.hasSamplingRate) {
387 | aggregator.sampling_rate = this.target.horAggregator.samplingRate;
388 | }
389 | if (this.panel.hasUnit) {
390 | aggregator.unit = this.target.horAggregator.unit;
391 | }
392 | if (this.panel.hasFactor) {
393 | aggregator.factor = this.target.horAggregator.factor;
394 | }
395 | if (this.panel.hasPercentile) {
396 | aggregator.percentile = this.target.horAggregator.percentile;
397 | }
398 | this.target.horizontalAggregators.push(aggregator);
399 | this.targetBlur();
400 | }
401 |
402 | this.panel.addHorizontalAggregatorMode = false;
403 | this.panel.hasSamplingRate = false;
404 | this.panel.hasUnit = false;
405 | this.panel.hasFactor = false;
406 | this.panel.hasPercentile = false;
407 | }
408 | }, {
409 | key: 'removeHorizontalAggregator',
410 | value: function removeHorizontalAggregator(index) {
411 | this.target.horizontalAggregators.splice(index, 1);
412 | if (_.size(this.target.horizontalAggregators) === 0) {
413 | this.target.horizontalAggregators = null;
414 | }
415 |
416 | this.targetBlur();
417 | }
418 | }, {
419 | key: 'changeHorAggregationInput',
420 | value: function changeHorAggregationInput() {
421 | this.panel.hasSamplingRate = _.contains(['avg', 'dev', 'max', 'min', 'sum', 'least_squares', 'count', 'percentile'], this.target.currentHorizontalAggregatorName);
422 | this.panel.hasUnit = _.contains(['sampler', 'rate'], this.target.currentHorizontalAggregatorName);
423 | this.panel.hasFactor = _.contains(['div', 'scale'], this.target.currentHorizontalAggregatorName);
424 | this.panel.hasPercentile = 'percentile' === this.target.currentHorizontalAggregatorName;
425 | this.validateHorizontalAggregator();
426 | }
427 | }, {
428 | key: 'validateHorizontalAggregator',
429 | value: function validateHorizontalAggregator() {
430 | delete this.target.errors.horAggregator;
431 | var errors = {};
432 | this.panel.isAggregatorValid = true;
433 |
434 | if (this.panel.hasSamplingRate) {
435 | try {
436 | this.datasource.convertToChronixInterval(this.target.horAggregator.samplingRate);
437 | } catch (err) {
438 | errors.samplingRate = err.message;
439 | this.panel.isAggregatorValid = false;
440 | }
441 | }
442 |
443 | if (this.hasFactor) {
444 | if (!this.target.horAggregator.factor) {
445 | errors.factor = 'You must supply a numeric value for this aggregator';
446 | this.panel.isAggregatorValid = false;
447 | } else if (parseInt(this.target.horAggregator.factor) === 0 && this.target.currentHorizontalAggregatorName === 'div') {
448 | errors.factor = 'Cannot divide by 0';
449 | this.panel.isAggregatorValid = false;
450 | }
451 | }
452 |
453 | if (this.panel.hasPercentile) {
454 | if (!this.target.horAggregator.percentile || this.target.horAggregator.percentile <= 0 || this.target.horAggregator.percentile > 1) {
455 | errors.percentile = 'Percentile must be between 0 and 1';
456 | this.panel.isAggregatorValid = false;
457 | }
458 | }
459 |
460 | if (!_.isEmpty(errors)) {
461 | this.target.errors.horAggregator = errors;
462 | }
463 | }
464 | }, {
465 | key: 'alert',
466 | value: function (_alert) {
467 | function alert(_x) {
468 | return _alert.apply(this, arguments);
469 | }
470 |
471 | alert.toString = function () {
472 | return _alert.toString();
473 | };
474 |
475 | return alert;
476 | }(function (message) {
477 | alert(message);
478 | })
479 | }]);
480 |
481 | return ChronixDbQueryController;
482 | }(QueryCtrl));
483 |
484 | _export('ChronixDbQueryController', ChronixDbQueryController);
485 |
486 | ChronixDbQueryController.templateUrl = 'partials/query.editor.html';
487 | }
488 | };
489 | });
490 | //# sourceMappingURL=query-controller.js.map
491 |
--------------------------------------------------------------------------------
/dist/query-controller.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["../src/query-controller.js"],"names":["isInt","n","parseInt","QueryCtrl","_","ChronixDbQueryController","$scope","$injector","panel","stack","downsampling","target","sampling","suggestAttributes","query","callback","datasource","then","getTextValues","bind","suggestTagValues","suggestAttributesValues","name","currentTagKey","suggestTagAttributes","suggestMetrics","findTimeSeriesByNames","validateTarget","getCollapsedText","errs","convertToChronixInterval","err","message","errors","isEqual","oldTarget","isEmpty","angular","copy","panelCtrl","refresh","metricFindResult","map","value","text","console","info","attributes","currentAttributeKey","attribute","index","indexOf","splice","size","targetBlur","addJoinAttributeMode","validateJoinAttributes","push","addFilterTagMode","validateFilterTag","tags","has","currentTagValue","key","addGroupByMode","currentGroupByType","isTagGroupBy","validateGroupBy","groupBy","groupByTags","contains","tagKey","nonTagGroupBys","isValueGroupBy","range_size","valueRange","isTimeGroupBy","timeInterval","group_count","groupCount","values","isGroupByValid","addHorizontalAggregatorMode","currentHorizontalAggregatorName","hasSamplingRate","validateHorizontalAggregator","horAggregator","horizontalAggregators","aggregator","sampling_rate","samplingRate","hasUnit","unit","hasFactor","factor","hasPercentile","percentile","isAggregatorValid","alert","templateUrl"],"mappings":"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","file":"query-controller.js","sourcesContent":["import { QueryCtrl } from 'app/plugins/sdk';\r\nimport _ from 'lodash';\r\n\r\nfunction isInt (n) {\r\n return parseInt(n) % 1 === 0;\r\n}\r\n\r\nexport class ChronixDbQueryController extends QueryCtrl {\r\n\r\n constructor ($scope, $injector) {\r\n super($scope, $injector);\r\n\r\n this.panel.stack = false;\r\n\r\n if (!this.panel.downsampling) {\r\n this.panel.downsampling = 'avg';\r\n }\r\n\r\n if (!this.target.downsampling) {\r\n this.target.downsampling = this.panel.downsampling;\r\n this.target.sampling = this.panel.sampling;\r\n }\r\n\r\n /**\r\n * Is called if someone types something into a key field of an attribute.\r\n */\r\n this.suggestAttributes = (query, callback) => {\r\n this.datasource.suggestAttributes()\r\n .then(this.getTextValues.bind(this))\r\n .then(callback);\r\n };\r\n\r\n /**\r\n * Is called if someone types something into a value field of an attribute.\r\n */\r\n this.suggestTagValues = (query, callback) => {\r\n this.datasource.suggestAttributesValues(this.target.name, this.target.currentTagKey)\r\n .then(this.getTextValues.bind(this))\r\n .then(callback);\r\n };\r\n\r\n /**\r\n * Is called if someone types something into a key field of an attribute.\r\n */\r\n this.suggestTagAttributes = (query, callback) => {\r\n this.datasource.suggestAttributes(query)\r\n .then(this.getTextValues.bind(this))\r\n .then(callback);\r\n };\r\n\r\n this.suggestMetrics = (query, callback) => {\r\n this.datasource.findTimeSeriesByNames(query)\r\n .then(this.getTextValues.bind(this))\r\n .then(callback);\r\n };\r\n\r\n this.validateTarget();\r\n\r\n this.getCollapsedText = () => {\r\n return 'Expand to configure Chronix Query data source';\r\n };\r\n }\r\n\r\n validateTarget () {\r\n var errs = {};\r\n\r\n if (!this.target.name) {\r\n errs.name = \"You must supply a time series name.\";\r\n }\r\n\r\n try {\r\n if (this.target.sampling) {\r\n this.datasource.convertToChronixInterval(this.target.sampling);\r\n }\r\n } catch (err) {\r\n errs.sampling = err.message;\r\n }\r\n\r\n this.target.errors = errs;\r\n }\r\n\r\n targetBlur () {\r\n this.validateTarget();\r\n\r\n if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {\r\n this.oldTarget = angular.copy(this.target);\r\n this.panelCtrl.refresh();\r\n }\r\n };\r\n\r\n getTextValues (metricFindResult) {\r\n return _.map(metricFindResult, function (value) {\r\n return value.text;\r\n });\r\n };\r\n\r\n /**\r\n * =========================================================================\r\n *\r\n * Join section\r\n *\r\n * =========================================================================\r\n */\r\n\r\n /**\r\n * Is called if someone types something into the join by box\r\n * @param query\r\n * @param callback\r\n */\r\n addJoinByAttribute (query, callback) {\r\n console.info(\"add join by attribute is called for \" + query);\r\n\r\n this.datasource.suggestAttributes(query)\r\n .then(this.getTextValues.bind(this))\r\n .then(callback);\r\n };\r\n\r\n validateJoinAttributes () {\r\n console.info(\"validateJoinAttributes is called\");\r\n this.target.errors.attributes = null;\r\n if (!this.target.currentAttributeKey) {\r\n this.target.errors.attributes = \"You must specify a tag name and value.\";\r\n }\r\n };\r\n\r\n /**\r\n * Is calls if someone removes a group by tag\r\n * @param attribute\r\n */\r\n removeJoinByAttribute (attribute) {\r\n console.info(\"removeJoinByAttribute is called for \" + attribute);\r\n\r\n var index = this.target.attributes.indexOf(attribute);\r\n\r\n this.target.attributes.splice(index, 1);\r\n\r\n if (_.size(this.target.attributes) === 0) {\r\n this.target.attributes = null;\r\n }\r\n this.targetBlur();\r\n };\r\n\r\n /**\r\n * Add join by attribute\r\n */\r\n addJoinByAttribute () {\r\n console.info(\"addJoinByAttribute is called\");\r\n if (!this.panel.addJoinAttributeMode) {\r\n this.panel.addJoinAttributeMode = true;\r\n this.validateJoinAttributes();\r\n return;\r\n }\r\n\r\n if (!this.target.attributes) {\r\n this.target.attributes = [];\r\n }\r\n\r\n this.validateJoinAttributes();\r\n if (!this.target.errors.attributes) {\r\n this.target.attributes.push(this.target.currentAttributeKey);\r\n this.target.currentAttributeKey = '';\r\n\r\n this.targetBlur();\r\n }\r\n\r\n this.panel.addJoinAttributeMode = false;\r\n };\r\n\r\n // Filter metric by tag\r\n addFilterTag () {\r\n if (!this.panel.addFilterTagMode) {\r\n this.panel.addFilterTagMode = true;\r\n this.validateFilterTag();\r\n return;\r\n }\r\n\r\n if (!this.target.tags) {\r\n this.target.tags = {};\r\n }\r\n\r\n this.validateFilterTag();\r\n if (!this.target.errors.tags) {\r\n if (!_.has(this.target.tags, this.target.currentTagKey)) {\r\n this.target.tags[this.target.currentTagKey] = [];\r\n }\r\n this.target.tags[this.target.currentTagKey].push(this.target.currentTagValue);\r\n this.target.currentTagKey = '';\r\n this.target.currentTagValue = '';\r\n this.targetBlur();\r\n }\r\n\r\n this.panel.addFilterTagMode = false;\r\n };\r\n\r\n removeFilterTag (key) {\r\n delete this.target.tags[key];\r\n if (_.size(this.target.tags) === 0) {\r\n this.target.tags = null;\r\n }\r\n this.targetBlur();\r\n };\r\n\r\n validateFilterTag () {\r\n this.target.errors.tags = null;\r\n if (!this.target.currentTagKey || !this.target.currentTagValue) {\r\n this.target.errors.tags = \"You must specify a tag name and value.\";\r\n }\r\n };\r\n\r\n //////////////////////////////\r\n // GROUP BY\r\n //////////////////////////////\r\n addGroupBy () {\r\n if (!this.panel.addGroupByMode) {\r\n this.target.currentGroupByType = 'tag';\r\n this.panel.addGroupByMode = true;\r\n this.panel.isTagGroupBy = true;\r\n this.validateGroupBy();\r\n return;\r\n }\r\n this.validateGroupBy();\r\n // nb: if error is found, means that user clicked on cross : cancels input\r\n\r\n if (_.isEmpty(this.target.errors.groupBy)) {\r\n if (this.panel.isTagGroupBy) {\r\n if (!this.target.groupByTags) {\r\n this.target.groupByTags = [];\r\n }\r\n if (!_.contains(this.target.groupByTags, this.target.groupBy.tagKey)) {\r\n this.target.groupByTags.push(this.target.groupBy.tagKey);\r\n this.targetBlur();\r\n }\r\n this.target.groupBy.tagKey = '';\r\n }\r\n else {\r\n if (!this.target.nonTagGroupBys) {\r\n this.target.nonTagGroupBys = [];\r\n }\r\n var groupBy = {\r\n name: this.target.currentGroupByType\r\n };\r\n if (this.panel.isValueGroupBy) {\r\n groupBy.range_size = this.target.groupBy.valueRange;\r\n } else if (this.panel.isTimeGroupBy) {\r\n groupBy.range_size = this.target.groupBy.timeInterval;\r\n groupBy.group_count = this.target.groupBy.groupCount;\r\n }\r\n this.target.nonTagGroupBys.push(groupBy);\r\n }\r\n this.targetBlur();\r\n }\r\n\r\n this.panel.isTagGroupBy = false;\r\n this.panel.isValueGroupBy = false;\r\n this.panel.isTimeGroupBy = false;\r\n this.panel.addGroupByMode = false;\r\n };\r\n\r\n removeGroupByTag (index) {\r\n this.target.groupByTags.splice(index, 1);\r\n if (_.size(this.target.groupByTags) === 0) {\r\n this.target.groupByTags = null;\r\n }\r\n this.targetBlur();\r\n };\r\n\r\n removeNonTagGroupBy (index) {\r\n this.target.nonTagGroupBys.splice(index, 1);\r\n if (_.size(this.target.nonTagGroupBys) === 0) {\r\n this.target.nonTagGroupBys = null;\r\n }\r\n this.targetBlur();\r\n };\r\n\r\n changeGroupByInput () {\r\n this.panel.isTagGroupBy = this.target.currentGroupByType === 'tag';\r\n this.panel.isValueGroupBy = this.target.currentGroupByType === 'value';\r\n this.panel.isTimeGroupBy = this.target.currentGroupByType === 'time';\r\n this.validateGroupBy();\r\n };\r\n\r\n getValuesOfGroupBy (groupBy) {\r\n return _.values(groupBy);\r\n };\r\n\r\n validateGroupBy () {\r\n delete this.target.errors.groupBy;\r\n var errors = {};\r\n this.panel.isGroupByValid = true;\r\n if (this.panel.isTagGroupBy) {\r\n if (!this.target.groupBy.tagKey) {\r\n this.panel.isGroupByValid = false;\r\n errors.tagKey = 'You must supply a tag name';\r\n }\r\n }\r\n\r\n if (this.panel.isValueGroupBy) {\r\n if (!this.target.groupBy.valueRange || !isInt(this.target.groupBy.valueRange)) {\r\n errors.valueRange = \"Range must be an integer\";\r\n this.isGroupByValid = false;\r\n }\r\n }\r\n\r\n if (this.panel.isTimeGroupBy) {\r\n try {\r\n this.datasource.convertToChronixInterval(this.target.groupBy.timeInterval);\r\n } catch (err) {\r\n errors.timeInterval = err.message;\r\n this.isGroupByValid = false;\r\n }\r\n if (!this.target.groupBy.groupCount || !isInt(this.target.groupBy.groupCount)) {\r\n errors.groupCount = \"Group count must be an integer\";\r\n this.isGroupByValid = false;\r\n }\r\n }\r\n\r\n if (!_.isEmpty(errors)) {\r\n this.target.errors.groupBy = errors;\r\n }\r\n };\r\n\r\n //////////////////////////////\r\n // HORIZONTAL AGGREGATION\r\n //////////////////////////////\r\n\r\n addHorizontalAggregator () {\r\n if (!this.panel.addHorizontalAggregatorMode) {\r\n this.panel.addHorizontalAggregatorMode = true;\r\n this.target.currentHorizontalAggregatorName = 'avg';\r\n this.panel.hasSamplingRate = true;\r\n this.validateHorizontalAggregator();\r\n return;\r\n }\r\n\r\n this.validateHorizontalAggregator();\r\n // nb: if error is found, means that user clicked on cross : cancels input\r\n if (_.isEmpty(this.target.errors.horAggregator)) {\r\n if (!this.target.horizontalAggregators) {\r\n this.target.horizontalAggregators = [];\r\n }\r\n var aggregator = {\r\n name: this.target.currentHorizontalAggregatorName\r\n };\r\n if (this.panel.hasSamplingRate) {\r\n aggregator.sampling_rate = this.target.horAggregator.samplingRate;\r\n }\r\n if (this.panel.hasUnit) {\r\n aggregator.unit = this.target.horAggregator.unit;\r\n }\r\n if (this.panel.hasFactor) {\r\n aggregator.factor = this.target.horAggregator.factor;\r\n }\r\n if (this.panel.hasPercentile) {\r\n aggregator.percentile = this.target.horAggregator.percentile;\r\n }\r\n this.target.horizontalAggregators.push(aggregator);\r\n this.targetBlur();\r\n }\r\n\r\n this.panel.addHorizontalAggregatorMode = false;\r\n this.panel.hasSamplingRate = false;\r\n this.panel.hasUnit = false;\r\n this.panel.hasFactor = false;\r\n this.panel.hasPercentile = false;\r\n };\r\n\r\n removeHorizontalAggregator (index) {\r\n this.target.horizontalAggregators.splice(index, 1);\r\n if (_.size(this.target.horizontalAggregators) === 0) {\r\n this.target.horizontalAggregators = null;\r\n }\r\n\r\n this.targetBlur();\r\n };\r\n\r\n changeHorAggregationInput () {\r\n this.panel.hasSamplingRate = _.contains(['avg', 'dev', 'max', 'min', 'sum', 'least_squares', 'count', 'percentile'],\r\n this.target.currentHorizontalAggregatorName);\r\n this.panel.hasUnit = _.contains(['sampler', 'rate'], this.target.currentHorizontalAggregatorName);\r\n this.panel.hasFactor = _.contains(['div', 'scale'], this.target.currentHorizontalAggregatorName);\r\n this.panel.hasPercentile = 'percentile' === this.target.currentHorizontalAggregatorName;\r\n this.validateHorizontalAggregator();\r\n };\r\n\r\n validateHorizontalAggregator () {\r\n delete this.target.errors.horAggregator;\r\n var errors = {};\r\n this.panel.isAggregatorValid = true;\r\n\r\n if (this.panel.hasSamplingRate) {\r\n try {\r\n this.datasource.convertToChronixInterval(this.target.horAggregator.samplingRate);\r\n } catch (err) {\r\n errors.samplingRate = err.message;\r\n this.panel.isAggregatorValid = false;\r\n }\r\n }\r\n\r\n if (this.hasFactor) {\r\n if (!this.target.horAggregator.factor) {\r\n errors.factor = 'You must supply a numeric value for this aggregator';\r\n this.panel.isAggregatorValid = false;\r\n }\r\n else if (parseInt(this.target.horAggregator.factor) === 0 && this.target.currentHorizontalAggregatorName === 'div') {\r\n errors.factor = 'Cannot divide by 0';\r\n this.panel.isAggregatorValid = false;\r\n }\r\n }\r\n\r\n if (this.panel.hasPercentile) {\r\n if (!this.target.horAggregator.percentile ||\r\n this.target.horAggregator.percentile <= 0 ||\r\n this.target.horAggregator.percentile > 1) {\r\n errors.percentile = 'Percentile must be between 0 and 1';\r\n this.panel.isAggregatorValid = false;\r\n }\r\n }\r\n\r\n if (!_.isEmpty(errors)) {\r\n this.target.errors.horAggregator = errors;\r\n }\r\n };\r\n\r\n alert (message) {\r\n alert(message);\r\n };\r\n\r\n}\r\n\r\nChronixDbQueryController.templateUrl = 'partials/query.editor.html';\r\n"]}
--------------------------------------------------------------------------------
/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChronixDB/chronix.grafana/f0fa8361fbf97f9fc860c8fb4e830dfd2e65a9d8/img/logo.png
--------------------------------------------------------------------------------
/img/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChronixDB/chronix.grafana/f0fa8361fbf97f9fc860c8fb4e830dfd2e65a9d8/img/screenshot.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chronix-grafana",
3 | "version": "0.4.0",
4 | "description": "Datasource plugin for Chronix",
5 | "repository": {
6 | "type": "git",
7 | "url": "git+https://github.com/ChronixDB/chronix.grafana"
8 | },
9 | "author": {
10 | "name": "Florian Lautenschlager",
11 | "email": "florian.lautenschlager@qaware.de"
12 | },
13 | "contributors": [
14 | {
15 | "name": "Roland Hummel",
16 | "email": "roland.hummel@qaware.de"
17 | }
18 | ],
19 | "license": "Apache-2.0",
20 | "devDependencies": {
21 | "babel-core": "^6.5.1",
22 | "babel-plugin-transform-es2015-for-of": "^6.8.0",
23 | "babel-plugin-transform-es2015-modules-systemjs": "^6.14.0",
24 | "babel-preset-es2015": "^6.14.0",
25 | "grunt": "^1.0.1",
26 | "grunt-babel": "^6.0.0",
27 | "grunt-cli": "^1.2.0",
28 | "grunt-contrib-clean": "^1.0.0",
29 | "grunt-contrib-copy": "^1.0.0",
30 | "grunt-contrib-watch": "^1.0.0",
31 | "load-grunt-tasks": "^3.5.2"
32 | },
33 | "dependencies": {
34 | "lodash": "^4.0.0"
35 | },
36 | "scripts": {
37 | "build": "grunt",
38 | "watch": "grunt watch",
39 | "test": "grunt test"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/plugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "datasource",
3 | "name": "Chronix",
4 | "id": "chronix",
5 | "info": {
6 | "description": "Datasource plugin for Chronix",
7 | "author": {
8 | "name": "QAware",
9 | "url": "http://www.chronix.io"
10 | },
11 | "keywords": [
12 | "chronix",
13 | "chronixdb",
14 | "apache solr",
15 | "solr",
16 | "time series",
17 | "timeseries",
18 | "time-series"
19 | ],
20 | "logos": {
21 | "small": "img/logo.png",
22 | "large": "img/logo.png"
23 | },
24 | "links": [
25 | {
26 | "name": "Home Page",
27 | "url": "http://www.chronix.io"
28 | },
29 | {
30 | "name": "GitHub",
31 | "url": "https://github.com/ChronixDB/chronix.grafana"
32 | },
33 | {
34 | "name": "Issues",
35 | "url": "https://github.com/ChronixDB/chronix.grafana/issues"
36 | },
37 | {
38 | "name": "License",
39 | "url": "https://github.com/ChronixDB/chronix.grafana/blob/master/LICENSE"
40 | }
41 | ],
42 | "screenshots": [
43 | {
44 | "name": "ChronixDB in Grafana",
45 | "path": "img/screenshot.png"
46 | }
47 | ],
48 | "version": "0.4.0",
49 | "updated": "2016-11-05"
50 | },
51 | "metrics": true,
52 | "annotations": false,
53 | "dependencies": {
54 | "grafanaVersion": "3.x.x",
55 | "plugins": []
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/config-controller.js:
--------------------------------------------------------------------------------
1 | export class ChronixConfigController {}
2 |
3 | ChronixConfigController.templateUrl = 'partials/config.html';
4 |
--------------------------------------------------------------------------------
/src/datasource.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 |
3 | function escapeTag(name) {
4 | return name.indexOf('.') !== -1 ? `"${name}"` : name;
5 | }
6 |
7 | function toTagQueryString(tag, tagName) {
8 | return tagName + ':(' + tag.map(escapeTag).join(' OR ') + ')'
9 | }
10 |
11 | function toTargetQueryString(target) {
12 | if (!target.tags || Object.keys(target.tags).length === 0) {
13 | // simple name-only
14 | return target.name;
15 | }
16 |
17 | // create strings for each tag
18 | const targetQueryStrings = _(target.tags).map(toTagQueryString);
19 |
20 | return '(' + target.name + ' AND ' + targetQueryStrings.join(' AND ') + ')';
21 | }
22 |
23 | function toTargetJoinString(target) {
24 | if (!target.attributes || Object.keys(target.attributes).length === 0) {
25 | return "name";
26 | }
27 | // create strings for each tag
28 | return _(target.attributes).join(',') + ",name,type";
29 | }
30 |
31 | var requiredFields = ["data", "start", "end", "_version_", "id", "name", "type"];
32 |
33 | export class ChronixDbDatasource {
34 |
35 | constructor(instanceSettings, $q, backendSrv, templateSrv) {
36 | this.type = instanceSettings.type;
37 | this.url = instanceSettings.url;
38 | this.name = instanceSettings.name;
39 | this.$q = $q;
40 | this.backendSrv = backendSrv;
41 | this.templateSrv = templateSrv;
42 | }
43 |
44 | //region Required Grafana Datasource methods
45 |
46 | query(options) {
47 | // get the start and the end and multiply it with 1000 to get millis since 1970
48 | var start = options.range.from.unix() * 1000;
49 | var end = options.range.to.unix() * 1000;
50 | var targets = options.targets;
51 |
52 | return this.rawQuery(targets, start, end).then(this.extractTimeSeries);
53 | }
54 |
55 | /**
56 | * Attempts to connect to the URL entered by the user and responds with a promise to either a "success" or an
57 | * "error" message.
58 | */
59 | testDatasource() {
60 | const options = {
61 | url: `${this.url}/select?q=%7B!lucene%7D*%3A*&rows=0`,
62 | method: 'GET'
63 | };
64 | const successMessage = {
65 | status: "success",
66 | message: "Connection to Chronix established",
67 | title: "Success"
68 | };
69 | const errorMessage = this.$q.reject({
70 | status: "error",
71 | message: "Connection to Chronix failed",
72 | title: "Error"
73 | });
74 |
75 | // perform the actual call...
76 | return this.backendSrv.datasourceRequest(options)
77 | // ... check if the response is technically successful ...
78 | .then(response => response && response.status === 200)
79 | // ... and respond appropriately
80 | .then(success => success ? successMessage : errorMessage)
81 | // ... and react appropriately, too, when the call somehow didn't work
82 | .catch(error => errorMessage);
83 | }
84 |
85 | /**
86 | *
87 | */
88 | findTimeSeriesByNames(tsName) {
89 | const emptyResult = this.$q.when([]);
90 |
91 | if (!tsName || tsName === '*') {
92 | // no "*" accepted from the user
93 | return emptyResult;
94 | }
95 |
96 | if (tsName.indexOf('*') === -1) {
97 | // append an "*" at the end if the user didn't already provide one
98 | tsName = tsName + '*';
99 | }
100 |
101 | const options = {
102 | //do a facet query
103 | url: `${this.url}/select?facet.field=name&facet=on&facet.mincount=1&q=name:${tsName}&rows=0&wt=json`,
104 | method: 'GET'
105 | };
106 |
107 | return this.backendSrv.datasourceRequest(options)
108 | .then(response => response && response.data && response.data.facet_counts && response.data.facet_counts.facet_fields && response.data.facet_counts.facet_fields.name)
109 | .then((nameFields) => {
110 | // somehow no valid response => empty array
111 | if (!nameFields) {
112 | console.log(`could not find any matching time series for "${tsName}"`);
113 | return emptyResult;
114 | }
115 |
116 | // take only the names, not the counts
117 | return nameFields
118 | .filter((unused, index) => index % 2 === 0)
119 | // and provide them as objects with the "text" property
120 | .map(text => ({text}));
121 | })
122 | // if the request itself failed
123 | .catch(error => emptyResult);
124 | }
125 |
126 | //endregion
127 |
128 | rawQuery(targets, start, end) {
129 | // create strings for each target
130 | var targetsQueryStrings = _(targets).map(toTargetQueryString);
131 |
132 | var query = 'name:(' + targetsQueryStrings.join(' OR ') + ')'
133 | + ' AND start:' + start
134 | + ' AND end:' + end;
135 |
136 | var joinquery = _(targets).map(toTargetJoinString);
137 |
138 | //At this point we have to query chronix
139 | var RAW_QUERY_BASE = '/select?fl=dataAsJson&wt=json';
140 | var RAW_QUERY_JOIN = '&cj=' + joinquery;
141 | var RAW_QUERY_FILTER_FUNCTION = '';//'&cf=metric{vector:0.1}';
142 | var RAW_QUERY_BASE_WITH_FILTER = RAW_QUERY_BASE + RAW_QUERY_FILTER_FUNCTION + RAW_QUERY_JOIN + '&q=';
143 |
144 | console.log("Chronix Query: " + RAW_QUERY_BASE_WITH_FILTER + query);
145 |
146 | var options = {
147 | method: 'GET',
148 | url: this.url + RAW_QUERY_BASE_WITH_FILTER + query
149 | };
150 |
151 | return this.backendSrv.datasourceRequest(options).then(function (response) {
152 | return [targets, response];
153 | });
154 | }
155 |
156 | extractTimeSeries(targetsResponse) {
157 | var response = targetsResponse[1];
158 |
159 | if (response.data === undefined) {
160 | return {data: []};
161 | }
162 | var dataset = response.data.response.docs;
163 |
164 | var tsPoints = {};
165 |
166 | for (var i = 0; i < dataset.length; i++) {
167 | var currentDataSet = dataset[i];
168 | var currentTimeSeries = currentDataSet.name;
169 |
170 | if (!(currentTimeSeries in tsPoints)) {
171 | tsPoints[currentTimeSeries] = [];
172 | }
173 |
174 | var jsonData = JSON.parse(currentDataSet.dataAsJson);
175 |
176 | var timestamps = jsonData[0];
177 | var values = jsonData[1];
178 |
179 | //add them
180 | for (var j = 0; j < timestamps.length; j++) {
181 | tsPoints[currentTimeSeries].push([values[j], timestamps[j]]);
182 | }
183 |
184 | }
185 |
186 | var ret = [];
187 | for (var key in tsPoints) {
188 | ret.push({target: key, datapoints: tsPoints[key]});
189 | }
190 | return {data: ret};
191 | }
192 |
193 | /**
194 | * Gets the available fields / attributes
195 | */
196 | suggestAttributes() {
197 | var options = {
198 | method: 'GET',
199 | url: this.url + '/admin/luke?numTerms=0&wt=json'
200 | };
201 |
202 | return this.backendSrv.datasourceRequest(options).then(this.mapToTextValue);
203 | }
204 |
205 | mapToTextValue(result) {
206 | var fields = result.data.fields;
207 |
208 | var stringFields = [];
209 | //Iterate over the returned fields
210 | for (var property in fields) {
211 | if (fields.hasOwnProperty(property)) {
212 | if (requiredFields.indexOf(property.toLowerCase()) == -1) {
213 | stringFields.push(property)
214 | }
215 | }
216 | }
217 | return _.map(stringFields, (name) => {
218 | return {text: name};
219 | });
220 | }
221 |
222 | /**
223 | * Gets the available values for the attributes.
224 | *
225 | * @param name The name to get the available attributes.
226 | * @param attribute The attribute.
227 | */
228 | suggestAttributesValues(name, attribute) {
229 | var options = {
230 | method: 'GET',
231 | url: this.url + '/select?facet.field=' + attribute + '&facet=on&q=name:' + name + '&rows=0&wt=json'
232 | };
233 |
234 | return this.backendSrv.datasourceRequest(options).then(this.mapValueToText);
235 | }
236 |
237 | mapValueToText(result) {
238 | var fields = result.data.facet_counts.facet_fields;
239 |
240 | var field;
241 | //Iterate over the returned fields
242 | for (var property in fields) {
243 | if (fields.hasOwnProperty(property)) {
244 | field = property;
245 | }
246 | }
247 |
248 | var pairs = [];
249 | var values = fields[field];
250 |
251 | //Build pairs
252 | for (var i = 0; i < values.length; i++) {
253 | pairs.push([values[i], values[++i]]);
254 | }
255 |
256 | return _.map(pairs, (pair) => {
257 | return {text: pair[0], value: pair[1]};
258 | });
259 | }
260 |
261 | }
262 |
--------------------------------------------------------------------------------
/src/module.js:
--------------------------------------------------------------------------------
1 | import { ChronixDbDatasource } from './datasource';
2 | import { ChronixDbQueryController } from './query-controller';
3 | import { ChronixConfigController } from './config-controller';
4 |
5 | export {
6 | ChronixDbDatasource as Datasource,
7 | ChronixDbQueryController as QueryCtrl,
8 | ChronixConfigController as ConfigCtrl
9 | };
10 |
--------------------------------------------------------------------------------
/src/partials/config.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/partials/query.editor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Time Series
7 |
8 |
Name:
9 |
25 |
26 |
27 |
28 |
Attributes
29 |
30 |
31 |
32 |
{{ key }} = {{ value }}
33 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
Attribute key:
49 |
50 |
59 |
60 |
61 |
62 |
Attribute value:
63 |
64 |
73 |
74 |
75 |
83 |
84 |
85 |
86 |
87 |
88 |
Join by
89 |
90 |
91 |
97 |
98 |
99 |
104 |
105 |
106 |
107 |
108 |
Join type:
109 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/src/query-controller.js:
--------------------------------------------------------------------------------
1 | import { QueryCtrl } from 'app/plugins/sdk';
2 | import _ from 'lodash';
3 |
4 | function isInt (n) {
5 | return parseInt(n) % 1 === 0;
6 | }
7 |
8 | export class ChronixDbQueryController extends QueryCtrl {
9 |
10 | constructor ($scope, $injector) {
11 | super($scope, $injector);
12 |
13 | this.panel.stack = false;
14 |
15 | if (!this.panel.downsampling) {
16 | this.panel.downsampling = 'avg';
17 | }
18 |
19 | if (!this.target.downsampling) {
20 | this.target.downsampling = this.panel.downsampling;
21 | this.target.sampling = this.panel.sampling;
22 | }
23 |
24 | /**
25 | * Is called if someone types something into a key field of an attribute.
26 | */
27 | this.suggestAttributes = (query, callback) => {
28 | this.datasource.suggestAttributes()
29 | .then(this.getTextValues.bind(this))
30 | .then(callback);
31 | };
32 |
33 | /**
34 | * Is called if someone types something into a value field of an attribute.
35 | */
36 | this.suggestTagValues = (query, callback) => {
37 | this.datasource.suggestAttributesValues(this.target.name, this.target.currentTagKey)
38 | .then(this.getTextValues.bind(this))
39 | .then(callback);
40 | };
41 |
42 | /**
43 | * Is called if someone types something into a key field of an attribute.
44 | */
45 | this.suggestTagAttributes = (query, callback) => {
46 | this.datasource.suggestAttributes(query)
47 | .then(this.getTextValues.bind(this))
48 | .then(callback);
49 | };
50 |
51 | this.suggestMetrics = (query, callback) => {
52 | this.datasource.findTimeSeriesByNames(query)
53 | .then(this.getTextValues.bind(this))
54 | .then(callback);
55 | };
56 |
57 | this.validateTarget();
58 |
59 | this.getCollapsedText = () => {
60 | return 'Expand to configure Chronix Query data source';
61 | };
62 | }
63 |
64 | validateTarget () {
65 | var errs = {};
66 |
67 | if (!this.target.name) {
68 | errs.name = "You must supply a time series name.";
69 | }
70 |
71 | try {
72 | if (this.target.sampling) {
73 | this.datasource.convertToChronixInterval(this.target.sampling);
74 | }
75 | } catch (err) {
76 | errs.sampling = err.message;
77 | }
78 |
79 | this.target.errors = errs;
80 | }
81 |
82 | targetBlur () {
83 | this.validateTarget();
84 |
85 | if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
86 | this.oldTarget = angular.copy(this.target);
87 | this.panelCtrl.refresh();
88 | }
89 | };
90 |
91 | getTextValues (metricFindResult) {
92 | return _.map(metricFindResult, function (value) {
93 | return value.text;
94 | });
95 | };
96 |
97 | /**
98 | * =========================================================================
99 | *
100 | * Join section
101 | *
102 | * =========================================================================
103 | */
104 |
105 | /**
106 | * Is called if someone types something into the join by box
107 | * @param query
108 | * @param callback
109 | */
110 | addJoinByAttribute (query, callback) {
111 | console.info("add join by attribute is called for " + query);
112 |
113 | this.datasource.suggestAttributes(query)
114 | .then(this.getTextValues.bind(this))
115 | .then(callback);
116 | };
117 |
118 | validateJoinAttributes () {
119 | console.info("validateJoinAttributes is called");
120 | this.target.errors.attributes = null;
121 | if (!this.target.currentAttributeKey) {
122 | this.target.errors.attributes = "You must specify a tag name and value.";
123 | }
124 | };
125 |
126 | /**
127 | * Is calls if someone removes a group by tag
128 | * @param attribute
129 | */
130 | removeJoinByAttribute (attribute) {
131 | console.info("removeJoinByAttribute is called for " + attribute);
132 |
133 | var index = this.target.attributes.indexOf(attribute);
134 |
135 | this.target.attributes.splice(index, 1);
136 |
137 | if (_.size(this.target.attributes) === 0) {
138 | this.target.attributes = null;
139 | }
140 | this.targetBlur();
141 | };
142 |
143 | /**
144 | * Add join by attribute
145 | */
146 | addJoinByAttribute () {
147 | console.info("addJoinByAttribute is called");
148 | if (!this.panel.addJoinAttributeMode) {
149 | this.panel.addJoinAttributeMode = true;
150 | this.validateJoinAttributes();
151 | return;
152 | }
153 |
154 | if (!this.target.attributes) {
155 | this.target.attributes = [];
156 | }
157 |
158 | this.validateJoinAttributes();
159 | if (!this.target.errors.attributes) {
160 | this.target.attributes.push(this.target.currentAttributeKey);
161 | this.target.currentAttributeKey = '';
162 |
163 | this.targetBlur();
164 | }
165 |
166 | this.panel.addJoinAttributeMode = false;
167 | };
168 |
169 | // Filter metric by tag
170 | addFilterTag () {
171 | if (!this.panel.addFilterTagMode) {
172 | this.panel.addFilterTagMode = true;
173 | this.validateFilterTag();
174 | return;
175 | }
176 |
177 | if (!this.target.tags) {
178 | this.target.tags = {};
179 | }
180 |
181 | this.validateFilterTag();
182 | if (!this.target.errors.tags) {
183 | if (!_.has(this.target.tags, this.target.currentTagKey)) {
184 | this.target.tags[this.target.currentTagKey] = [];
185 | }
186 | this.target.tags[this.target.currentTagKey].push(this.target.currentTagValue);
187 | this.target.currentTagKey = '';
188 | this.target.currentTagValue = '';
189 | this.targetBlur();
190 | }
191 |
192 | this.panel.addFilterTagMode = false;
193 | };
194 |
195 | removeFilterTag (key) {
196 | delete this.target.tags[key];
197 | if (_.size(this.target.tags) === 0) {
198 | this.target.tags = null;
199 | }
200 | this.targetBlur();
201 | };
202 |
203 | validateFilterTag () {
204 | this.target.errors.tags = null;
205 | if (!this.target.currentTagKey || !this.target.currentTagValue) {
206 | this.target.errors.tags = "You must specify a tag name and value.";
207 | }
208 | };
209 |
210 | //////////////////////////////
211 | // GROUP BY
212 | //////////////////////////////
213 | addGroupBy () {
214 | if (!this.panel.addGroupByMode) {
215 | this.target.currentGroupByType = 'tag';
216 | this.panel.addGroupByMode = true;
217 | this.panel.isTagGroupBy = true;
218 | this.validateGroupBy();
219 | return;
220 | }
221 | this.validateGroupBy();
222 | // nb: if error is found, means that user clicked on cross : cancels input
223 |
224 | if (_.isEmpty(this.target.errors.groupBy)) {
225 | if (this.panel.isTagGroupBy) {
226 | if (!this.target.groupByTags) {
227 | this.target.groupByTags = [];
228 | }
229 | if (!_.contains(this.target.groupByTags, this.target.groupBy.tagKey)) {
230 | this.target.groupByTags.push(this.target.groupBy.tagKey);
231 | this.targetBlur();
232 | }
233 | this.target.groupBy.tagKey = '';
234 | }
235 | else {
236 | if (!this.target.nonTagGroupBys) {
237 | this.target.nonTagGroupBys = [];
238 | }
239 | var groupBy = {
240 | name: this.target.currentGroupByType
241 | };
242 | if (this.panel.isValueGroupBy) {
243 | groupBy.range_size = this.target.groupBy.valueRange;
244 | } else if (this.panel.isTimeGroupBy) {
245 | groupBy.range_size = this.target.groupBy.timeInterval;
246 | groupBy.group_count = this.target.groupBy.groupCount;
247 | }
248 | this.target.nonTagGroupBys.push(groupBy);
249 | }
250 | this.targetBlur();
251 | }
252 |
253 | this.panel.isTagGroupBy = false;
254 | this.panel.isValueGroupBy = false;
255 | this.panel.isTimeGroupBy = false;
256 | this.panel.addGroupByMode = false;
257 | };
258 |
259 | removeGroupByTag (index) {
260 | this.target.groupByTags.splice(index, 1);
261 | if (_.size(this.target.groupByTags) === 0) {
262 | this.target.groupByTags = null;
263 | }
264 | this.targetBlur();
265 | };
266 |
267 | removeNonTagGroupBy (index) {
268 | this.target.nonTagGroupBys.splice(index, 1);
269 | if (_.size(this.target.nonTagGroupBys) === 0) {
270 | this.target.nonTagGroupBys = null;
271 | }
272 | this.targetBlur();
273 | };
274 |
275 | changeGroupByInput () {
276 | this.panel.isTagGroupBy = this.target.currentGroupByType === 'tag';
277 | this.panel.isValueGroupBy = this.target.currentGroupByType === 'value';
278 | this.panel.isTimeGroupBy = this.target.currentGroupByType === 'time';
279 | this.validateGroupBy();
280 | };
281 |
282 | getValuesOfGroupBy (groupBy) {
283 | return _.values(groupBy);
284 | };
285 |
286 | validateGroupBy () {
287 | delete this.target.errors.groupBy;
288 | var errors = {};
289 | this.panel.isGroupByValid = true;
290 | if (this.panel.isTagGroupBy) {
291 | if (!this.target.groupBy.tagKey) {
292 | this.panel.isGroupByValid = false;
293 | errors.tagKey = 'You must supply a tag name';
294 | }
295 | }
296 |
297 | if (this.panel.isValueGroupBy) {
298 | if (!this.target.groupBy.valueRange || !isInt(this.target.groupBy.valueRange)) {
299 | errors.valueRange = "Range must be an integer";
300 | this.isGroupByValid = false;
301 | }
302 | }
303 |
304 | if (this.panel.isTimeGroupBy) {
305 | try {
306 | this.datasource.convertToChronixInterval(this.target.groupBy.timeInterval);
307 | } catch (err) {
308 | errors.timeInterval = err.message;
309 | this.isGroupByValid = false;
310 | }
311 | if (!this.target.groupBy.groupCount || !isInt(this.target.groupBy.groupCount)) {
312 | errors.groupCount = "Group count must be an integer";
313 | this.isGroupByValid = false;
314 | }
315 | }
316 |
317 | if (!_.isEmpty(errors)) {
318 | this.target.errors.groupBy = errors;
319 | }
320 | };
321 |
322 | //////////////////////////////
323 | // HORIZONTAL AGGREGATION
324 | //////////////////////////////
325 |
326 | addHorizontalAggregator () {
327 | if (!this.panel.addHorizontalAggregatorMode) {
328 | this.panel.addHorizontalAggregatorMode = true;
329 | this.target.currentHorizontalAggregatorName = 'avg';
330 | this.panel.hasSamplingRate = true;
331 | this.validateHorizontalAggregator();
332 | return;
333 | }
334 |
335 | this.validateHorizontalAggregator();
336 | // nb: if error is found, means that user clicked on cross : cancels input
337 | if (_.isEmpty(this.target.errors.horAggregator)) {
338 | if (!this.target.horizontalAggregators) {
339 | this.target.horizontalAggregators = [];
340 | }
341 | var aggregator = {
342 | name: this.target.currentHorizontalAggregatorName
343 | };
344 | if (this.panel.hasSamplingRate) {
345 | aggregator.sampling_rate = this.target.horAggregator.samplingRate;
346 | }
347 | if (this.panel.hasUnit) {
348 | aggregator.unit = this.target.horAggregator.unit;
349 | }
350 | if (this.panel.hasFactor) {
351 | aggregator.factor = this.target.horAggregator.factor;
352 | }
353 | if (this.panel.hasPercentile) {
354 | aggregator.percentile = this.target.horAggregator.percentile;
355 | }
356 | this.target.horizontalAggregators.push(aggregator);
357 | this.targetBlur();
358 | }
359 |
360 | this.panel.addHorizontalAggregatorMode = false;
361 | this.panel.hasSamplingRate = false;
362 | this.panel.hasUnit = false;
363 | this.panel.hasFactor = false;
364 | this.panel.hasPercentile = false;
365 | };
366 |
367 | removeHorizontalAggregator (index) {
368 | this.target.horizontalAggregators.splice(index, 1);
369 | if (_.size(this.target.horizontalAggregators) === 0) {
370 | this.target.horizontalAggregators = null;
371 | }
372 |
373 | this.targetBlur();
374 | };
375 |
376 | changeHorAggregationInput () {
377 | this.panel.hasSamplingRate = _.contains(['avg', 'dev', 'max', 'min', 'sum', 'least_squares', 'count', 'percentile'],
378 | this.target.currentHorizontalAggregatorName);
379 | this.panel.hasUnit = _.contains(['sampler', 'rate'], this.target.currentHorizontalAggregatorName);
380 | this.panel.hasFactor = _.contains(['div', 'scale'], this.target.currentHorizontalAggregatorName);
381 | this.panel.hasPercentile = 'percentile' === this.target.currentHorizontalAggregatorName;
382 | this.validateHorizontalAggregator();
383 | };
384 |
385 | validateHorizontalAggregator () {
386 | delete this.target.errors.horAggregator;
387 | var errors = {};
388 | this.panel.isAggregatorValid = true;
389 |
390 | if (this.panel.hasSamplingRate) {
391 | try {
392 | this.datasource.convertToChronixInterval(this.target.horAggregator.samplingRate);
393 | } catch (err) {
394 | errors.samplingRate = err.message;
395 | this.panel.isAggregatorValid = false;
396 | }
397 | }
398 |
399 | if (this.hasFactor) {
400 | if (!this.target.horAggregator.factor) {
401 | errors.factor = 'You must supply a numeric value for this aggregator';
402 | this.panel.isAggregatorValid = false;
403 | }
404 | else if (parseInt(this.target.horAggregator.factor) === 0 && this.target.currentHorizontalAggregatorName === 'div') {
405 | errors.factor = 'Cannot divide by 0';
406 | this.panel.isAggregatorValid = false;
407 | }
408 | }
409 |
410 | if (this.panel.hasPercentile) {
411 | if (!this.target.horAggregator.percentile ||
412 | this.target.horAggregator.percentile <= 0 ||
413 | this.target.horAggregator.percentile > 1) {
414 | errors.percentile = 'Percentile must be between 0 and 1';
415 | this.panel.isAggregatorValid = false;
416 | }
417 | }
418 |
419 | if (!_.isEmpty(errors)) {
420 | this.target.errors.horAggregator = errors;
421 | }
422 | };
423 |
424 | alert (message) {
425 | alert(message);
426 | };
427 |
428 | }
429 |
430 | ChronixDbQueryController.templateUrl = 'partials/query.editor.html';
431 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | abbrev@1:
6 | version "1.1.0"
7 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
8 |
9 | ansi-regex@^2.0.0:
10 | version "2.1.1"
11 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
12 |
13 | ansi-styles@^2.2.1:
14 | version "2.2.1"
15 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
16 |
17 | argparse@^1.0.2:
18 | version "1.0.9"
19 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
20 | dependencies:
21 | sprintf-js "~1.0.2"
22 |
23 | array-differ@^1.0.0:
24 | version "1.0.0"
25 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
26 |
27 | array-find-index@^1.0.1:
28 | version "1.0.2"
29 | resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
30 |
31 | array-union@^1.0.1:
32 | version "1.0.2"
33 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
34 | dependencies:
35 | array-uniq "^1.0.1"
36 |
37 | array-uniq@^1.0.1:
38 | version "1.0.3"
39 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
40 |
41 | arrify@^1.0.0:
42 | version "1.0.1"
43 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
44 |
45 | async@^1.5.0, async@^1.5.2, async@~1.5.2:
46 | version "1.5.2"
47 | resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
48 |
49 | babel-code-frame@^6.22.0:
50 | version "6.22.0"
51 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
52 | dependencies:
53 | chalk "^1.1.0"
54 | esutils "^2.0.2"
55 | js-tokens "^3.0.0"
56 |
57 | babel-core@^6.0.12, babel-core@^6.24.1, babel-core@^6.5.1:
58 | version "6.24.1"
59 | resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83"
60 | dependencies:
61 | babel-code-frame "^6.22.0"
62 | babel-generator "^6.24.1"
63 | babel-helpers "^6.24.1"
64 | babel-messages "^6.23.0"
65 | babel-register "^6.24.1"
66 | babel-runtime "^6.22.0"
67 | babel-template "^6.24.1"
68 | babel-traverse "^6.24.1"
69 | babel-types "^6.24.1"
70 | babylon "^6.11.0"
71 | convert-source-map "^1.1.0"
72 | debug "^2.1.1"
73 | json5 "^0.5.0"
74 | lodash "^4.2.0"
75 | minimatch "^3.0.2"
76 | path-is-absolute "^1.0.0"
77 | private "^0.1.6"
78 | slash "^1.0.0"
79 | source-map "^0.5.0"
80 |
81 | babel-generator@^6.24.1:
82 | version "6.24.1"
83 | resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497"
84 | dependencies:
85 | babel-messages "^6.23.0"
86 | babel-runtime "^6.22.0"
87 | babel-types "^6.24.1"
88 | detect-indent "^4.0.0"
89 | jsesc "^1.3.0"
90 | lodash "^4.2.0"
91 | source-map "^0.5.0"
92 | trim-right "^1.0.1"
93 |
94 | babel-helper-call-delegate@^6.24.1:
95 | version "6.24.1"
96 | resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
97 | dependencies:
98 | babel-helper-hoist-variables "^6.24.1"
99 | babel-runtime "^6.22.0"
100 | babel-traverse "^6.24.1"
101 | babel-types "^6.24.1"
102 |
103 | babel-helper-define-map@^6.24.1:
104 | version "6.24.1"
105 | resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080"
106 | dependencies:
107 | babel-helper-function-name "^6.24.1"
108 | babel-runtime "^6.22.0"
109 | babel-types "^6.24.1"
110 | lodash "^4.2.0"
111 |
112 | babel-helper-function-name@^6.24.1:
113 | version "6.24.1"
114 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
115 | dependencies:
116 | babel-helper-get-function-arity "^6.24.1"
117 | babel-runtime "^6.22.0"
118 | babel-template "^6.24.1"
119 | babel-traverse "^6.24.1"
120 | babel-types "^6.24.1"
121 |
122 | babel-helper-get-function-arity@^6.24.1:
123 | version "6.24.1"
124 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
125 | dependencies:
126 | babel-runtime "^6.22.0"
127 | babel-types "^6.24.1"
128 |
129 | babel-helper-hoist-variables@^6.24.1:
130 | version "6.24.1"
131 | resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76"
132 | dependencies:
133 | babel-runtime "^6.22.0"
134 | babel-types "^6.24.1"
135 |
136 | babel-helper-optimise-call-expression@^6.24.1:
137 | version "6.24.1"
138 | resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
139 | dependencies:
140 | babel-runtime "^6.22.0"
141 | babel-types "^6.24.1"
142 |
143 | babel-helper-regex@^6.24.1:
144 | version "6.24.1"
145 | resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8"
146 | dependencies:
147 | babel-runtime "^6.22.0"
148 | babel-types "^6.24.1"
149 | lodash "^4.2.0"
150 |
151 | babel-helper-replace-supers@^6.24.1:
152 | version "6.24.1"
153 | resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a"
154 | dependencies:
155 | babel-helper-optimise-call-expression "^6.24.1"
156 | babel-messages "^6.23.0"
157 | babel-runtime "^6.22.0"
158 | babel-template "^6.24.1"
159 | babel-traverse "^6.24.1"
160 | babel-types "^6.24.1"
161 |
162 | babel-helpers@^6.24.1:
163 | version "6.24.1"
164 | resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
165 | dependencies:
166 | babel-runtime "^6.22.0"
167 | babel-template "^6.24.1"
168 |
169 | babel-messages@^6.23.0:
170 | version "6.23.0"
171 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
172 | dependencies:
173 | babel-runtime "^6.22.0"
174 |
175 | babel-plugin-check-es2015-constants@^6.22.0:
176 | version "6.22.0"
177 | resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
178 | dependencies:
179 | babel-runtime "^6.22.0"
180 |
181 | babel-plugin-transform-es2015-arrow-functions@^6.22.0:
182 | version "6.22.0"
183 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
184 | dependencies:
185 | babel-runtime "^6.22.0"
186 |
187 | babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
188 | version "6.22.0"
189 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141"
190 | dependencies:
191 | babel-runtime "^6.22.0"
192 |
193 | babel-plugin-transform-es2015-block-scoping@^6.24.1:
194 | version "6.24.1"
195 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576"
196 | dependencies:
197 | babel-runtime "^6.22.0"
198 | babel-template "^6.24.1"
199 | babel-traverse "^6.24.1"
200 | babel-types "^6.24.1"
201 | lodash "^4.2.0"
202 |
203 | babel-plugin-transform-es2015-classes@^6.24.1:
204 | version "6.24.1"
205 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db"
206 | dependencies:
207 | babel-helper-define-map "^6.24.1"
208 | babel-helper-function-name "^6.24.1"
209 | babel-helper-optimise-call-expression "^6.24.1"
210 | babel-helper-replace-supers "^6.24.1"
211 | babel-messages "^6.23.0"
212 | babel-runtime "^6.22.0"
213 | babel-template "^6.24.1"
214 | babel-traverse "^6.24.1"
215 | babel-types "^6.24.1"
216 |
217 | babel-plugin-transform-es2015-computed-properties@^6.24.1:
218 | version "6.24.1"
219 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3"
220 | dependencies:
221 | babel-runtime "^6.22.0"
222 | babel-template "^6.24.1"
223 |
224 | babel-plugin-transform-es2015-destructuring@^6.22.0:
225 | version "6.23.0"
226 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
227 | dependencies:
228 | babel-runtime "^6.22.0"
229 |
230 | babel-plugin-transform-es2015-duplicate-keys@^6.24.1:
231 | version "6.24.1"
232 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e"
233 | dependencies:
234 | babel-runtime "^6.22.0"
235 | babel-types "^6.24.1"
236 |
237 | babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.8.0:
238 | version "6.23.0"
239 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
240 | dependencies:
241 | babel-runtime "^6.22.0"
242 |
243 | babel-plugin-transform-es2015-function-name@^6.24.1:
244 | version "6.24.1"
245 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b"
246 | dependencies:
247 | babel-helper-function-name "^6.24.1"
248 | babel-runtime "^6.22.0"
249 | babel-types "^6.24.1"
250 |
251 | babel-plugin-transform-es2015-literals@^6.22.0:
252 | version "6.22.0"
253 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e"
254 | dependencies:
255 | babel-runtime "^6.22.0"
256 |
257 | babel-plugin-transform-es2015-modules-amd@^6.24.1:
258 | version "6.24.1"
259 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154"
260 | dependencies:
261 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
262 | babel-runtime "^6.22.0"
263 | babel-template "^6.24.1"
264 |
265 | babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
266 | version "6.24.1"
267 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe"
268 | dependencies:
269 | babel-plugin-transform-strict-mode "^6.24.1"
270 | babel-runtime "^6.22.0"
271 | babel-template "^6.24.1"
272 | babel-types "^6.24.1"
273 |
274 | babel-plugin-transform-es2015-modules-systemjs@^6.14.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1:
275 | version "6.24.1"
276 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23"
277 | dependencies:
278 | babel-helper-hoist-variables "^6.24.1"
279 | babel-runtime "^6.22.0"
280 | babel-template "^6.24.1"
281 |
282 | babel-plugin-transform-es2015-modules-umd@^6.24.1:
283 | version "6.24.1"
284 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468"
285 | dependencies:
286 | babel-plugin-transform-es2015-modules-amd "^6.24.1"
287 | babel-runtime "^6.22.0"
288 | babel-template "^6.24.1"
289 |
290 | babel-plugin-transform-es2015-object-super@^6.24.1:
291 | version "6.24.1"
292 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d"
293 | dependencies:
294 | babel-helper-replace-supers "^6.24.1"
295 | babel-runtime "^6.22.0"
296 |
297 | babel-plugin-transform-es2015-parameters@^6.24.1:
298 | version "6.24.1"
299 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b"
300 | dependencies:
301 | babel-helper-call-delegate "^6.24.1"
302 | babel-helper-get-function-arity "^6.24.1"
303 | babel-runtime "^6.22.0"
304 | babel-template "^6.24.1"
305 | babel-traverse "^6.24.1"
306 | babel-types "^6.24.1"
307 |
308 | babel-plugin-transform-es2015-shorthand-properties@^6.24.1:
309 | version "6.24.1"
310 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0"
311 | dependencies:
312 | babel-runtime "^6.22.0"
313 | babel-types "^6.24.1"
314 |
315 | babel-plugin-transform-es2015-spread@^6.22.0:
316 | version "6.22.0"
317 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1"
318 | dependencies:
319 | babel-runtime "^6.22.0"
320 |
321 | babel-plugin-transform-es2015-sticky-regex@^6.24.1:
322 | version "6.24.1"
323 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc"
324 | dependencies:
325 | babel-helper-regex "^6.24.1"
326 | babel-runtime "^6.22.0"
327 | babel-types "^6.24.1"
328 |
329 | babel-plugin-transform-es2015-template-literals@^6.22.0:
330 | version "6.22.0"
331 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d"
332 | dependencies:
333 | babel-runtime "^6.22.0"
334 |
335 | babel-plugin-transform-es2015-typeof-symbol@^6.22.0:
336 | version "6.23.0"
337 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
338 | dependencies:
339 | babel-runtime "^6.22.0"
340 |
341 | babel-plugin-transform-es2015-unicode-regex@^6.24.1:
342 | version "6.24.1"
343 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9"
344 | dependencies:
345 | babel-helper-regex "^6.24.1"
346 | babel-runtime "^6.22.0"
347 | regexpu-core "^2.0.0"
348 |
349 | babel-plugin-transform-regenerator@^6.24.1:
350 | version "6.24.1"
351 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418"
352 | dependencies:
353 | regenerator-transform "0.9.11"
354 |
355 | babel-plugin-transform-strict-mode@^6.24.1:
356 | version "6.24.1"
357 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
358 | dependencies:
359 | babel-runtime "^6.22.0"
360 | babel-types "^6.24.1"
361 |
362 | babel-preset-es2015@^6.14.0:
363 | version "6.24.1"
364 | resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
365 | dependencies:
366 | babel-plugin-check-es2015-constants "^6.22.0"
367 | babel-plugin-transform-es2015-arrow-functions "^6.22.0"
368 | babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
369 | babel-plugin-transform-es2015-block-scoping "^6.24.1"
370 | babel-plugin-transform-es2015-classes "^6.24.1"
371 | babel-plugin-transform-es2015-computed-properties "^6.24.1"
372 | babel-plugin-transform-es2015-destructuring "^6.22.0"
373 | babel-plugin-transform-es2015-duplicate-keys "^6.24.1"
374 | babel-plugin-transform-es2015-for-of "^6.22.0"
375 | babel-plugin-transform-es2015-function-name "^6.24.1"
376 | babel-plugin-transform-es2015-literals "^6.22.0"
377 | babel-plugin-transform-es2015-modules-amd "^6.24.1"
378 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
379 | babel-plugin-transform-es2015-modules-systemjs "^6.24.1"
380 | babel-plugin-transform-es2015-modules-umd "^6.24.1"
381 | babel-plugin-transform-es2015-object-super "^6.24.1"
382 | babel-plugin-transform-es2015-parameters "^6.24.1"
383 | babel-plugin-transform-es2015-shorthand-properties "^6.24.1"
384 | babel-plugin-transform-es2015-spread "^6.22.0"
385 | babel-plugin-transform-es2015-sticky-regex "^6.24.1"
386 | babel-plugin-transform-es2015-template-literals "^6.22.0"
387 | babel-plugin-transform-es2015-typeof-symbol "^6.22.0"
388 | babel-plugin-transform-es2015-unicode-regex "^6.24.1"
389 | babel-plugin-transform-regenerator "^6.24.1"
390 |
391 | babel-register@^6.24.1:
392 | version "6.24.1"
393 | resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f"
394 | dependencies:
395 | babel-core "^6.24.1"
396 | babel-runtime "^6.22.0"
397 | core-js "^2.4.0"
398 | home-or-tmp "^2.0.0"
399 | lodash "^4.2.0"
400 | mkdirp "^0.5.1"
401 | source-map-support "^0.4.2"
402 |
403 | babel-runtime@^6.18.0, babel-runtime@^6.22.0:
404 | version "6.23.0"
405 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
406 | dependencies:
407 | core-js "^2.4.0"
408 | regenerator-runtime "^0.10.0"
409 |
410 | babel-template@^6.24.1:
411 | version "6.24.1"
412 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333"
413 | dependencies:
414 | babel-runtime "^6.22.0"
415 | babel-traverse "^6.24.1"
416 | babel-types "^6.24.1"
417 | babylon "^6.11.0"
418 | lodash "^4.2.0"
419 |
420 | babel-traverse@^6.24.1:
421 | version "6.24.1"
422 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695"
423 | dependencies:
424 | babel-code-frame "^6.22.0"
425 | babel-messages "^6.23.0"
426 | babel-runtime "^6.22.0"
427 | babel-types "^6.24.1"
428 | babylon "^6.15.0"
429 | debug "^2.2.0"
430 | globals "^9.0.0"
431 | invariant "^2.2.0"
432 | lodash "^4.2.0"
433 |
434 | babel-types@^6.19.0, babel-types@^6.24.1:
435 | version "6.24.1"
436 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975"
437 | dependencies:
438 | babel-runtime "^6.22.0"
439 | esutils "^2.0.2"
440 | lodash "^4.2.0"
441 | to-fast-properties "^1.0.1"
442 |
443 | babylon@^6.11.0, babylon@^6.15.0:
444 | version "6.17.1"
445 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.1.tgz#17f14fddf361b695981fe679385e4f1c01ebd86f"
446 |
447 | balanced-match@^0.4.1:
448 | version "0.4.2"
449 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
450 |
451 | body-parser@~1.14.0:
452 | version "1.14.2"
453 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9"
454 | dependencies:
455 | bytes "2.2.0"
456 | content-type "~1.0.1"
457 | debug "~2.2.0"
458 | depd "~1.1.0"
459 | http-errors "~1.3.1"
460 | iconv-lite "0.4.13"
461 | on-finished "~2.3.0"
462 | qs "5.2.0"
463 | raw-body "~2.1.5"
464 | type-is "~1.6.10"
465 |
466 | brace-expansion@^1.1.7:
467 | version "1.1.7"
468 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59"
469 | dependencies:
470 | balanced-match "^0.4.1"
471 | concat-map "0.0.1"
472 |
473 | builtin-modules@^1.0.0:
474 | version "1.1.1"
475 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
476 |
477 | bytes@2.2.0:
478 | version "2.2.0"
479 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588"
480 |
481 | bytes@2.4.0:
482 | version "2.4.0"
483 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339"
484 |
485 | camelcase-keys@^2.0.0:
486 | version "2.1.0"
487 | resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
488 | dependencies:
489 | camelcase "^2.0.0"
490 | map-obj "^1.0.0"
491 |
492 | camelcase@^2.0.0:
493 | version "2.1.1"
494 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
495 |
496 | chalk@^1.1.0, chalk@^1.1.1, chalk@~1.1.1:
497 | version "1.1.3"
498 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
499 | dependencies:
500 | ansi-styles "^2.2.1"
501 | escape-string-regexp "^1.0.2"
502 | has-ansi "^2.0.0"
503 | strip-ansi "^3.0.0"
504 | supports-color "^2.0.0"
505 |
506 | coffee-script@~1.10.0:
507 | version "1.10.0"
508 | resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0"
509 |
510 | colors@~1.1.2:
511 | version "1.1.2"
512 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
513 |
514 | concat-map@0.0.1:
515 | version "0.0.1"
516 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
517 |
518 | content-type@~1.0.1:
519 | version "1.0.2"
520 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
521 |
522 | convert-source-map@^1.1.0:
523 | version "1.5.0"
524 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
525 |
526 | core-js@^2.4.0:
527 | version "2.4.1"
528 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
529 |
530 | currently-unhandled@^0.4.1:
531 | version "0.4.1"
532 | resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
533 | dependencies:
534 | array-find-index "^1.0.1"
535 |
536 | dateformat@~1.0.12:
537 | version "1.0.12"
538 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
539 | dependencies:
540 | get-stdin "^4.0.1"
541 | meow "^3.3.0"
542 |
543 | debug@^2.1.1, debug@^2.2.0:
544 | version "2.6.8"
545 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
546 | dependencies:
547 | ms "2.0.0"
548 |
549 | debug@~2.2.0:
550 | version "2.2.0"
551 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
552 | dependencies:
553 | ms "0.7.1"
554 |
555 | decamelize@^1.1.2:
556 | version "1.2.0"
557 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
558 |
559 | depd@~1.1.0:
560 | version "1.1.0"
561 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
562 |
563 | detect-indent@^4.0.0:
564 | version "4.0.0"
565 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
566 | dependencies:
567 | repeating "^2.0.0"
568 |
569 | ee-first@1.1.1:
570 | version "1.1.1"
571 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
572 |
573 | error-ex@^1.2.0:
574 | version "1.3.1"
575 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
576 | dependencies:
577 | is-arrayish "^0.2.1"
578 |
579 | escape-string-regexp@^1.0.2:
580 | version "1.0.5"
581 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
582 |
583 | esprima@^2.6.0:
584 | version "2.7.3"
585 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
586 |
587 | esutils@^2.0.2:
588 | version "2.0.2"
589 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
590 |
591 | eventemitter2@~0.4.13:
592 | version "0.4.14"
593 | resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab"
594 |
595 | exit@~0.1.1:
596 | version "0.1.2"
597 | resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
598 |
599 | faye-websocket@~0.10.0:
600 | version "0.10.0"
601 | resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
602 | dependencies:
603 | websocket-driver ">=0.5.1"
604 |
605 | file-sync-cmp@^0.1.0:
606 | version "0.1.1"
607 | resolved "https://registry.yarnpkg.com/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz#a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b"
608 |
609 | find-up@^1.0.0:
610 | version "1.1.2"
611 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
612 | dependencies:
613 | path-exists "^2.0.0"
614 | pinkie-promise "^2.0.0"
615 |
616 | findup-sync@~0.3.0:
617 | version "0.3.0"
618 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16"
619 | dependencies:
620 | glob "~5.0.0"
621 |
622 | fs.realpath@^1.0.0:
623 | version "1.0.0"
624 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
625 |
626 | gaze@^1.0.0:
627 | version "1.1.2"
628 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105"
629 | dependencies:
630 | globule "^1.0.0"
631 |
632 | get-stdin@^4.0.1:
633 | version "4.0.1"
634 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
635 |
636 | getobject@~0.1.0:
637 | version "0.1.0"
638 | resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c"
639 |
640 | glob@^7.0.5, glob@~7.0.0:
641 | version "7.0.6"
642 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
643 | dependencies:
644 | fs.realpath "^1.0.0"
645 | inflight "^1.0.4"
646 | inherits "2"
647 | minimatch "^3.0.2"
648 | once "^1.3.0"
649 | path-is-absolute "^1.0.0"
650 |
651 | glob@~5.0.0:
652 | version "5.0.15"
653 | resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
654 | dependencies:
655 | inflight "^1.0.4"
656 | inherits "2"
657 | minimatch "2 || 3"
658 | once "^1.3.0"
659 | path-is-absolute "^1.0.0"
660 |
661 | glob@~7.1.1:
662 | version "7.1.2"
663 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
664 | dependencies:
665 | fs.realpath "^1.0.0"
666 | inflight "^1.0.4"
667 | inherits "2"
668 | minimatch "^3.0.4"
669 | once "^1.3.0"
670 | path-is-absolute "^1.0.0"
671 |
672 | globals@^9.0.0:
673 | version "9.17.0"
674 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286"
675 |
676 | globule@^1.0.0:
677 | version "1.1.0"
678 | resolved "https://registry.yarnpkg.com/globule/-/globule-1.1.0.tgz#c49352e4dc183d85893ee825385eb994bb6df45f"
679 | dependencies:
680 | glob "~7.1.1"
681 | lodash "~4.16.4"
682 | minimatch "~3.0.2"
683 |
684 | graceful-fs@^4.1.2:
685 | version "4.1.11"
686 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
687 |
688 | grunt-babel@^6.0.0:
689 | version "6.0.0"
690 | resolved "https://registry.yarnpkg.com/grunt-babel/-/grunt-babel-6.0.0.tgz#378189b487de1168c4c4a9fc88dd6005b35df960"
691 | dependencies:
692 | babel-core "^6.0.12"
693 |
694 | grunt-cli@^1.2.0, grunt-cli@~1.2.0:
695 | version "1.2.0"
696 | resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8"
697 | dependencies:
698 | findup-sync "~0.3.0"
699 | grunt-known-options "~1.1.0"
700 | nopt "~3.0.6"
701 | resolve "~1.1.0"
702 |
703 | grunt-contrib-clean@^1.0.0:
704 | version "1.1.0"
705 | resolved "https://registry.yarnpkg.com/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz#564abf2d0378a983a15b9e3f30ee75b738c40638"
706 | dependencies:
707 | async "^1.5.2"
708 | rimraf "^2.5.1"
709 |
710 | grunt-contrib-copy@^1.0.0:
711 | version "1.0.0"
712 | resolved "https://registry.yarnpkg.com/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz#7060c6581e904b8ab0d00f076e0a8f6e3e7c3573"
713 | dependencies:
714 | chalk "^1.1.1"
715 | file-sync-cmp "^0.1.0"
716 |
717 | grunt-contrib-watch@^1.0.0:
718 | version "1.0.0"
719 | resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz#84a1a7a1d6abd26ed568413496c73133e990018f"
720 | dependencies:
721 | async "^1.5.0"
722 | gaze "^1.0.0"
723 | lodash "^3.10.1"
724 | tiny-lr "^0.2.1"
725 |
726 | grunt-known-options@~1.1.0:
727 | version "1.1.0"
728 | resolved "https://registry.yarnpkg.com/grunt-known-options/-/grunt-known-options-1.1.0.tgz#a4274eeb32fa765da5a7a3b1712617ce3b144149"
729 |
730 | grunt-legacy-log-utils@~1.0.0:
731 | version "1.0.0"
732 | resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz#a7b8e2d0fb35b5a50f4af986fc112749ebc96f3d"
733 | dependencies:
734 | chalk "~1.1.1"
735 | lodash "~4.3.0"
736 |
737 | grunt-legacy-log@~1.0.0:
738 | version "1.0.0"
739 | resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz#fb86f1809847bc07dc47843f9ecd6cacb62df2d5"
740 | dependencies:
741 | colors "~1.1.2"
742 | grunt-legacy-log-utils "~1.0.0"
743 | hooker "~0.2.3"
744 | lodash "~3.10.1"
745 | underscore.string "~3.2.3"
746 |
747 | grunt-legacy-util@~1.0.0:
748 | version "1.0.0"
749 | resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz#386aa78dc6ed50986c2b18957265b1b48abb9b86"
750 | dependencies:
751 | async "~1.5.2"
752 | exit "~0.1.1"
753 | getobject "~0.1.0"
754 | hooker "~0.2.3"
755 | lodash "~4.3.0"
756 | underscore.string "~3.2.3"
757 | which "~1.2.1"
758 |
759 | grunt@^1.0.1:
760 | version "1.0.1"
761 | resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.1.tgz#e8778764e944b18f32bb0f10b9078475c9dfb56b"
762 | dependencies:
763 | coffee-script "~1.10.0"
764 | dateformat "~1.0.12"
765 | eventemitter2 "~0.4.13"
766 | exit "~0.1.1"
767 | findup-sync "~0.3.0"
768 | glob "~7.0.0"
769 | grunt-cli "~1.2.0"
770 | grunt-known-options "~1.1.0"
771 | grunt-legacy-log "~1.0.0"
772 | grunt-legacy-util "~1.0.0"
773 | iconv-lite "~0.4.13"
774 | js-yaml "~3.5.2"
775 | minimatch "~3.0.0"
776 | nopt "~3.0.6"
777 | path-is-absolute "~1.0.0"
778 | rimraf "~2.2.8"
779 |
780 | has-ansi@^2.0.0:
781 | version "2.0.0"
782 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
783 | dependencies:
784 | ansi-regex "^2.0.0"
785 |
786 | home-or-tmp@^2.0.0:
787 | version "2.0.0"
788 | resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
789 | dependencies:
790 | os-homedir "^1.0.0"
791 | os-tmpdir "^1.0.1"
792 |
793 | hooker@~0.2.3:
794 | version "0.2.3"
795 | resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959"
796 |
797 | hosted-git-info@^2.1.4:
798 | version "2.4.2"
799 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
800 |
801 | http-errors@~1.3.1:
802 | version "1.3.1"
803 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942"
804 | dependencies:
805 | inherits "~2.0.1"
806 | statuses "1"
807 |
808 | iconv-lite@0.4.13:
809 | version "0.4.13"
810 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
811 |
812 | iconv-lite@~0.4.13:
813 | version "0.4.17"
814 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.17.tgz#4fdaa3b38acbc2c031b045d0edcdfe1ecab18c8d"
815 |
816 | indent-string@^2.1.0:
817 | version "2.1.0"
818 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
819 | dependencies:
820 | repeating "^2.0.0"
821 |
822 | inflight@^1.0.4:
823 | version "1.0.6"
824 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
825 | dependencies:
826 | once "^1.3.0"
827 | wrappy "1"
828 |
829 | inherits@2, inherits@~2.0.1:
830 | version "2.0.3"
831 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
832 |
833 | invariant@^2.2.0:
834 | version "2.2.2"
835 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
836 | dependencies:
837 | loose-envify "^1.0.0"
838 |
839 | is-arrayish@^0.2.1:
840 | version "0.2.1"
841 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
842 |
843 | is-builtin-module@^1.0.0:
844 | version "1.0.0"
845 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
846 | dependencies:
847 | builtin-modules "^1.0.0"
848 |
849 | is-finite@^1.0.0:
850 | version "1.0.2"
851 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
852 | dependencies:
853 | number-is-nan "^1.0.0"
854 |
855 | is-utf8@^0.2.0:
856 | version "0.2.1"
857 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
858 |
859 | isexe@^2.0.0:
860 | version "2.0.0"
861 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
862 |
863 | js-tokens@^3.0.0:
864 | version "3.0.1"
865 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
866 |
867 | js-yaml@~3.5.2:
868 | version "3.5.5"
869 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.5.tgz#0377c38017cabc7322b0d1fbcd25a491641f2fbe"
870 | dependencies:
871 | argparse "^1.0.2"
872 | esprima "^2.6.0"
873 |
874 | jsesc@^1.3.0:
875 | version "1.3.0"
876 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
877 |
878 | jsesc@~0.5.0:
879 | version "0.5.0"
880 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
881 |
882 | json5@^0.5.0:
883 | version "0.5.1"
884 | resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
885 |
886 | livereload-js@^2.2.0:
887 | version "2.2.2"
888 | resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2"
889 |
890 | load-grunt-tasks@^3.5.2:
891 | version "3.5.2"
892 | resolved "https://registry.yarnpkg.com/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz#0728561180fd20ff8a6927505852fc58aaea0c88"
893 | dependencies:
894 | arrify "^1.0.0"
895 | multimatch "^2.0.0"
896 | pkg-up "^1.0.0"
897 | resolve-pkg "^0.1.0"
898 |
899 | load-json-file@^1.0.0:
900 | version "1.1.0"
901 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
902 | dependencies:
903 | graceful-fs "^4.1.2"
904 | parse-json "^2.2.0"
905 | pify "^2.0.0"
906 | pinkie-promise "^2.0.0"
907 | strip-bom "^2.0.0"
908 |
909 | lodash@^3.10.1, lodash@~3.10.1:
910 | version "3.10.1"
911 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
912 |
913 | lodash@^4.0.0, lodash@^4.2.0:
914 | version "4.17.4"
915 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
916 |
917 | lodash@~4.16.4:
918 | version "4.16.6"
919 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.6.tgz#d22c9ac660288f3843e16ba7d2b5d06cca27d777"
920 |
921 | lodash@~4.3.0:
922 | version "4.3.0"
923 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4"
924 |
925 | loose-envify@^1.0.0:
926 | version "1.3.1"
927 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
928 | dependencies:
929 | js-tokens "^3.0.0"
930 |
931 | loud-rejection@^1.0.0:
932 | version "1.6.0"
933 | resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
934 | dependencies:
935 | currently-unhandled "^0.4.1"
936 | signal-exit "^3.0.0"
937 |
938 | map-obj@^1.0.0, map-obj@^1.0.1:
939 | version "1.0.1"
940 | resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
941 |
942 | media-typer@0.3.0:
943 | version "0.3.0"
944 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
945 |
946 | meow@^3.3.0:
947 | version "3.7.0"
948 | resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
949 | dependencies:
950 | camelcase-keys "^2.0.0"
951 | decamelize "^1.1.2"
952 | loud-rejection "^1.0.0"
953 | map-obj "^1.0.1"
954 | minimist "^1.1.3"
955 | normalize-package-data "^2.3.4"
956 | object-assign "^4.0.1"
957 | read-pkg-up "^1.0.1"
958 | redent "^1.0.0"
959 | trim-newlines "^1.0.0"
960 |
961 | mime-db@~1.27.0:
962 | version "1.27.0"
963 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
964 |
965 | mime-types@~2.1.15:
966 | version "2.1.15"
967 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
968 | dependencies:
969 | mime-db "~1.27.0"
970 |
971 | "minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.0, minimatch@~3.0.2:
972 | version "3.0.4"
973 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
974 | dependencies:
975 | brace-expansion "^1.1.7"
976 |
977 | minimist@0.0.8:
978 | version "0.0.8"
979 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
980 |
981 | minimist@^1.1.3:
982 | version "1.2.0"
983 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
984 |
985 | mkdirp@^0.5.1:
986 | version "0.5.1"
987 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
988 | dependencies:
989 | minimist "0.0.8"
990 |
991 | ms@0.7.1:
992 | version "0.7.1"
993 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
994 |
995 | ms@2.0.0:
996 | version "2.0.0"
997 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
998 |
999 | multimatch@^2.0.0:
1000 | version "2.1.0"
1001 | resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
1002 | dependencies:
1003 | array-differ "^1.0.0"
1004 | array-union "^1.0.1"
1005 | arrify "^1.0.0"
1006 | minimatch "^3.0.0"
1007 |
1008 | nopt@~3.0.6:
1009 | version "3.0.6"
1010 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
1011 | dependencies:
1012 | abbrev "1"
1013 |
1014 | normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
1015 | version "2.3.8"
1016 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb"
1017 | dependencies:
1018 | hosted-git-info "^2.1.4"
1019 | is-builtin-module "^1.0.0"
1020 | semver "2 || 3 || 4 || 5"
1021 | validate-npm-package-license "^3.0.1"
1022 |
1023 | number-is-nan@^1.0.0:
1024 | version "1.0.1"
1025 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
1026 |
1027 | object-assign@^4.0.1:
1028 | version "4.1.1"
1029 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
1030 |
1031 | on-finished@~2.3.0:
1032 | version "2.3.0"
1033 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
1034 | dependencies:
1035 | ee-first "1.1.1"
1036 |
1037 | once@^1.3.0:
1038 | version "1.4.0"
1039 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
1040 | dependencies:
1041 | wrappy "1"
1042 |
1043 | os-homedir@^1.0.0:
1044 | version "1.0.2"
1045 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
1046 |
1047 | os-tmpdir@^1.0.1:
1048 | version "1.0.2"
1049 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
1050 |
1051 | parse-json@^2.2.0:
1052 | version "2.2.0"
1053 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
1054 | dependencies:
1055 | error-ex "^1.2.0"
1056 |
1057 | parseurl@~1.3.0:
1058 | version "1.3.1"
1059 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56"
1060 |
1061 | path-exists@^2.0.0:
1062 | version "2.1.0"
1063 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
1064 | dependencies:
1065 | pinkie-promise "^2.0.0"
1066 |
1067 | path-is-absolute@^1.0.0, path-is-absolute@~1.0.0:
1068 | version "1.0.1"
1069 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
1070 |
1071 | path-type@^1.0.0:
1072 | version "1.1.0"
1073 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
1074 | dependencies:
1075 | graceful-fs "^4.1.2"
1076 | pify "^2.0.0"
1077 | pinkie-promise "^2.0.0"
1078 |
1079 | pify@^2.0.0:
1080 | version "2.3.0"
1081 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
1082 |
1083 | pinkie-promise@^2.0.0:
1084 | version "2.0.1"
1085 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
1086 | dependencies:
1087 | pinkie "^2.0.0"
1088 |
1089 | pinkie@^2.0.0:
1090 | version "2.0.4"
1091 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
1092 |
1093 | pkg-up@^1.0.0:
1094 | version "1.0.0"
1095 | resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
1096 | dependencies:
1097 | find-up "^1.0.0"
1098 |
1099 | private@^0.1.6:
1100 | version "0.1.7"
1101 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
1102 |
1103 | qs@5.2.0:
1104 | version "5.2.0"
1105 | resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be"
1106 |
1107 | qs@~5.1.0:
1108 | version "5.1.0"
1109 | resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9"
1110 |
1111 | raw-body@~2.1.5:
1112 | version "2.1.7"
1113 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774"
1114 | dependencies:
1115 | bytes "2.4.0"
1116 | iconv-lite "0.4.13"
1117 | unpipe "1.0.0"
1118 |
1119 | read-pkg-up@^1.0.1:
1120 | version "1.0.1"
1121 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
1122 | dependencies:
1123 | find-up "^1.0.0"
1124 | read-pkg "^1.0.0"
1125 |
1126 | read-pkg@^1.0.0:
1127 | version "1.1.0"
1128 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
1129 | dependencies:
1130 | load-json-file "^1.0.0"
1131 | normalize-package-data "^2.3.2"
1132 | path-type "^1.0.0"
1133 |
1134 | redent@^1.0.0:
1135 | version "1.0.0"
1136 | resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
1137 | dependencies:
1138 | indent-string "^2.1.0"
1139 | strip-indent "^1.0.1"
1140 |
1141 | regenerate@^1.2.1:
1142 | version "1.3.2"
1143 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
1144 |
1145 | regenerator-runtime@^0.10.0:
1146 | version "0.10.5"
1147 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
1148 |
1149 | regenerator-transform@0.9.11:
1150 | version "0.9.11"
1151 | resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283"
1152 | dependencies:
1153 | babel-runtime "^6.18.0"
1154 | babel-types "^6.19.0"
1155 | private "^0.1.6"
1156 |
1157 | regexpu-core@^2.0.0:
1158 | version "2.0.0"
1159 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
1160 | dependencies:
1161 | regenerate "^1.2.1"
1162 | regjsgen "^0.2.0"
1163 | regjsparser "^0.1.4"
1164 |
1165 | regjsgen@^0.2.0:
1166 | version "0.2.0"
1167 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
1168 |
1169 | regjsparser@^0.1.4:
1170 | version "0.1.5"
1171 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
1172 | dependencies:
1173 | jsesc "~0.5.0"
1174 |
1175 | repeating@^2.0.0:
1176 | version "2.0.1"
1177 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
1178 | dependencies:
1179 | is-finite "^1.0.0"
1180 |
1181 | resolve-from@^2.0.0:
1182 | version "2.0.0"
1183 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
1184 |
1185 | resolve-pkg@^0.1.0:
1186 | version "0.1.0"
1187 | resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-0.1.0.tgz#02cc993410e2936962bd97166a1b077da9725531"
1188 | dependencies:
1189 | resolve-from "^2.0.0"
1190 |
1191 | resolve@~1.1.0:
1192 | version "1.1.7"
1193 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
1194 |
1195 | rimraf@^2.5.1:
1196 | version "2.6.1"
1197 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
1198 | dependencies:
1199 | glob "^7.0.5"
1200 |
1201 | rimraf@~2.2.8:
1202 | version "2.2.8"
1203 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
1204 |
1205 | "semver@2 || 3 || 4 || 5":
1206 | version "5.3.0"
1207 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
1208 |
1209 | signal-exit@^3.0.0:
1210 | version "3.0.2"
1211 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
1212 |
1213 | slash@^1.0.0:
1214 | version "1.0.0"
1215 | resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
1216 |
1217 | source-map-support@^0.4.2:
1218 | version "0.4.15"
1219 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
1220 | dependencies:
1221 | source-map "^0.5.6"
1222 |
1223 | source-map@^0.5.0, source-map@^0.5.6:
1224 | version "0.5.6"
1225 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
1226 |
1227 | spdx-correct@~1.0.0:
1228 | version "1.0.2"
1229 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
1230 | dependencies:
1231 | spdx-license-ids "^1.0.2"
1232 |
1233 | spdx-expression-parse@~1.0.0:
1234 | version "1.0.4"
1235 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
1236 |
1237 | spdx-license-ids@^1.0.2:
1238 | version "1.2.2"
1239 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
1240 |
1241 | sprintf-js@~1.0.2:
1242 | version "1.0.3"
1243 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
1244 |
1245 | statuses@1:
1246 | version "1.3.1"
1247 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
1248 |
1249 | strip-ansi@^3.0.0:
1250 | version "3.0.1"
1251 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
1252 | dependencies:
1253 | ansi-regex "^2.0.0"
1254 |
1255 | strip-bom@^2.0.0:
1256 | version "2.0.0"
1257 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
1258 | dependencies:
1259 | is-utf8 "^0.2.0"
1260 |
1261 | strip-indent@^1.0.1:
1262 | version "1.0.1"
1263 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
1264 | dependencies:
1265 | get-stdin "^4.0.1"
1266 |
1267 | supports-color@^2.0.0:
1268 | version "2.0.0"
1269 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
1270 |
1271 | tiny-lr@^0.2.1:
1272 | version "0.2.1"
1273 | resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d"
1274 | dependencies:
1275 | body-parser "~1.14.0"
1276 | debug "~2.2.0"
1277 | faye-websocket "~0.10.0"
1278 | livereload-js "^2.2.0"
1279 | parseurl "~1.3.0"
1280 | qs "~5.1.0"
1281 |
1282 | to-fast-properties@^1.0.1:
1283 | version "1.0.3"
1284 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
1285 |
1286 | trim-newlines@^1.0.0:
1287 | version "1.0.0"
1288 | resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
1289 |
1290 | trim-right@^1.0.1:
1291 | version "1.0.1"
1292 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
1293 |
1294 | type-is@~1.6.10:
1295 | version "1.6.15"
1296 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
1297 | dependencies:
1298 | media-typer "0.3.0"
1299 | mime-types "~2.1.15"
1300 |
1301 | underscore.string@~3.2.3:
1302 | version "3.2.3"
1303 | resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.2.3.tgz#806992633665d5e5fcb4db1fb3a862eb68e9e6da"
1304 |
1305 | unpipe@1.0.0:
1306 | version "1.0.0"
1307 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
1308 |
1309 | validate-npm-package-license@^3.0.1:
1310 | version "3.0.1"
1311 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
1312 | dependencies:
1313 | spdx-correct "~1.0.0"
1314 | spdx-expression-parse "~1.0.0"
1315 |
1316 | websocket-driver@>=0.5.1:
1317 | version "0.6.5"
1318 | resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
1319 | dependencies:
1320 | websocket-extensions ">=0.1.1"
1321 |
1322 | websocket-extensions@>=0.1.1:
1323 | version "0.1.1"
1324 | resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7"
1325 |
1326 | which@~1.2.1:
1327 | version "1.2.14"
1328 | resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
1329 | dependencies:
1330 | isexe "^2.0.0"
1331 |
1332 | wrappy@1:
1333 | version "1.0.2"
1334 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1335 |
--------------------------------------------------------------------------------