rails_mini_profiler 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -10
  3. data/app/assets/javascripts/rails_mini_profiler.js +1 -78
  4. data/app/assets/stylesheets/rails_mini_profiler/application.css +1 -171
  5. data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +10 -1
  6. data/app/helpers/rails_mini_profiler/application_helper.rb +9 -0
  7. data/app/{assets/images/rails_mini_profiler → javascript/images}/bookmark.svg +0 -0
  8. data/app/{assets/images/rails_mini_profiler → javascript/images}/chart.svg +0 -0
  9. data/app/{assets/images/rails_mini_profiler → javascript/images}/delete.svg +0 -0
  10. data/app/{assets/images/rails_mini_profiler → javascript/images}/graph.svg +0 -0
  11. data/app/{assets/images/rails_mini_profiler → javascript/images}/logo.svg +0 -0
  12. data/app/{assets/images/rails_mini_profiler → javascript/images}/logo_variant.svg +0 -0
  13. data/app/{assets/images/rails_mini_profiler → javascript/images}/search.svg +0 -0
  14. data/app/{assets/images/rails_mini_profiler → javascript/images}/setting.svg +0 -0
  15. data/app/{assets/images/rails_mini_profiler → javascript/images}/show.svg +0 -0
  16. data/app/javascript/packs/rails-mini-profiler.js +80 -0
  17. data/app/javascript/stylesheets/flamegraph.scss +9 -0
  18. data/app/{assets/stylesheets/rails_mini_profiler/flashes.css → javascript/stylesheets/flashes.scss} +0 -0
  19. data/app/{assets/stylesheets/rails_mini_profiler/navbar.css → javascript/stylesheets/navbar.scss} +2 -2
  20. data/app/{assets/stylesheets/rails_mini_profiler/profiled_requests.css → javascript/stylesheets/profiled_requests.scss} +1 -7
  21. data/app/javascript/stylesheets/rails-mini-profiler.scss +175 -0
  22. data/app/{assets/stylesheets/rails_mini_profiler/traces.css → javascript/stylesheets/traces.scss} +0 -5
  23. data/app/models/rails_mini_profiler/application_record.rb +1 -1
  24. data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +2 -2
  25. data/app/views/layouts/rails_mini_profiler/application.html.erb +1 -8
  26. data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +1 -8
  27. data/app/views/rails_mini_profiler/badge.html.erb +1 -1
  28. data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +3 -3
  29. data/app/views/rails_mini_profiler/shared/_head.erb +13 -0
  30. data/app/views/rails_mini_profiler/shared/_navbar.html.erb +1 -1
  31. data/lib/generators/rails_mini_profiler/install_generator.rb +18 -0
  32. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +13 -0
  33. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +18 -7
  34. data/lib/rails_mini_profiler.rb +29 -3
  35. data/lib/rails_mini_profiler/badge.rb +21 -1
  36. data/lib/rails_mini_profiler/configuration.rb +24 -0
  37. data/lib/rails_mini_profiler/engine.rb +8 -1
  38. data/lib/rails_mini_profiler/guard.rb +18 -7
  39. data/lib/rails_mini_profiler/logger.rb +5 -0
  40. data/lib/rails_mini_profiler/models/base_model.rb +5 -0
  41. data/lib/rails_mini_profiler/models/trace.rb +28 -0
  42. data/lib/rails_mini_profiler/redirect.rb +8 -0
  43. data/lib/rails_mini_profiler/request_context.rb +24 -5
  44. data/lib/rails_mini_profiler/storage.rb +18 -0
  45. data/lib/rails_mini_profiler/tracers.rb +1 -1
  46. data/lib/rails_mini_profiler/version.rb +4 -1
  47. data/vendor/assets/images/bookmark.svg +10 -0
  48. data/vendor/assets/images/chart.svg +12 -0
  49. data/vendor/assets/images/delete.svg +9 -0
  50. data/vendor/assets/images/graph.svg +11 -0
  51. data/vendor/assets/images/logo.svg +18 -0
  52. data/vendor/assets/images/logo_variant.svg +32 -0
  53. data/vendor/assets/images/search.svg +10 -0
  54. data/vendor/assets/images/setting.svg +10 -0
  55. data/vendor/assets/images/show.svg +11 -0
  56. data/vendor/assets/javascripts/rails-mini-profiler.css +1 -0
  57. data/vendor/assets/javascripts/rails-mini-profiler.js +1 -0
  58. metadata +31 -21
  59. data/app/assets/fonts/rails_mini_profiler/LICENSE.txt +0 -202
  60. data/app/assets/fonts/rails_mini_profiler/OpenSans-Bold.ttf +0 -0
  61. data/app/assets/fonts/rails_mini_profiler/OpenSans-Regular.ttf +0 -0
  62. data/app/assets/fonts/rails_mini_profiler/OpenSans-SemiBold.ttf +0 -0
  63. data/app/assets/stylesheets/rails_mini_profiler/flamegraph.css +0 -14
  64. data/lib/rails_mini_profiler/errors.rb +0 -8
@@ -1,16 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../../app/helpers/rails_mini_profiler/application_helper'
4
+
3
5
  module RailsMiniProfiler
6
+ # Wraps functionality to render an interactive badge on top of HTML responses
7
+ #
8
+ # @api private
4
9
  class Badge
5
10
  include InlineSvg::ActionView::Helpers
11
+ include RailsMiniProfiler::ApplicationHelper
6
12
  include Engine.routes.url_helpers
7
13
 
14
+ # @param request_context [RequestContext] The current request context
15
+ # @param configuration [Configuration] The current configuration
8
16
  def initialize(request_context, configuration: RailsMiniProfiler.configuration)
9
17
  @configuration = configuration
10
18
  @profiled_request = request_context.profiled_request
11
19
  @original_response = request_context.response
12
20
  end
13
21
 
22
+ # Inject the badge into the response
23
+ #
24
+ # @return [ResponseWrapper] The modified response
14
25
  def render
15
26
  content_type = @original_response.headers['Content-Type']
16
27
  return @original_response unless content_type =~ %r{text/html}
@@ -29,6 +40,9 @@ module RailsMiniProfiler
29
40
 
30
41
  private
31
42
 
43
+ # Modify the body of the original response
44
+ #
45
+ # @return String The modified body
32
46
  def modified_body
33
47
  body = @original_response.response.body
34
48
  index = body.rindex(%r{</body>}i) || body.rindex(%r{</html>}i)
@@ -39,6 +53,9 @@ module RailsMiniProfiler
39
53
  end
40
54
  end
41
55
 
56
+ # Render the badge template
57
+ #
58
+ # @return String The badge HTML content to be injected
42
59
  def badge_content
43
60
  html = IO.read(File.expand_path('../../app/views/rails_mini_profiler/badge.html.erb', __dir__))
44
61
  @position = css_position
@@ -46,8 +63,11 @@ module RailsMiniProfiler
46
63
  template.result(binding)
47
64
  end
48
65
 
66
+ # Transform the configuration position into CSS style positions
67
+ #
68
+ # @return String The badge position as CSS style
49
69
  def css_position
50
- case RailsMiniProfiler.configuration.badge_position
70
+ case @configuration.badge_position
51
71
  when 'top-right'
52
72
  'top: 5px; right: 5px;'
53
73
  when 'bottom-left'
@@ -1,6 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # The main Rails Mini Profiler configuration object
5
+ #
6
+ # @!attribute [r] logger
7
+ # @return [Logger] the current logger
8
+ # @!attribute enabled
9
+ # @return [Boolean] if the profiler is enabled
10
+ # @!attribute badge_position
11
+ # @see Badge
12
+ # @return [String] the position of the interactive HTML badge.
13
+ # @!attribute flamegraph_enabled
14
+ # @return [Boolean] if Flamegraph recording is enabled
15
+ # @!attribute flamegraph_sample_rate
16
+ # @return [Float] the sample rate in samples per millisecond
17
+ # @!attribute skip_paths
18
+ # @return [Array<String>] a list of regex patterns for paths to skip
19
+ # @!attribute storage
20
+ # @return [Storage] the storage configuration
21
+ # @!attribute user_provider
22
+ # @return [Proc] a proc to identify a user based on a rack env
4
23
  class Configuration
5
24
  attr_reader :logger
6
25
 
@@ -18,6 +37,7 @@ module RailsMiniProfiler
18
37
  kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
19
38
  end
20
39
 
40
+ # Reset the configuration to default values
21
41
  def reset
22
42
  @enabled = proc { |_env| Rails.env.development? || Rails.env.test? }
23
43
  @badge_enabled = true
@@ -30,6 +50,10 @@ module RailsMiniProfiler
30
50
  @user_provider = proc { |env| Rack::Request.new(env).ip }
31
51
  end
32
52
 
53
+ # Set the logger
54
+ #
55
+ # @param logger [Logger]
56
+ # The logger to be used. If set to nil, the Rails default logger is used and the log level set to fatal
33
57
  def logger=(logger)
34
58
  if logger.nil?
35
59
  @logger.level = Logger::FATAL
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # The Rails Mini Profiler engine
5
+ #
6
+ # Injects a a custom [Middleware] into an existing Rails app to record request profiling information.
4
7
  class Engine < ::Rails::Engine
5
8
  isolate_namespace RailsMiniProfiler
6
9
 
@@ -9,7 +12,11 @@ module RailsMiniProfiler
9
12
  end
10
13
 
11
14
  initializer 'rails_mini_profiler.assets.precompile', group: :all do |app|
12
- app.config.assets.precompile += %w[rails_mini_profiler.js rails_mini_profiler/application.css]
15
+ app.config.assets.precompile += %w[
16
+ rails_mini_profiler.js
17
+ rails_mini_profiler/application.css
18
+ vendor/assets/images
19
+ ]
13
20
  end
14
21
 
15
22
  config.generators do |g|
@@ -1,13 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # Encapsulates guard conditions on whether or not to run certain parts of the profiler.
4
5
  class Guard
6
+ # @param request_context [RequestContext] the current request context
7
+ # @param configuration [Configuration] the current configuration
5
8
  def initialize(request_context, configuration: RailsMiniProfiler.configuration)
6
9
  @request_context = request_context
7
10
  @request = request_context.request
8
11
  @configuration = configuration
9
12
  end
10
13
 
14
+ # Whether or not to profile
15
+ #
16
+ # Profiling is disabled the profiler has been flat out disabled in the configuration or if the current request path
17
+ # matches on of the ignored paths.
18
+ #
19
+ # @return [Boolean] false if no profiling should be done
11
20
  def profile?
12
21
  return false unless enabled?
13
22
 
@@ -16,26 +25,28 @@ module RailsMiniProfiler
16
25
  true
17
26
  end
18
27
 
19
- def store?
20
- return false unless @request_context.user
21
-
22
- true
23
- end
24
-
25
28
  private
26
29
 
30
+ # Is the path of the current request an ignored one?
31
+ #
32
+ # @return [Boolean] true if the path is ignored. Per default, paths going to the engine itself are ignored, as are
33
+ # asset requests, and the paths the user has configured.
27
34
  def ignored_path?
28
35
  return true if /#{Engine.routes.find_script_name({})}/.match?(@request.path)
29
36
 
30
37
  return true if /assets/.match?(@request.path)
31
38
 
32
39
  ignored_paths = @configuration.skip_paths
33
-
34
40
  return true if Regexp.union(ignored_paths).match?(@request.path)
35
41
 
36
42
  false
37
43
  end
38
44
 
45
+ # Is the profiler enabled?
46
+ #
47
+ # Takes into account the current request env to decide if the profiler is enabled.
48
+ #
49
+ # @return [Boolean] false if the profiler is disabled
39
50
  def enabled?
40
51
  enabled = @configuration.enabled
41
52
  return enabled unless enabled.respond_to?(:call)
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # Construct a new custom logger to log from within the engine
4
5
  module Logger
6
+ # Extends a logger with additional formatting
7
+ #
8
+ # @return [Logger] a customized logger
5
9
  def self.new(logger)
6
10
  logger = logger.dup
7
11
 
@@ -11,6 +15,7 @@ module RailsMiniProfiler
11
15
  logger.extend(self)
12
16
  end
13
17
 
18
+ # Custom formatter to add a RailsMiniProfiler tag to log messages
14
19
  module Formatter
15
20
  def call(severity, timestamp, progname, msg)
16
21
  super(severity, timestamp, progname, "[RailsMiniProfiler] #{msg}")
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # Thin wrappers around request/response classes
5
+ #
6
+ # @api private
4
7
  module Models
8
+ # A pseudo model to be used to wrap profiling information. We can't use regular models, as their connecting
9
+ # to the database results in problems when profiling.
5
10
  class BaseModel
6
11
  include ActiveModel::Model
7
12
 
@@ -2,6 +2,34 @@
2
2
 
3
3
  module RailsMiniProfiler
4
4
  module Models
5
+ # A simplified representation of a trace.
6
+ #
7
+ # Is transformed into [RailsMiniProfiler::Trace] when recording has finished.
8
+ #
9
+ # @see https://guides.rubyonrails.org/active_support_instrumentation.html
10
+ #
11
+ # @!attribute id
12
+ # @return [Integer] the trace ID
13
+ # @!attribute name
14
+ # @return [Integer] the trace type.
15
+ # @!attribute start
16
+ # @return [Integer] the trace start as microsecond timestamp
17
+ # @!attribute finish
18
+ # @return [Integer] the trace finish as microsecond timestamp
19
+ # @!attribute duration
20
+ # @return [Integer] the trace duration
21
+ # @!attribute payload
22
+ # @return [Hash] a subset of trace data
23
+ # @!attribute backtrace
24
+ # @return [String] the line where this trace was recorded
25
+ # @!attribute allocations
26
+ # @return [Integer] the number of alloactions
27
+ # @!attribute created_at
28
+ # @return [DateTime] the creation date
29
+ # @!attribute updated_at
30
+ # @return [DateTime] the last updated date
31
+ #
32
+ # @api private
5
33
  class Trace < BaseModel
6
34
  attr_accessor :id, :name, :start, :finish, :duration, :payload, :backtrace, :allocations, :created_at, :updated_at
7
35
  end
@@ -1,14 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # Renders a redirect response if the user should be redirected from the original request
4
5
  class Redirect
5
6
  include Engine.routes.url_helpers
6
7
 
8
+ # @param request_context [RequestContext] the current request context
7
9
  def initialize(request_context)
8
10
  @request = request_context.request
9
11
  @profiled_request = request_context.profiled_request
10
12
  end
11
13
 
14
+ # Renders a redirect to a specific resource under certain conditions
15
+ #
16
+ # When the user requests a Flamegraph using a parameter for a specific request, they are being served a redirect.
17
+ #
18
+ # @return [Boolean] false if no redirect happens
19
+ # @return [Array] response with status 302 and the new location to redirect to
12
20
  def render
13
21
  params = CGI.parse(@request.query_string).transform_values(&:first).with_indifferent_access
14
22
  return redirect_to(flamegraph_path(@profiled_request.id)) if params[:rmp_flamegraph]
@@ -1,11 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # A working context for the duration of a request, as it runs through Rails Mini Profiler's middleware
5
+ #
6
+ # Contains all information that is being gathered while profiling is active. At the end of the request processing,
7
+ # the request context is converted into a models which are then stored in the host apps database.
8
+ #
9
+ # @!attribute [r] request
10
+ # @return [RequestWrapper] the request as sent to the application
11
+ # @!attribute response
12
+ # @return [ResponseWrapper] the response as rendered by the application
13
+ # @!attribute profiled_request
14
+ # @return [ProfiledRequest] the profiling data as gathered during profiling
15
+ # @!attribute traces
16
+ # @return [Array<Models::Trace>] trace wrappers gathered during profiling
17
+ # @!attribute flamegraph
18
+ # @return [Flamegraph] a Flamegraph, if recorded
4
19
  class RequestContext
5
20
  attr_reader :request
6
21
 
7
22
  attr_accessor :response, :profiled_request, :traces, :flamegraph
8
23
 
24
+ # @param request [RequestWrapper] the request as sent to the application
9
25
  def initialize(request)
10
26
  @request = request
11
27
  @env = request.env
@@ -13,16 +29,16 @@ module RailsMiniProfiler
13
29
  @complete = false
14
30
  end
15
31
 
16
- def user_id
17
- @user_id ||= User.current_user
18
- end
19
-
32
+ # If a user is currently authorized
33
+ #
34
+ # @return [Boolean] true if the user is authorized
20
35
  def authorized?
21
36
  @authorized ||= User.get(@env).present?
22
37
  end
23
38
 
39
+ # Completes profiling, setting all data and preparing for saving it.
24
40
  def complete_profiling!
25
- profiled_request.user_id = user_id
41
+ profiled_request.user_id = User.current_user
26
42
  profiled_request.request = @request
27
43
  profiled_request.response = @response
28
44
  total_time = traces.find { |trace| trace.name == 'rails_mini_profiler.total_time' }
@@ -30,6 +46,9 @@ module RailsMiniProfiler
30
46
  @complete = true
31
47
  end
32
48
 
49
+ # Save profiling data in the database.
50
+ #
51
+ # This will store the profiled request, as well as any attached traces and Flamgraph.
33
52
  def save_results!
34
53
  ActiveRecord::Base.transaction do
35
54
  profiled_request.flamegraph = RailsMiniProfiler::Flamegraph.new(data: flamegraph) if flamegraph.present?
@@ -1,14 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
+ # Configure how profiling data is stored within your Rails app.
5
+ #
6
+ # @!attribute database
7
+ # @return [Symbol] which database to connect to
8
+ # @!attribute profiled_requests_table
9
+ # @return [Symbol] where to store profiled requests
10
+ # @!attribute traces_table
11
+ # @return [Symbol] where to store traces
12
+ # @!attribute flamegraphs_table
13
+ # @return [Symbol] where to store flamegraphs
4
14
  class Storage
5
15
  class << self
16
+ # Construct a new configuration instance
17
+ #
18
+ # @return [Storage] a new storage configuration
6
19
  def configuration
7
20
  @configuration ||= new
8
21
  end
9
22
 
23
+ # Configure how profiling data is stored
24
+ #
25
+ # @yieldreturn [Storage] a new storage configuration object
10
26
  def configure
11
27
  yield(configuration)
28
+ configuration
12
29
  end
13
30
  end
14
31
 
@@ -19,6 +36,7 @@ module RailsMiniProfiler
19
36
  kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
20
37
  end
21
38
 
39
+ # Reset the configuration to default values
22
40
  def defaults!
23
41
  @database = nil
24
42
  @profiled_requests_table = 'rmp_profiled_requests'
@@ -60,7 +60,7 @@ module RailsMiniProfiler
60
60
  typecasted_binds = payload[:type_casted_binds]
61
61
  # Sometimes, typecasted binds are a proc. Not sure why. In those instances, we extract the typecasted
62
62
  # values from the proc by executing call.
63
- typecasted_binds = typecasted_binds.respond_to?(:call) ? typecasted_binds.call : typecasted_binds
63
+ typecasted_binds = typecasted_binds.call if typecasted_binds.respond_to?(:call)
64
64
  payload[:binds] = transform_binds(payload[:binds], typecasted_binds)
65
65
  payload.delete(:type_casted_binds)
66
66
  payload.reject { |_k, v| v.blank? }
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsMiniProfiler
4
- VERSION = '0.1.2'
4
+ # This needs to be double quoted for release-please
5
+ #
6
+ # See https://github.com/googleapis/release-please/issues/1018
7
+ VERSION = "0.3.0" # rubocop:disable Style/StringLiterals
5
8
  end
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Iconly/Bulk/Bookmark</title>
4
+ <g id="Iconly/Bulk/Bookmark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Bookmark" transform="translate(4.000000, 2.000000)" fill="#000000" fill-rule="nonzero">
6
+ <path d="M7.99117971,16.6215262 L1.49944873,19.8641008 C1.00920819,20.1302192 0.397682727,19.9525481 0.123484013,19.4643313 C0.043404087,19.3108374 0.00105752372,19.1402321 -5.24025268e-14,18.9668404 L-5.24025268e-14,11.7088036 C-5.24025268e-14,12.4283887 0.405733186,12.872577 1.47298787,13.3700679 L7.99117971,16.6215262 Z" id="Bookmark-2" opacity="0.400000006"></path>
7
+ <path d="M11.0694598,0 C13.7772878,0 15.9735391,1.06605192 16,3.79336809 L16,3.79336809 L16,18.9668404 C15.998918,19.1374024 15.9565307,19.3051222 15.876516,19.4554476 C15.7479482,19.7006536 15.5259405,19.8826876 15.2614691,19.959752 C14.9969977,20.0368164 14.7127851,20.0022901 14.4740904,19.8641008 L14.4740904,19.8641008 L7.99117971,16.6215262 L1.47298787,13.3700679 C0.405733186,12.872577 8.17124146e-14,12.4283887 8.17124146e-14,11.7088036 L8.17124146e-14,11.7088036 L8.17124146e-14,3.79336809 C8.17124146e-14,1.06605192 2.19625138,0 4.8952591,0 L4.8952591,0 Z M11.7486218,6.04096089 L4.22491731,6.04096089 C3.79137074,6.04096089 3.4399118,6.39494927 3.4399118,6.83161607 C3.4399118,7.26828286 3.79137074,7.62227124 4.22491731,7.62227124 L4.22491731,7.62227124 L11.7486218,7.62227124 C12.1821684,7.62227124 12.5336273,7.26828286 12.5336273,6.83161607 C12.5336273,6.39494927 12.1821684,6.04096089 11.7486218,6.04096089 L11.7486218,6.04096089 Z"></path>
8
+ </g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Iconly/Bulk/Chart</title>
4
+ <g id="Iconly/Bulk/Chart" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Chart" transform="translate(2.000000, 2.000000)" fill="currentColor" fill-rule="nonzero">
6
+ <path d="M14.6755556,0 L5.33333333,0 C1.92888889,0 0,1.92888889 0,5.33333333 L0,14.6666667 C0,18.0711111 1.92888889,20 5.33333333,20 L14.6755556,20 C18.08,20 20,18.0711111 20,14.6666667 L20,5.33333333 C20,1.92888889 18.08,0 14.6755556,0" id="Fill-1" opacity="0.400000006"></path>
7
+ <path d="M5.36871111,7.36897778 C4.91537778,7.36897778 4.54204444,7.74231111 4.54204444,8.20453333 L4.54204444,15.0756444 C4.54204444,15.5289778 4.91537778,15.9023111 5.36871111,15.9023111 C5.83093333,15.9023111 6.20426667,15.5289778 6.20426667,15.0756444 L6.20426667,8.20453333 C6.20426667,7.74231111 5.83093333,7.36897778 5.36871111,7.36897778" id="Fill-4"></path>
8
+ <path d="M10.0353778,4.08897778 C9.58204444,4.08897778 9.20871111,4.46231111 9.20871111,4.92453333 L9.20871111,15.0756444 C9.20871111,15.5289778 9.58204444,15.9023111 10.0353778,15.9023111 C10.4976,15.9023111 10.8709333,15.5289778 10.8709333,15.0756444 L10.8709333,4.92453333 C10.8709333,4.46231111 10.4976,4.08897778 10.0353778,4.08897778" id="Fill-6"></path>
9
+ <path d="M14.6399111,10.9956444 C14.1776889,10.9956444 13.8043556,11.3689778 13.8043556,11.8312 L13.8043556,15.0756444 C13.8043556,15.5289778 14.1776889,15.9023111 14.6310222,15.9023111 C15.0932444,15.9023111 15.4665778,15.5289778 15.4665778,15.0756444 L15.4665778,11.8312 C15.4665778,11.3689778 15.0932444,10.9956444 14.6399111,10.9956444" id="Fill-8"></path>
10
+ </g>
11
+ </g>
12
+ </svg>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <g id="Iconly/Bulk/Delete" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4
+ <g id="Delete" transform="translate(3.000000, 2.000000)" fill="currentColor" fill-rule="nonzero">
5
+ <path d="M16.6432894,7.4884379 C16.6432894,7.55643552 16.1103307,14.2971996 15.8059218,17.1341003 C15.6153015,18.8750394 14.492976,19.9310024 12.8094878,19.9610014 C11.5159931,19.9900003 10.2497298,20 9.00389021,20 C7.68121893,20 6.38772423,19.9900003 5.13215907,19.9610014 C3.50507888,19.9220027 2.38178085,18.8450404 2.2008861,17.1341003 C1.88772423,14.2871999 1.36449103,7.55643552 1.35476551,7.4884379 C1.34503998,7.28344508 1.41117355,7.0884519 1.54538578,6.93045743 C1.67765291,6.78446254 1.86827318,6.69646562 2.06861898,6.69646562 L15.9391614,6.69646562 C16.1385347,6.69646562 16.3194294,6.78446254 16.4623946,6.93045743 C16.5956343,7.0884519 16.6627404,7.28344508 16.6432894,7.4884379" id="Fill-1" opacity="0.400000006"></path>
6
+ <path d="M18,3.97686081 C18,3.56587519 17.67614,3.24388646 17.2871191,3.24388646 L14.371407,3.24388646 C13.77815,3.24388646 13.2626972,2.82190123 13.1304301,2.22692206 L12.9670413,1.49794757 C12.7384915,0.616978406 11.9497515,-1.50990331e-14 11.0647288,-1.50990331e-14 L6.93624379,-1.50990331e-14 C6.04149557,-1.50990331e-14 5.26053598,0.616978406 5.0232332,1.54594589 L4.87054247,2.22792202 C4.73730279,2.82190123 4.22185001,3.24388646 3.62956559,3.24388646 L0.713853469,3.24388646 C0.323859952,3.24388646 0,3.56587519 0,3.97686081 L0,4.35684751 C0,4.75783348 0.323859952,5.08982186 0.713853469,5.08982186 L17.2871191,5.08982186 C17.67614,5.08982186 18,4.75783348 18,4.35684751 L18,3.97686081 Z" id="Fill-4"></path>
7
+ </g>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
+ <g id="Iconly/Bulk/Graph" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4
+ <g id="Graph" transform="translate(2.000000, 2.000000)" fill="currentColor" fill-rule="nonzero">
5
+ <path d="M8.152754,3.55552761 C8.20368413,3.65919399 8.237323,3.77020981 8.2523868,3.88433813 L8.53082191,8.02425688 L8.53082191,8.02425688 L8.66903307,10.1050779 C8.67046167,10.3190591 8.7040335,10.5316649 8.76866587,10.7360386 C8.9355965,11.1325559 9.33716333,11.3845716 9.77405142,11.3669994 L16.4313342,10.9315476 C16.7196104,10.9267943 16.9980001,11.0346143 17.2052401,11.2312807 C17.3779401,11.3951693 17.4894372,11.6095651 17.524563,11.8401601 L17.5363525,11.9801866 C17.260866,15.7948982 14.4591587,18.9766559 10.6523561,19.797994 C6.84555351,20.6193322 2.94186389,18.8842999 1.06070995,15.534895 C0.518387516,14.5618191 0.179650312,13.4922526 0.0643819183,12.388978 C0.0162285779,12.0623771 -0.00497451535,11.7324952 0.000979225624,11.4025464 C-0.00496594783,7.31273376 2.90747021,3.77695779 6.98433295,2.92456686 C7.47500829,2.84816493 7.95602805,3.10792111 8.152754,3.55552761 Z"
6
+ id="Path"></path>
7
+ <path d="M10.8700123,0.000819186003 C15.42989,0.11682655 19.2623146,3.39578782 20,7.81229094 L19.9929553,7.84487576 L19.9929553,7.84487576 L19.9728274,7.89227188 L19.9756317,8.0223616 C19.9651826,8.19471218 19.8986437,8.36053991 19.7839681,8.49448471 C19.6645145,8.63401054 19.5013145,8.72903004 19.3215929,8.76590816 L19.2119951,8.78094898 L11.5312118,9.27860816 C11.2757261,9.30380455 11.0213466,9.22142251 10.8313499,9.05195453 C10.6730193,8.91073121 10.5717997,8.72009233 10.543203,8.5146766 L10.0276622,0.845062436 C10.0186901,0.819128783 10.0186901,0.791015148 10.0276622,0.765081496 C10.0347061,0.553672114 10.127765,0.353839855 10.2860482,0.210229821 C10.4443315,0.0666197874 10.6546487,-0.00880036929 10.8700123,0.000819186003 Z"
8
+ id="Path" opacity="0.400000006"></path>
9
+ </g>
10
+ </g>
11
+ </svg>