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.
- checksums.yaml +4 -4
- data/README.md +19 -10
- data/app/assets/javascripts/rails_mini_profiler.js +1 -78
- data/app/assets/stylesheets/rails_mini_profiler/application.css +1 -171
- data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +10 -1
- data/app/helpers/rails_mini_profiler/application_helper.rb +9 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/bookmark.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/chart.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/delete.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/graph.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/logo.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/logo_variant.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/search.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/setting.svg +0 -0
- data/app/{assets/images/rails_mini_profiler → javascript/images}/show.svg +0 -0
- data/app/javascript/packs/rails-mini-profiler.js +80 -0
- data/app/javascript/stylesheets/flamegraph.scss +9 -0
- data/app/{assets/stylesheets/rails_mini_profiler/flashes.css → javascript/stylesheets/flashes.scss} +0 -0
- data/app/{assets/stylesheets/rails_mini_profiler/navbar.css → javascript/stylesheets/navbar.scss} +2 -2
- data/app/{assets/stylesheets/rails_mini_profiler/profiled_requests.css → javascript/stylesheets/profiled_requests.scss} +1 -7
- data/app/javascript/stylesheets/rails-mini-profiler.scss +175 -0
- data/app/{assets/stylesheets/rails_mini_profiler/traces.css → javascript/stylesheets/traces.scss} +0 -5
- data/app/models/rails_mini_profiler/application_record.rb +1 -1
- data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +2 -2
- data/app/views/layouts/rails_mini_profiler/application.html.erb +1 -8
- data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +1 -8
- data/app/views/rails_mini_profiler/badge.html.erb +1 -1
- data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +3 -3
- data/app/views/rails_mini_profiler/shared/_head.erb +13 -0
- data/app/views/rails_mini_profiler/shared/_navbar.html.erb +1 -1
- data/lib/generators/rails_mini_profiler/install_generator.rb +18 -0
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +13 -0
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +18 -7
- data/lib/rails_mini_profiler.rb +29 -3
- data/lib/rails_mini_profiler/badge.rb +21 -1
- data/lib/rails_mini_profiler/configuration.rb +24 -0
- data/lib/rails_mini_profiler/engine.rb +8 -1
- data/lib/rails_mini_profiler/guard.rb +18 -7
- data/lib/rails_mini_profiler/logger.rb +5 -0
- data/lib/rails_mini_profiler/models/base_model.rb +5 -0
- data/lib/rails_mini_profiler/models/trace.rb +28 -0
- data/lib/rails_mini_profiler/redirect.rb +8 -0
- data/lib/rails_mini_profiler/request_context.rb +24 -5
- data/lib/rails_mini_profiler/storage.rb +18 -0
- data/lib/rails_mini_profiler/tracers.rb +1 -1
- data/lib/rails_mini_profiler/version.rb +4 -1
- data/vendor/assets/images/bookmark.svg +10 -0
- data/vendor/assets/images/chart.svg +12 -0
- data/vendor/assets/images/delete.svg +9 -0
- data/vendor/assets/images/graph.svg +11 -0
- data/vendor/assets/images/logo.svg +18 -0
- data/vendor/assets/images/logo_variant.svg +32 -0
- data/vendor/assets/images/search.svg +10 -0
- data/vendor/assets/images/setting.svg +10 -0
- data/vendor/assets/images/show.svg +11 -0
- data/vendor/assets/javascripts/rails-mini-profiler.css +1 -0
- data/vendor/assets/javascripts/rails-mini-profiler.js +1 -0
- metadata +31 -21
- data/app/assets/fonts/rails_mini_profiler/LICENSE.txt +0 -202
- data/app/assets/fonts/rails_mini_profiler/OpenSans-Bold.ttf +0 -0
- data/app/assets/fonts/rails_mini_profiler/OpenSans-Regular.ttf +0 -0
- data/app/assets/fonts/rails_mini_profiler/OpenSans-SemiBold.ttf +0 -0
- data/app/assets/stylesheets/rails_mini_profiler/flamegraph.css +0 -14
- 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
|
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[
|
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
|
-
|
17
|
-
|
18
|
-
|
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 =
|
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)
|
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
|
-
|
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>
|