sabisu_rails 0.0.1.pre.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +109 -0
  6. data/Rakefile +1 -0
  7. data/app/assets/javascripts/sabisu_rails/application.js +12 -0
  8. data/app/assets/javascripts/sabisu_rails/sabisu.js.coffee +40 -0
  9. data/app/assets/stylesheets/sabisu_rails/application.css.scss +9 -0
  10. data/app/assets/stylesheets/sabisu_rails/explorer.css.scss +117 -0
  11. data/app/assets/stylesheets/sabisu_rails/furatto_overrides.scss +24 -0
  12. data/app/controllers/sabisu_rails/base_controller.rb +16 -0
  13. data/app/controllers/sabisu_rails/explorer_controller.rb +15 -0
  14. data/app/helpers/sabisu_rails/explorer_helper.rb +28 -0
  15. data/app/helpers/sabisu_rails_helper.rb +3 -0
  16. data/app/views/layouts/sabisu_rails.html.erb +28 -0
  17. data/app/views/sabisu_rails/explorer/index.html.erb +86 -0
  18. data/app/views/sabisu_rails/explorer/index.js.erb +6 -0
  19. data/config/routes.rb +3 -0
  20. data/lib/generators/sabisu_rails/install_generator.rb +17 -0
  21. data/lib/generators/sabisu_rails/templates/sabisu_rails.rb +34 -0
  22. data/lib/sabisu_rails/builders/base.rb +26 -0
  23. data/lib/sabisu_rails/builders/headers_builder.rb +6 -0
  24. data/lib/sabisu_rails/builders/url_params_builder.rb +6 -0
  25. data/lib/sabisu_rails/builders.rb +7 -0
  26. data/lib/sabisu_rails/engine.rb +5 -0
  27. data/lib/sabisu_rails/explorer.rb +35 -0
  28. data/lib/sabisu_rails/helpers/required.rb +14 -0
  29. data/lib/sabisu_rails/helpers.rb +5 -0
  30. data/lib/sabisu_rails/railtie.rb +22 -0
  31. data/lib/sabisu_rails/request.rb +28 -0
  32. data/lib/sabisu_rails/route_recognizer.rb +34 -0
  33. data/lib/sabisu_rails/version.rb +3 -0
  34. data/lib/sabisu_rails.rb +70 -0
  35. data/sabisu_rails.gemspec +30 -0
  36. data/vendor/assets/javascripts/sabisu_rails/KelpJSONView.js +120 -0
  37. data/vendor/assets/javascripts/sabisu_rails/pace.js +2 -0
  38. data/vendor/assets/stylesheets/sabisu_rails/KelpJSONView.css.scss +50 -0
  39. data/vendor/assets/stylesheets/sabisu_rails/pace.css +80 -0
  40. metadata +167 -0
@@ -0,0 +1,7 @@
1
+ module SabisuRails
2
+ module Builders
3
+ autoload :Base, 'sabisu_rails/builders/base'
4
+ autoload :UrlParamsBuilder, 'sabisu_rails/builders/url_params_builder'
5
+ autoload :HeadersBuilder, 'sabisu_rails/builders/headers_builder'
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module SabisuRails
2
+ class Engine < Rails::Engine
3
+ isolate_namespace SabisuRails
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ module SabisuRails
2
+ class Explorer
3
+
4
+ include SabisuRails::Helpers::Required
5
+
6
+ attr_reader :resource, :uri_pattern, :http_method
7
+
8
+ def initialize(attrs = {})
9
+ @resource = attrs[:resource] || SabisuRails.default_resource
10
+ @uri_pattern = attrs[:uri_pattern]
11
+ @http_method = attrs[:http_method].nil? ? "get" : attrs[:http_method].downcase
12
+ end
13
+
14
+ # Method to retrieve the resource class name, such as User, Product, etc
15
+ def resource_class
16
+ @resource_class ||= @resource.singularize.classify.constantize
17
+ end
18
+
19
+ def resource_name
20
+ @resource_name ||= @resource.singularize
21
+ end
22
+
23
+ def resource_columns
24
+ resource_class.columns
25
+ end
26
+
27
+ def resource_attributes
28
+ resource_columns.map(&:name) - SabisuRails.ignored_attributes
29
+ end
30
+
31
+ def method_missing(meth, *args, &block)
32
+ resource_class.new.send(meth, *args, &block)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module SabisuRails
2
+ module Helpers
3
+ module Required
4
+
5
+ def required_attribute?(attr)
6
+ required_attributes.include? attr.to_sym
7
+ end
8
+
9
+ def required_attributes
10
+ @required_attributes ||= resource_class.validators.map(&:attributes).flatten.uniq
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module SabisuRails
2
+ module Helpers
3
+ autoload :Required, 'sabisu_rails/helpers/required'
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails/railtie'
2
+
3
+ module SabisuRails
4
+ class Railtie < ::Rails::Railtie
5
+ config.eager_load_namespaces << SabisuRails
6
+
7
+ ActiveSupport.on_load :active_record do
8
+ if SabisuRails.resources.empty?
9
+ SabisuRails.resources = SabisuRails::RouteRecognizer.new.resources
10
+ SabisuRails.default_resource = SabisuRails.resources.first.to_s
11
+ end
12
+ SabisuRails.app_name = Rails.application.class.parent_name
13
+ end
14
+
15
+ config.after_initialize do
16
+ unless SabisuRails.configured?
17
+ warn '[Sabisu] Sabisu is not configured in the application and will use the default values.' +
18
+ ' We recommend you to check the file just created with the installer and setup it up.'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ module SabisuRails
2
+ class Request
3
+ include HTTParty
4
+
5
+ base_uri SabisuRails.base_api_uri
6
+ headers SabisuRails.api_headers
7
+
8
+ def initialize(explorer, body_params, params)
9
+ @explorer = explorer
10
+ @body_params = body_params || {}
11
+ @params = params || {}
12
+ @headers = SabisuRails::Builders::HeadersBuilder.new(@params[:headers]).build
13
+ @url_params = SabisuRails::Builders::UrlParamsBuilder.new(@params[:url_params]).build
14
+ end
15
+
16
+ def response
17
+ self.class.send(@explorer.http_method, "/#{@explorer.resource}/#{@explorer.uri_pattern}", body: resource_body_params, headers: @headers, query: @url_params)
18
+ end
19
+
20
+ def resource_body_params
21
+ body_params = {}
22
+
23
+ body_params[@explorer.resource_name] = @body_params.reject { |k, v| v.blank? }
24
+
25
+ body_params
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module SabisuRails
2
+ class RouteRecognizer
3
+ attr_reader :paths
4
+
5
+ # Based on @bantic solution - https://gist.github.com/bantic/5688232#file-rails_route_recognizer-rb
6
+ # To use this inside your app, call:
7
+ # `RouteRecognizer.new.initial_path_segments`
8
+ # This returns an array, e.g.: ['assets','blog','team','faq','users']
9
+
10
+ INITIAL_SEGMENT_REGEX = %r{^\/([^\/\(:]+)}
11
+ IGNORED_PATHS = ["assets", "rails", "sabisu_rails"]
12
+
13
+ def initialize
14
+ routes = Rails.application.routes.routes
15
+ @paths = routes.collect {|r| r.path.spec.to_s }
16
+ end
17
+
18
+ def initial_path_segments
19
+ @initial_path_segments ||= begin
20
+ paths.collect {|path| match_initial_path_segment(path)}.compact.uniq
21
+ end
22
+ end
23
+
24
+ def match_initial_path_segment(path)
25
+ if match = INITIAL_SEGMENT_REGEX.match(path)
26
+ match[1]
27
+ end
28
+ end
29
+
30
+ def resources
31
+ initial_path_segments - IGNORED_PATHS
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module SabisuRails
2
+ VERSION = "0.0.1-beta"
3
+ end
@@ -0,0 +1,70 @@
1
+ require 'httparty'
2
+
3
+ module SabisuRails
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :Request
7
+ autoload :RouteRecognizer
8
+ autoload :Explorer
9
+ autoload :Helpers
10
+ autoload :Builders
11
+
12
+ # We ignore some attribues that might cause a collision between models
13
+ @@default_ignored_attributes = %w{ created_at updated_at id }
14
+
15
+ # We append the extra attributes you want to ignore to the default ones
16
+ mattr_accessor :ignored_attributes
17
+ @@ignored_attributes = @@ignored_attributes.to_a + @@default_ignored_attributes
18
+
19
+ # Base api uri for the endpoints
20
+ mattr_accessor :base_api_uri
21
+ @@base_api_uri = nil
22
+
23
+ # HTTP methods for the api
24
+ @@default_http_methods = %w{ GET POST PUT DELETE PATCH }
25
+
26
+ mattr_accessor :http_methods
27
+ @@http_methods = @@http_methods.to_a + @@default_http_methods
28
+
29
+ # Headers to include on each request
30
+ mattr_accessor :api_headers
31
+ @@api_headers = {}
32
+
33
+ # Layout
34
+ mattr_accessor :layout
35
+ @@layout = "sabisu_rails"
36
+
37
+ # Resources
38
+ mattr_accessor :resources
39
+ @@resources = []
40
+
41
+ # Authentication
42
+ mattr_accessor :authentication_username
43
+ @@authentication_username = "admin"
44
+
45
+ mattr_accessor :authentication_password
46
+ @@authentication_password = "sekret"
47
+
48
+ mattr_accessor :app_name
49
+ @@app_name = 'Sabisu'
50
+
51
+ mattr_accessor :default_resource
52
+
53
+ @@configured = false
54
+
55
+ def self.configured? #:nodoc:
56
+ @@configured
57
+ end
58
+
59
+ #Method to configure sabisu
60
+ def self.setup
61
+ @@configured = true
62
+
63
+ yield self
64
+ end
65
+
66
+ end
67
+
68
+ require 'sabisu_rails/railtie'
69
+ require 'sabisu_rails/engine'
70
+ require 'sabisu_rails/version'
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sabisu_rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sabisu_rails"
8
+ spec.version = SabisuRails::VERSION.dup
9
+ spec.authors = ["Abraham Kuri"]
10
+ spec.email = ["kurenn@icalialabs.com"]
11
+ spec.summary = %q{Smart API Explorer}
12
+ spec.description = %q{A smart api explorer for a rails app}
13
+ spec.homepage = "https://github.com/IcaliaLabs/sabisu-rails"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split("\n")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.rubyforge_project = "sabisu_rails"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake", "~> 10.3"
25
+ spec.add_development_dependency "debugger", "~> 1.6"
26
+
27
+ spec.add_dependency "activemodel", '~> 4.0'
28
+ spec.add_dependency "actionpack", '~> 4.0'
29
+ spec.add_dependency "httparty", "~> 0.13"
30
+ end
@@ -0,0 +1,120 @@
1
+ /*
2
+ * Kelp JSONView – http://kelp.phate.org/2011/11/kelp-json-view-json-syntax-highlighting.html
3
+ * Modded by Bramus! - http://www.bram.us/
4
+ */
5
+ $.extend(jQuery,
6
+ {
7
+ JSONView: function (json, container) {
8
+ var ob = (typeof json == 'string') ? JSON.parse(json) : json,
9
+ p,
10
+ l = [],
11
+ c = container;
12
+
13
+ var repeat = function (s, n) {
14
+ return new Array(n + 1).join(s);
15
+ };
16
+
17
+ // Check whether a string is an URL – Added by Bramus!
18
+ var isUrl = function(s) {
19
+ var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
20
+ return regexp.test(s);
21
+ };
22
+
23
+ // Escape string for output – Added by Bramus!
24
+ var htmlEntities = function(str) {
25
+ return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
26
+ }
27
+
28
+ //²£¥Í JSON µ²ºc¸ê®Æªº»¼°j¨ç¼Æ
29
+ //o ¨Ó·½ª«¥ó
30
+ //isar ¸ê®Æ¬O true ªº¸Ü¥Nªí³o¤@¦¸»¼°j¬°°}¦C¸ê®Æ
31
+ //s »¼°j¶¥¼h¼Æ
32
+ var r = function (o, isar, s) {
33
+ for (var n in o) {
34
+ var p = o[n];
35
+ switch (typeof p) {
36
+ case 'function':
37
+ break;
38
+ case 'string':
39
+ p = isUrl(p) ? '<a href="' + p + '">' + p + '</a>' : htmlEntities(p);
40
+ if (isar)
41
+ l.push({ Text: '<span class="jsonstring">"' + p + '"</span><span class="jsontag">,</span>', Step: s });
42
+ else
43
+ l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonstring">"' + p + '"</span><span class="jsontag">,</span>', Step: s });
44
+ break;
45
+ case 'boolean':
46
+ if (isar)
47
+ l.push({ Text: '<span class="jsonboolean">"' + p + '"</span><span class="jsontag">,</span>', Step: s });
48
+ else
49
+ l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonboolean">' + p + '</span><span class="jsontag">,</span>', Step: s });
50
+ break;
51
+ case 'number':
52
+ if (isar)
53
+ l.push({ Text: '<span class="jsonnumber">' + p + '</span><span class="jsontag">,</span>', Step: s });
54
+ else
55
+ l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonnumber">' + p + '</span><span class="jsontag">,</span>', Step: s });
56
+ break;
57
+ case 'object':
58
+ if (p === null) {
59
+ if (isar)
60
+ l.push({ Text: '<span class="jsonnull">' + p + '</span><span class="jsontag">,</span>', Step: s });
61
+ else
62
+ l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonnull">' + p + '</span><span class="jsontag">,</span>', Step: s });
63
+ }
64
+ else if (p.length == undefined) {
65
+ //object
66
+ if (!isar) {
67
+ l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">:</span>', Step: s });
68
+ }
69
+ l.push({ Text: '<span class="jsontag">{</span>', Step: s });
70
+ r(p, false, s + 1);
71
+ l.push({ Text: '<span class="jsontag">},</span>', Step: s });
72
+ }
73
+ else {
74
+ //array
75
+ if (!isar) {
76
+ l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">:</span>', Step: s });
77
+ }
78
+ l.push({ Text: '<span class="jsontag">[</span>', Step: s });
79
+ r(p, true, s + 1);
80
+ l.push({ Text: '<span class="jsontag">],</span>', Step: s });
81
+ }
82
+ break;
83
+ default: break;
84
+ }
85
+ }
86
+ var last = l.pop();
87
+ var ct = ',</span>';
88
+ if (last.Text.substr(last.Text.length - ct.length) == ct)
89
+ l.push({ Text: last.Text.replace(ct, '</span>'), Step: last.Step });
90
+ else
91
+ l.push(last);
92
+ };
93
+
94
+ //±N JavaScript Object ®æ¦¡¤Æ¶ë¶i array ¤¤
95
+ if (ob.length == undefined) {
96
+ //object
97
+ l.push({ Text: '<span class="jsontag">{</span>', Step: 0 });
98
+ r(ob, false, 1);
99
+ l.push({ Text: '<span class="jsontag">}</span>', Step: 0 });
100
+ }
101
+ else {
102
+ //array
103
+ l.push({ Text: '<span class="jsontag">[</span>', Step: 0 });
104
+ r(ob, true, 1);
105
+ l.push({ Text: '<span class="jsontag">]</span>', Step: 0 });
106
+ }
107
+
108
+ // Build HTML String
109
+ var html = '<ol>';
110
+ for (var index in l) {
111
+ var jobject = l[index];
112
+ html += '<li>' + repeat(' &nbsp; &nbsp;', jobject.Step) + jobject.Text + '</li>';
113
+ }
114
+ html += '</ol>';
115
+
116
+ // Inject HTML String into container
117
+ c.addClass('KelpJSONView').html(html);
118
+
119
+ }
120
+ });
@@ -0,0 +1,2 @@
1
+ /*! pace 0.5.1 */
2
+ (function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W=[].slice,X={}.hasOwnProperty,Y=function(a,b){function c(){this.constructor=a}for(var d in b)X.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},Z=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};for(t={catchupTime:500,initialRate:.03,minTime:500,ghostTime:500,maxProgressPerFrame:10,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},B=function(){var a;return null!=(a="undefined"!=typeof performance&&null!==performance?"function"==typeof performance.now?performance.now():void 0:void 0)?a:+new Date},D=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,s=window.cancelAnimationFrame||window.mozCancelAnimationFrame,null==D&&(D=function(a){return setTimeout(a,50)},s=function(a){return clearTimeout(a)}),F=function(a){var b,c;return b=B(),(c=function(){var d;return d=B()-b,d>=33?(b=B(),a(d,function(){return D(c)})):setTimeout(c,33-d)})()},E=function(){var a,b,c;return c=arguments[0],b=arguments[1],a=3<=arguments.length?W.call(arguments,2):[],"function"==typeof c[b]?c[b].apply(c,a):c[b]},u=function(){var a,b,c,d,e,f,g;for(b=arguments[0],d=2<=arguments.length?W.call(arguments,1):[],f=0,g=d.length;g>f;f++)if(c=d[f])for(a in c)X.call(c,a)&&(e=c[a],null!=b[a]&&"object"==typeof b[a]&&null!=e&&"object"==typeof e?u(b[a],e):b[a]=e);return b},p=function(a){var b,c,d,e,f;for(c=b=0,e=0,f=a.length;f>e;e++)d=a[e],c+=Math.abs(d),b++;return c/b},w=function(a,b){var c,d,e;if(null==a&&(a="options"),null==b&&(b=!0),e=document.querySelector("[data-pace-"+a+"]")){if(c=e.getAttribute("data-pace-"+a),!b)return c;try{return JSON.parse(c)}catch(f){return d=f,"undefined"!=typeof console&&null!==console?console.error("Error parsing inline pace options",d):void 0}}},g=function(){function a(){}return a.prototype.on=function(a,b,c,d){var e;return null==d&&(d=!1),null==this.bindings&&(this.bindings={}),null==(e=this.bindings)[a]&&(e[a]=[]),this.bindings[a].push({handler:b,ctx:c,once:d})},a.prototype.once=function(a,b,c){return this.on(a,b,c,!0)},a.prototype.off=function(a,b){var c,d,e;if(null!=(null!=(d=this.bindings)?d[a]:void 0)){if(null==b)return delete this.bindings[a];for(c=0,e=[];c<this.bindings[a].length;)this.bindings[a][c].handler===b?e.push(this.bindings[a].splice(c,1)):e.push(c++);return e}},a.prototype.trigger=function(){var a,b,c,d,e,f,g,h,i;if(c=arguments[0],a=2<=arguments.length?W.call(arguments,1):[],null!=(g=this.bindings)?g[c]:void 0){for(e=0,i=[];e<this.bindings[c].length;)h=this.bindings[c][e],d=h.handler,b=h.ctx,f=h.once,d.apply(null!=b?b:this,a),f?i.push(this.bindings[c].splice(e,1)):i.push(e++);return i}},a}(),null==window.Pace&&(window.Pace={}),u(Pace,g.prototype),C=Pace.options=u({},t,window.paceOptions,w()),T=["ajax","document","eventLag","elements"],P=0,R=T.length;R>P;P++)J=T[P],C[J]===!0&&(C[J]=t[J]);i=function(a){function b(){return U=b.__super__.constructor.apply(this,arguments)}return Y(b,a),b}(Error),b=function(){function a(){this.progress=0}return a.prototype.getElement=function(){var a;if(null==this.el){if(a=document.querySelector(C.target),!a)throw new i;this.el=document.createElement("div"),this.el.className="pace pace-active",document.body.className=document.body.className.replace(/pace-done/g,""),document.body.className+=" pace-running",this.el.innerHTML='<div class="pace-progress">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>',null!=a.firstChild?a.insertBefore(this.el,a.firstChild):a.appendChild(this.el)}return this.el},a.prototype.finish=function(){var a;return a=this.getElement(),a.className=a.className.replace("pace-active",""),a.className+=" pace-inactive",document.body.className=document.body.className.replace("pace-running",""),document.body.className+=" pace-done"},a.prototype.update=function(a){return this.progress=a,this.render()},a.prototype.destroy=function(){try{this.getElement().parentNode.removeChild(this.getElement())}catch(a){i=a}return this.el=void 0},a.prototype.render=function(){var a,b;return null==document.querySelector(C.target)?!1:(a=this.getElement(),a.children[0].style.width=""+this.progress+"%",(!this.lastRenderedProgress||this.lastRenderedProgress|0!==this.progress|0)&&(a.children[0].setAttribute("data-progress-text",""+(0|this.progress)+"%"),this.progress>=100?b="99":(b=this.progress<10?"0":"",b+=0|this.progress),a.children[0].setAttribute("data-progress",""+b)),this.lastRenderedProgress=this.progress)},a.prototype.done=function(){return this.progress>=100},a}(),h=function(){function a(){this.bindings={}}return a.prototype.trigger=function(a,b){var c,d,e,f,g;if(null!=this.bindings[a]){for(f=this.bindings[a],g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.call(this,b));return g}},a.prototype.on=function(a,b){var c;return null==(c=this.bindings)[a]&&(c[a]=[]),this.bindings[a].push(b)},a}(),O=window.XMLHttpRequest,N=window.XDomainRequest,M=window.WebSocket,v=function(a,b){var c,d,e,f;f=[];for(d in b.prototype)try{e=b.prototype[d],null==a[d]&&"function"!=typeof e?f.push(a[d]=e):f.push(void 0)}catch(g){c=g}return f},z=[],Pace.ignore=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?W.call(arguments,1):[],z.unshift("ignore"),c=b.apply(null,a),z.shift(),c},Pace.track=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?W.call(arguments,1):[],z.unshift("track"),c=b.apply(null,a),z.shift(),c},I=function(a){var b;if(null==a&&(a="GET"),"track"===z[0])return"force";if(!z.length&&C.ajax){if("socket"===a&&C.ajax.trackWebSockets)return!0;if(b=a.toUpperCase(),Z.call(C.ajax.trackMethods,b)>=0)return!0}return!1},j=function(a){function b(){var a,c=this;b.__super__.constructor.apply(this,arguments),a=function(a){var b;return b=a.open,a.open=function(d,e){return I(d)&&c.trigger("request",{type:d,url:e,request:a}),b.apply(a,arguments)}},window.XMLHttpRequest=function(b){var c;return c=new O(b),a(c),c},v(window.XMLHttpRequest,O),null!=N&&(window.XDomainRequest=function(){var b;return b=new N,a(b),b},v(window.XDomainRequest,N)),null!=M&&C.ajax.trackWebSockets&&(window.WebSocket=function(a,b){var d;return d=null!=b?new M(a,b):new M(a),I("socket")&&c.trigger("request",{type:"socket",url:a,protocols:b,request:d}),d},v(window.WebSocket,M))}return Y(b,a),b}(h),Q=null,x=function(){return null==Q&&(Q=new j),Q},H=function(a){var b,c,d,e;for(e=C.ajax.ignoreURLs,c=0,d=e.length;d>c;c++)if(b=e[c],"string"==typeof b){if(-1!==a.indexOf(b))return!0}else if(b.test(a))return!0;return!1},x().on("request",function(b){var c,d,e,f,g;return f=b.type,e=b.request,g=b.url,H(g)?void 0:Pace.running||C.restartOnRequestAfter===!1&&"force"!==I(f)?void 0:(d=arguments,c=C.restartOnRequestAfter||0,"boolean"==typeof c&&(c=0),setTimeout(function(){var b,c,g,h,i,j;if(b="socket"===f?e.readyState<2:0<(h=e.readyState)&&4>h){for(Pace.restart(),i=Pace.sources,j=[],c=0,g=i.length;g>c;c++){if(J=i[c],J instanceof a){J.watch.apply(J,d);break}j.push(void 0)}return j}},c))}),a=function(){function a(){var a=this;this.elements=[],x().on("request",function(){return a.watch.apply(a,arguments)})}return a.prototype.watch=function(a){var b,c,d,e;return d=a.type,b=a.request,e=a.url,H(e)?void 0:(c="socket"===d?new m(b):new n(b),this.elements.push(c))},a}(),n=function(){function a(a){var b,c,d,e,f,g,h=this;if(this.progress=0,null!=window.ProgressEvent)for(c=null,a.addEventListener("progress",function(a){return h.progress=a.lengthComputable?100*a.loaded/a.total:h.progress+(100-h.progress)/2}),g=["load","abort","timeout","error"],d=0,e=g.length;e>d;d++)b=g[d],a.addEventListener(b,function(){return h.progress=100});else f=a.onreadystatechange,a.onreadystatechange=function(){var b;return 0===(b=a.readyState)||4===b?h.progress=100:3===a.readyState&&(h.progress=50),"function"==typeof f?f.apply(null,arguments):void 0}}return a}(),m=function(){function a(a){var b,c,d,e,f=this;for(this.progress=0,e=["error","open"],c=0,d=e.length;d>c;c++)b=e[c],a.addEventListener(b,function(){return f.progress=100})}return a}(),d=function(){function a(a){var b,c,d,f;for(null==a&&(a={}),this.elements=[],null==a.selectors&&(a.selectors=[]),f=a.selectors,c=0,d=f.length;d>c;c++)b=f[c],this.elements.push(new e(b))}return a}(),e=function(){function a(a){this.selector=a,this.progress=0,this.check()}return a.prototype.check=function(){var a=this;return document.querySelector(this.selector)?this.done():setTimeout(function(){return a.check()},C.elements.checkInterval)},a.prototype.done=function(){return this.progress=100},a}(),c=function(){function a(){var a,b,c=this;this.progress=null!=(b=this.states[document.readyState])?b:100,a=document.onreadystatechange,document.onreadystatechange=function(){return null!=c.states[document.readyState]&&(c.progress=c.states[document.readyState]),"function"==typeof a?a.apply(null,arguments):void 0}}return a.prototype.states={loading:0,interactive:50,complete:100},a}(),f=function(){function a(){var a,b,c,d,e,f=this;this.progress=0,a=0,e=[],d=0,c=B(),b=setInterval(function(){var g;return g=B()-c-50,c=B(),e.push(g),e.length>C.eventLag.sampleCount&&e.shift(),a=p(e),++d>=C.eventLag.minSamples&&a<C.eventLag.lagThreshold?(f.progress=100,clearInterval(b)):f.progress=100*(3/(a+3))},50)}return a}(),l=function(){function a(a){this.source=a,this.last=this.sinceLastUpdate=0,this.rate=C.initialRate,this.catchup=0,this.progress=this.lastProgress=0,null!=this.source&&(this.progress=E(this.source,"progress"))}return a.prototype.tick=function(a,b){var c;return null==b&&(b=E(this.source,"progress")),b>=100&&(this.done=!0),b===this.last?this.sinceLastUpdate+=a:(this.sinceLastUpdate&&(this.rate=(b-this.last)/this.sinceLastUpdate),this.catchup=(b-this.progress)/C.catchupTime,this.sinceLastUpdate=0,this.last=b),b>this.progress&&(this.progress+=this.catchup*a),c=1-Math.pow(this.progress/100,C.easeFactor),this.progress+=c*this.rate*a,this.progress=Math.min(this.lastProgress+C.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},a}(),K=null,G=null,q=null,L=null,o=null,r=null,Pace.running=!1,y=function(){return C.restartOnPushState?Pace.restart():void 0},null!=window.history.pushState&&(S=window.history.pushState,window.history.pushState=function(){return y(),S.apply(window.history,arguments)}),null!=window.history.replaceState&&(V=window.history.replaceState,window.history.replaceState=function(){return y(),V.apply(window.history,arguments)}),k={ajax:a,elements:d,document:c,eventLag:f},(A=function(){var a,c,d,e,f,g,h,i;for(Pace.sources=K=[],g=["ajax","elements","document","eventLag"],c=0,e=g.length;e>c;c++)a=g[c],C[a]!==!1&&K.push(new k[a](C[a]));for(i=null!=(h=C.extraSources)?h:[],d=0,f=i.length;f>d;d++)J=i[d],K.push(new J(C));return Pace.bar=q=new b,G=[],L=new l})(),Pace.stop=function(){return Pace.trigger("stop"),Pace.running=!1,q.destroy(),r=!0,null!=o&&("function"==typeof s&&s(o),o=null),A()},Pace.restart=function(){return Pace.trigger("restart"),Pace.stop(),Pace.start()},Pace.go=function(){var a;return Pace.running=!0,q.render(),a=B(),r=!1,o=F(function(b,c){var d,e,f,g,h,i,j,k,m,n,o,p,s,t,u,v;for(k=100-q.progress,e=o=0,f=!0,i=p=0,t=K.length;t>p;i=++p)for(J=K[i],n=null!=G[i]?G[i]:G[i]=[],h=null!=(v=J.elements)?v:[J],j=s=0,u=h.length;u>s;j=++s)g=h[j],m=null!=n[j]?n[j]:n[j]=new l(g),f&=m.done,m.done||(e++,o+=m.tick(b));return d=o/e,q.update(L.tick(b,d)),q.done()||f||r?(q.update(100),Pace.trigger("done"),setTimeout(function(){return q.finish(),Pace.running=!1,Pace.trigger("hide")},Math.max(C.ghostTime,Math.max(C.minTime-(B()-a),0)))):c()})},Pace.start=function(a){u(C,a),Pace.running=!0;try{q.render()}catch(b){i=b}return document.querySelector(".pace")?(Pace.trigger("start"),Pace.go()):setTimeout(Pace.start,50)},"function"==typeof define&&define.amd?define(function(){return Pace}):"object"==typeof exports?module.exports=Pace:C.startOnPageLoad&&Pace.start()}).call(this);
@@ -0,0 +1,50 @@
1
+ .KelpJSONView
2
+ {
3
+ font-family: monospace;
4
+ font-weight: 400;
5
+ font-style:normal;
6
+ font-size:14px;
7
+ background-color: #3F3F3F;
8
+ padding: 6px;
9
+ }
10
+ .KelpJSONView ol {
11
+ background: transparent;
12
+ margin: 0;
13
+ padding: 0;
14
+ color: gainsboro;
15
+ list-style-position: inside;
16
+ list-style: none;
17
+ }
18
+ .KelpJSONView ol li
19
+ {
20
+ white-space:nowrap;
21
+ margin-bottom: 0;
22
+ }
23
+ .jsonname
24
+ {
25
+ color: #ddddbe;
26
+ }
27
+ .jsonstring
28
+ {
29
+ color: #CC9393;
30
+ }
31
+
32
+ .jsonstring a {
33
+ color: #c79696;
34
+ }
35
+ .jsonnull
36
+ {
37
+ color: #FFF;
38
+ }
39
+ .jsonnumber
40
+ {
41
+ color: #8CD0D3;
42
+ }
43
+ .jsonboolean
44
+ {
45
+ color: #b64B72;
46
+ }
47
+ .jsontag
48
+ {
49
+ color: gainsboro;
50
+ }
@@ -0,0 +1,80 @@
1
+ .pace {
2
+ -webkit-pointer-events: none;
3
+ pointer-events: none;
4
+ -webkit-user-select: none;
5
+ -moz-user-select: none;
6
+ user-select: none;
7
+ }
8
+
9
+ .pace-inactive {
10
+ display: none;
11
+ }
12
+
13
+ .pace .pace-progress {
14
+ background: #ea5d5f;
15
+ position: fixed;
16
+ z-index: 2000;
17
+ top: 0;
18
+ left: 0;
19
+ height: 2px;
20
+
21
+ -webkit-transition: width 1s;
22
+ -moz-transition: width 1s;
23
+ -o-transition: width 1s;
24
+ transition: width 1s;
25
+ }
26
+
27
+ .pace .pace-progress-inner {
28
+ display: block;
29
+ position: absolute;
30
+ right: 0px;
31
+ width: 100px;
32
+ height: 100%;
33
+ box-shadow: 0 0 10px #ea5d5f, 0 0 5px #ea5d5f;
34
+ opacity: 1.0;
35
+ -webkit-transform: rotate(3deg) translate(0px, -4px);
36
+ -moz-transform: rotate(3deg) translate(0px, -4px);
37
+ -ms-transform: rotate(3deg) translate(0px, -4px);
38
+ -o-transform: rotate(3deg) translate(0px, -4px);
39
+ transform: rotate(3deg) translate(0px, -4px);
40
+ }
41
+
42
+ .pace .pace-activity {
43
+ display: block;
44
+ position: fixed;
45
+ z-index: 2000;
46
+ top: 15px;
47
+ right: 15px;
48
+ width: 14px;
49
+ height: 14px;
50
+ border: solid 2px transparent;
51
+ border-top-color: #ea5d5f;
52
+ border-left-color: #ea5d5f;
53
+ border-radius: 10px;
54
+ -webkit-animation: pace-spinner 400ms linear infinite;
55
+ -moz-animation: pace-spinner 400ms linear infinite;
56
+ -ms-animation: pace-spinner 400ms linear infinite;
57
+ -o-animation: pace-spinner 400ms linear infinite;
58
+ animation: pace-spinner 400ms linear infinite;
59
+ }
60
+
61
+ @-webkit-keyframes pace-spinner {
62
+ 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
63
+ 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
64
+ }
65
+ @-moz-keyframes pace-spinner {
66
+ 0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
67
+ 100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
68
+ }
69
+ @-o-keyframes pace-spinner {
70
+ 0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
71
+ 100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
72
+ }
73
+ @-ms-keyframes pace-spinner {
74
+ 0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
75
+ 100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
76
+ }
77
+ @keyframes pace-spinner {
78
+ 0% { transform: rotate(0deg); transform: rotate(0deg); }
79
+ 100% { transform: rotate(360deg); transform: rotate(360deg); }
80
+ }