pagy 43.6.2 → 43.7.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/apps/active_search.ru +283 -0
- data/apps/calendar.ru +6 -2
- data/apps/demo.ru +3 -3
- data/apps/enable_rails_page_segment.rb +1 -1
- data/apps/keynav+root_key.ru +7 -7
- data/apps/keynav.ru +4 -4
- data/apps/keyset.ru +4 -4
- data/apps/keyset_sequel.ru +3 -3
- data/apps/rails.ru +5 -5
- data/apps/repro.ru +4 -4
- data/config/pagy.rb +2 -2
- data/javascripts/pagy.js +3 -3
- data/javascripts/pagy.min.js +1 -1
- data/javascripts/pagy.mjs +1 -1
- data/lib/pagy/classes/offset/search.rb +25 -5
- data/lib/pagy/classes/request.rb +4 -4
- data/lib/pagy/cli.rb +1 -1
- data/lib/pagy/deprecated.rb +3 -3
- data/lib/pagy/modules/abilities/linkable.rb +1 -1
- data/lib/pagy/modules/searcher.rb +13 -6
- data/lib/pagy/next.rb +1 -1
- data/lib/pagy/toolbox/helpers/headers_hash.rb +3 -1
- data/lib/pagy/toolbox/helpers/limit_tag_js.rb +3 -3
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +3 -3
- data/lib/pagy/toolbox/helpers/urls_hash.rb +5 -4
- data/lib/pagy/toolbox/paginators/method.rb +1 -0
- data/lib/pagy/toolbox/paginators/rails_active_search.rb +35 -0
- data/lib/pagy.rb +4 -3
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: acefb70fcb49a67bc580acb08d9d199cc57caecf51721e437cc475051641c555
|
|
4
|
+
data.tar.gz: 6a3bacb516190cd2669ea92c233338043bbe597d674ac0c4ed41799be9be1e2b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4bbb2f141e1657e4c6edbb96ba4bf6668c2f449b894f8c1ef5b4ee689f6edd018a71134f0485674bad8276e52dd00ac156bece5e918caa07905bd6db94889d9d
|
|
7
|
+
data.tar.gz: 4d67fb4c5a20e3935734cc63851eee75d2a49d2b1280ed7c5f8874df90429e711c7fe0c605c372b9963639f5dde0711a54ccd2e3ef5706c8123b77fc09a85b75
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# DESCRIPTION
|
|
4
|
+
# Showcase the ActiveSearch pagination (active and passive modes)
|
|
5
|
+
#
|
|
6
|
+
# DOC
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#active-search
|
|
8
|
+
#
|
|
9
|
+
# BIN HELP
|
|
10
|
+
# pagy -h
|
|
11
|
+
#
|
|
12
|
+
# DEV USAGE
|
|
13
|
+
# pagy clone active_search
|
|
14
|
+
# pagy ./active_search.ru
|
|
15
|
+
#
|
|
16
|
+
# URL
|
|
17
|
+
# http://127.0.0.1:8000
|
|
18
|
+
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
|
+
|
|
21
|
+
if VERSION != Pagy::VERSION
|
|
22
|
+
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Bundle
|
|
26
|
+
require 'bundler/inline'
|
|
27
|
+
gemfile(!Pagy::ROOT.join('pagy.gemspec').exist?) do
|
|
28
|
+
source 'https://rubygems.org'
|
|
29
|
+
gem 'oj'
|
|
30
|
+
gem 'puma'
|
|
31
|
+
gem 'rails', '~> 8.1'
|
|
32
|
+
gem 'sqlite3'
|
|
33
|
+
gem 'rails-active_search'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# require 'rails/all' # too much stuff
|
|
37
|
+
require 'action_controller/railtie'
|
|
38
|
+
require 'active_record'
|
|
39
|
+
require 'rails-active_search'
|
|
40
|
+
|
|
41
|
+
OUTPUT = Rails.env.showcase? ? IO::NULL : $stdout
|
|
42
|
+
|
|
43
|
+
# Rails config
|
|
44
|
+
class PagyActiveSearch < Rails::Application # :nodoc:
|
|
45
|
+
config.root = __dir__
|
|
46
|
+
config.eager_load = false
|
|
47
|
+
config.session_store :cookie_store, key: 'cookie_store_key'
|
|
48
|
+
Rails.application.credentials.secret_key_base = 'absolute_secret'
|
|
49
|
+
|
|
50
|
+
config.logger = Logger.new(OUTPUT)
|
|
51
|
+
Rails.logger = config.logger
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Initialize the app in order to run the ActiveSearch engine initializers
|
|
55
|
+
PagyActiveSearch.initialize!
|
|
56
|
+
|
|
57
|
+
# Draw the routes after the initialization, which would otherwise reset them
|
|
58
|
+
PagyActiveSearch.routes.draw do
|
|
59
|
+
root to: 'comments#active'
|
|
60
|
+
get '/comments/active', to: 'comments#active'
|
|
61
|
+
get '/comments/passive', to: 'comments#passive'
|
|
62
|
+
get '/javascripts/:file', to: 'pagy#javascripts', file: /.*/
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# ActiveSearch reads its stores only from config/search.yml, so we apply the equivalent config directly.
|
|
66
|
+
# The sqlite adapter uses the ActiveRecord connection, so it takes no connection options.
|
|
67
|
+
ActiveSearch.configuration.apply_store_config(adapter: :sqlite)
|
|
68
|
+
|
|
69
|
+
# Activerecord initializer
|
|
70
|
+
ActiveRecord::Base.logger = Logger.new(OUTPUT)
|
|
71
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'file:memdb1?mode=memory&cache=shared')
|
|
72
|
+
ActiveRecord::Schema.define do
|
|
73
|
+
create_table :posts, force: true do |t|
|
|
74
|
+
t.string :title
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
create_table :comments, force: true do |t|
|
|
78
|
+
t.string :body
|
|
79
|
+
t.integer :post_id
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# ActiveSearch sqlite documents: a table for the filterable fields and an FTS5 table for the text fields
|
|
83
|
+
create_table :post_documents, force: true do |t|
|
|
84
|
+
t.string :post_id, null: false, index: { unique: true }
|
|
85
|
+
end
|
|
86
|
+
create_virtual_table :post_documents_fts, :fts5, [:title]
|
|
87
|
+
|
|
88
|
+
create_table :comment_documents, force: true do |t|
|
|
89
|
+
t.string :comment_id, null: false, index: { unique: true }
|
|
90
|
+
t.integer :post_id
|
|
91
|
+
end
|
|
92
|
+
create_virtual_table :comment_documents_fts, :fts5, [:body]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class ApplicationRecord < ActiveRecord::Base
|
|
96
|
+
primary_abstract_class
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# ActiveSearch document models (one per index)
|
|
100
|
+
class PostDocument < ApplicationRecord; end
|
|
101
|
+
class CommentDocument < ApplicationRecord; end
|
|
102
|
+
|
|
103
|
+
# Models
|
|
104
|
+
class Post < ApplicationRecord # :nodoc:
|
|
105
|
+
extend Pagy::Search
|
|
106
|
+
|
|
107
|
+
has_many :comments
|
|
108
|
+
has_search async: false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# :nodoc:
|
|
112
|
+
|
|
113
|
+
class Comment < ApplicationRecord # :nodoc:
|
|
114
|
+
extend Pagy::Search
|
|
115
|
+
|
|
116
|
+
belongs_to :post
|
|
117
|
+
has_search async: false
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
ActiveSearch.define_index(:posts) do
|
|
121
|
+
text :title
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
ActiveSearch.define_index(:comments) do
|
|
125
|
+
text :body
|
|
126
|
+
integer :post_id
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# :nodoc:
|
|
130
|
+
|
|
131
|
+
# Unused model, useful to test overriding conflicts
|
|
132
|
+
module Calendar
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# DB seed
|
|
136
|
+
1.upto(11) do |pi|
|
|
137
|
+
Post.create(title: "Post #{pi + 1}")
|
|
138
|
+
end
|
|
139
|
+
Post.all.each_with_index do |post, pi|
|
|
140
|
+
2.times { |ci| Comment.create(post:, body: "Comment #{ci + 1} to Post #{pi + 1}") }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Controllers
|
|
144
|
+
class CommentsController < ActionController::Base # :nodoc:
|
|
145
|
+
include Rails.application.routes.url_helpers
|
|
146
|
+
include Pagy::Method
|
|
147
|
+
|
|
148
|
+
def active
|
|
149
|
+
search = Comment.pagy_search(params[:q])
|
|
150
|
+
@pagy, @comments = pagy(:rails_active_search, search, limit: 10, client_limit: 100)
|
|
151
|
+
# Reload the page in the network tab of the Chrome Inspector to check
|
|
152
|
+
# response.headers.merge!(@pagy.headers_hash)
|
|
153
|
+
render inline: TEMPLATE
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def passive
|
|
157
|
+
limit = [params[:limit].to_i, 10].max.clamp(..100)
|
|
158
|
+
page = [params[:page].to_i, 1].max
|
|
159
|
+
@comments = Comment.search(params[:q]).limit(limit).offset(limit * (page - 1)).results
|
|
160
|
+
@pagy = pagy(:rails_active_search, @comments, client_limit: 100)
|
|
161
|
+
# Reload the page in the network tab of the Chrome Inspector to check
|
|
162
|
+
# response.headers.merge!(@pagy.headers_hash)
|
|
163
|
+
render inline: TEMPLATE
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# You don't need this in real rails apps (see https://ddnexus.github.io/pagy/resources/javascripts)
|
|
168
|
+
class PagyController < ActionController::Base
|
|
169
|
+
def javascripts
|
|
170
|
+
format = params[:file].split('.').last
|
|
171
|
+
if format == 'js'
|
|
172
|
+
render js: Pagy::ROOT.join('javascripts', params[:file]).read
|
|
173
|
+
elsif format == 'map'
|
|
174
|
+
render json: Pagy::ROOT.join('javascripts', params[:file]).read
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
run PagyActiveSearch
|
|
180
|
+
|
|
181
|
+
TEMPLATE = <<~ERB
|
|
182
|
+
<!DOCTYPE html>
|
|
183
|
+
<html lang="en">
|
|
184
|
+
<head>
|
|
185
|
+
<title>Pagy ActiveSearch App</title>
|
|
186
|
+
<script src="/javascripts/pagy.js"></script>
|
|
187
|
+
<script>
|
|
188
|
+
window.addEventListener("load", Pagy.init);
|
|
189
|
+
</script>
|
|
190
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
191
|
+
<style type="text/css">
|
|
192
|
+
@media screen { html, body {
|
|
193
|
+
font-size: 1rem;
|
|
194
|
+
line-height: 1.2;
|
|
195
|
+
padding: 0;
|
|
196
|
+
margin: 0;
|
|
197
|
+
} }
|
|
198
|
+
body {
|
|
199
|
+
background: white !important;
|
|
200
|
+
margin: 0 !important;
|
|
201
|
+
font-family: sans-serif !important;
|
|
202
|
+
}
|
|
203
|
+
.main-content {
|
|
204
|
+
padding: 1rem 1.5rem 2rem !important;
|
|
205
|
+
}
|
|
206
|
+
.pagy, .pagy-bootstrap, .pagy-bulma {
|
|
207
|
+
padding: .5em;
|
|
208
|
+
margin: .3em 0;
|
|
209
|
+
width: fit-content;
|
|
210
|
+
box-shadow: 5px 5px 10px 0px rgba(0,0,0,0.2);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Quick demo for overriding the element style attribute of certain pagy helpers
|
|
214
|
+
.pagy input[style] {
|
|
215
|
+
width: 5rem !important;
|
|
216
|
+
}
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
/*
|
|
220
|
+
If you want to customize the style,
|
|
221
|
+
please replace the line below with the actual file content
|
|
222
|
+
*/
|
|
223
|
+
<%== Pagy::ROOT.join('stylesheets/pagy.css').read %>
|
|
224
|
+
</style>
|
|
225
|
+
</head>
|
|
226
|
+
|
|
227
|
+
<body>
|
|
228
|
+
|
|
229
|
+
<div class="main-content">
|
|
230
|
+
<h1>Pagy ActiveSearch App</h1>
|
|
231
|
+
<p> Self-contained, standalone Rails app usable to easily reproduce any rails related pagy issue.</p>
|
|
232
|
+
|
|
233
|
+
<h2>Versions</h2>
|
|
234
|
+
<ul>
|
|
235
|
+
<li>Ruby: <%== RUBY_VERSION %></li>
|
|
236
|
+
<li>Rack: <%== Rack::RELEASE %></li>
|
|
237
|
+
<li>Rails: <%== Rails.version %></li>
|
|
238
|
+
<li>Pagy: <%== Pagy::VERSION %></li>
|
|
239
|
+
</ul>
|
|
240
|
+
|
|
241
|
+
<h3>Active Collection</h3>
|
|
242
|
+
<%= form_with url: { controller: 'comments', action: 'active' }, method: :get, local: true do |form| %>
|
|
243
|
+
<%= form.text_field :q, value: params[:q], placeholder: "Search..." %>
|
|
244
|
+
<%= form.submit "Search" %>
|
|
245
|
+
<% end %>
|
|
246
|
+
|
|
247
|
+
<h3>Passive Collection</h3>
|
|
248
|
+
<%= form_with url: { controller: 'comments', action: 'passive' }, method: :get, local: true do |form| %>
|
|
249
|
+
<%= form.text_field :q, value: params[:q], placeholder: "Search..." %>
|
|
250
|
+
<%= form.submit "Search" %>
|
|
251
|
+
<% end %>
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
<div id="records" class="collection">
|
|
255
|
+
<% @comments.each do |comment| %>
|
|
256
|
+
<p style="margin: 0;"><%= comment.body %></p>
|
|
257
|
+
<% end %>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<hr>
|
|
261
|
+
|
|
262
|
+
<h4>@pagy.series_nav</h4>
|
|
263
|
+
<%== @pagy.series_nav(id: 'series-nav',
|
|
264
|
+
aria_label: 'Pages nav') %>
|
|
265
|
+
|
|
266
|
+
<h4>@pagy.series_nav_js</h4>
|
|
267
|
+
<%== @pagy.series_nav_js(id: 'series-nav-js',
|
|
268
|
+
aria_label: 'Pages nav_js') %>
|
|
269
|
+
|
|
270
|
+
<h4>@pagy.input_nav_js</h4>
|
|
271
|
+
<%== @pagy.input_nav_js(id: 'input-nav-js',
|
|
272
|
+
aria_label: 'Pages input_nav_js') %>
|
|
273
|
+
|
|
274
|
+
<h4>@pagy.limit_tag_js</h4>
|
|
275
|
+
<%== @pagy.limit_tag_js(id: 'limit-tag-js') %>
|
|
276
|
+
|
|
277
|
+
<h4>@pagy.info_tag</h4>
|
|
278
|
+
<%== @pagy.info_tag(id: 'pagy-info') %>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
</body>
|
|
282
|
+
</html>
|
|
283
|
+
ERB
|
data/apps/calendar.ru
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Showcase the calendar; reproduce related issues
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#calendar
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -46,6 +46,10 @@ require 'sinatra/base'
|
|
|
46
46
|
class PagyCalendar < Sinatra::Base
|
|
47
47
|
include Pagy::Method
|
|
48
48
|
|
|
49
|
+
# Serve one request at a time: concurrent requests calling the groupdate SQLite function
|
|
50
|
+
# on the shared in-memory database deadlock the server
|
|
51
|
+
use Rack::Lock
|
|
52
|
+
|
|
49
53
|
if ENV['E2E_TEST']
|
|
50
54
|
get('/assets/:file') do
|
|
51
55
|
content_type 'text/css'
|
data/apps/demo.ru
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Showcase all the helpers and styles
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#demo
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#demo
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
# URL
|
|
20
20
|
# http://127.0.0.1:8000
|
|
21
21
|
|
|
22
|
-
VERSION = '43.
|
|
22
|
+
VERSION = '43.7.0'
|
|
23
23
|
|
|
24
24
|
if VERSION != Pagy::VERSION
|
|
25
25
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -46,7 +46,7 @@ SECTIONS = { pagy: { css_anchor: 'pagy-css' },
|
|
|
46
46
|
require 'sinatra/base'
|
|
47
47
|
|
|
48
48
|
# Pagy init
|
|
49
|
-
Pagy::OPTIONS[:
|
|
49
|
+
Pagy::OPTIONS[:client_limit] = 100
|
|
50
50
|
|
|
51
51
|
# Sinatra application
|
|
52
52
|
class PagyDemo < Sinatra::Base
|
|
@@ -47,7 +47,7 @@ class Pagy
|
|
|
47
47
|
# Compose the final URL using `url_for`.
|
|
48
48
|
module LinkableOverride
|
|
49
49
|
def compose_url(absolute, _path, params, fragment)
|
|
50
|
-
params[:anchor] = fragment
|
|
50
|
+
params[:anchor] = fragment unless fragment.to_s.empty?
|
|
51
51
|
params[:only_path] = !absolute
|
|
52
52
|
@context.url_for(params)
|
|
53
53
|
end
|
data/apps/keynav+root_key.ru
CHANGED
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
# Showcase the Keynav pagination with independent instances
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#keysets
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
11
11
|
#
|
|
12
12
|
# DEV USAGE
|
|
13
|
-
# pagy clone keynav
|
|
14
|
-
# pagy ./keynav.ru
|
|
13
|
+
# pagy clone keynav+root_key
|
|
14
|
+
# pagy ./keynav+root_key.ru
|
|
15
15
|
#
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -35,7 +35,7 @@ end
|
|
|
35
35
|
# Sinatra setup
|
|
36
36
|
require 'sinatra/base'
|
|
37
37
|
# Sinatra application
|
|
38
|
-
class
|
|
38
|
+
class PagyKeynavRootKey < Sinatra::Base
|
|
39
39
|
include Pagy::Method
|
|
40
40
|
|
|
41
41
|
get('/javascripts/:file') do
|
|
@@ -132,7 +132,7 @@ class PagyKeynav < Sinatra::Base
|
|
|
132
132
|
template :main do
|
|
133
133
|
<<~ERB
|
|
134
134
|
<div class="main-content">
|
|
135
|
-
<h1>Pagy Keynav App</h1>
|
|
135
|
+
<h1>Pagy Keynav (root_key) App</h1>
|
|
136
136
|
<p>Self-contained, standalone app usable to easily reproduce any Keynav related pagy issue
|
|
137
137
|
with ActiveRecord sets.</p>
|
|
138
138
|
<p>The panels below show how to use the <code>:root_key</code> option for independent instances in the same request.</p>
|
|
@@ -313,4 +313,4 @@ data.each_line(chomp: true) do |pet|
|
|
|
313
313
|
end
|
|
314
314
|
Pet.insert_all(pets)
|
|
315
315
|
|
|
316
|
-
run
|
|
316
|
+
run PagyKeynavRootKey
|
data/apps/keynav.ru
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Showcase the Keynav pagination (ActiveRecord example)
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#keysets
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -53,9 +53,9 @@ class PagyKeynav < Sinatra::Base
|
|
|
53
53
|
Time.zone = 'UTC'
|
|
54
54
|
|
|
55
55
|
@order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }.freeze
|
|
56
|
-
@pagy, @pets = pagy(:keynav_js, Pet.order(@order), limit: 4,
|
|
56
|
+
@pagy, @pets = pagy(:keynav_js, Pet.order(@order), limit: 4, client_limit: 100)
|
|
57
57
|
# Support also root_key for replacing url in javascript
|
|
58
|
-
# @pagy, @pets = pagy(:keynav_js, Pet.order(@order), limit: 4,
|
|
58
|
+
# @pagy, @pets = pagy(:keynav_js, Pet.order(@order), limit: 4, client_limit: 100, root_key: 'animal')
|
|
59
59
|
@ids = @pets.pluck(:id)
|
|
60
60
|
erb :main
|
|
61
61
|
end
|
data/apps/keyset.ru
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Showcase the Keyset pagination (ActiveRecord example)
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#keysets
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -43,10 +43,10 @@ class PagyKeyset < Sinatra::Base
|
|
|
43
43
|
Time.zone = 'UTC'
|
|
44
44
|
|
|
45
45
|
@order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }.freeze
|
|
46
|
-
@pagy, @pets = pagy(:keyset, Pet.order(@order), limit: 10,
|
|
46
|
+
@pagy, @pets = pagy(:keyset, Pet.order(@order), limit: 10, client_limit: 100)
|
|
47
47
|
# @pagy, @pets = pagy(:keyset, Pet.order(@order),
|
|
48
48
|
# jsonapi: true, page_key: 'number', limit_key: 'size', # very customized jsonapi
|
|
49
|
-
# limit: 10,
|
|
49
|
+
# limit: 10, client_limit: 100)
|
|
50
50
|
# response.headers.merge!(@pagy.headers_hash)
|
|
51
51
|
erb :main
|
|
52
52
|
end
|
data/apps/keyset_sequel.ru
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Showcase the Keyset pagination (Sequel example)
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#keysets
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -43,7 +43,7 @@ class PagyKeysetSequel < Sinatra::Base
|
|
|
43
43
|
get '/' do
|
|
44
44
|
@order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }.freeze
|
|
45
45
|
@pagy, @pets = pagy(:keyset, Pet.order(:animal, :name, Sequel.desc(:birthdate), :id),
|
|
46
|
-
limit: 10,
|
|
46
|
+
limit: 10, client_limit: 100)
|
|
47
47
|
erb :main
|
|
48
48
|
end
|
|
49
49
|
|
data/apps/rails.ru
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# DESCRIPTION
|
|
4
|
-
# Reproduce
|
|
4
|
+
# Reproduce Rails-related issues
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#rails
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#rails
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -28,7 +28,7 @@ gemfile(!Pagy::ROOT.join('pagy.gemspec').exist?) do
|
|
|
28
28
|
source 'https://rubygems.org'
|
|
29
29
|
gem 'oj'
|
|
30
30
|
gem 'puma'
|
|
31
|
-
gem 'rails', '~> 8.
|
|
31
|
+
gem 'rails', '~> 8.1'
|
|
32
32
|
gem 'sqlite3'
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -102,7 +102,7 @@ class CommentsController < ActionController::Base # :nodoc:
|
|
|
102
102
|
include Pagy::Method
|
|
103
103
|
|
|
104
104
|
def index
|
|
105
|
-
@pagy, @comments = pagy(:offset, Comment.all, limit: 10,
|
|
105
|
+
@pagy, @comments = pagy(:offset, Comment.all, limit: 10, client_limit: 100)
|
|
106
106
|
# Reload the page in the network tab of the Chrome Inspector to check
|
|
107
107
|
# response.headers.merge!(@pagy.headers_hash)
|
|
108
108
|
render inline: TEMPLATE
|
data/apps/repro.ru
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Reproduce generic/simple issues
|
|
5
5
|
#
|
|
6
6
|
# DOC
|
|
7
|
-
# https://ddnexus.github.io/pagy/playground/#repro
|
|
7
|
+
# https://ddnexus.github.io/pagy/sandbox/playground/#repro
|
|
8
8
|
#
|
|
9
9
|
# BIN HELP
|
|
10
10
|
# pagy -h
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# URL
|
|
17
17
|
# http://127.0.0.1:8000
|
|
18
18
|
|
|
19
|
-
VERSION = '43.
|
|
19
|
+
VERSION = '43.7.0'
|
|
20
20
|
|
|
21
21
|
if VERSION != Pagy::VERSION
|
|
22
22
|
Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
|
|
@@ -34,7 +34,7 @@ end
|
|
|
34
34
|
|
|
35
35
|
# Edit this section adding the legacy as needed
|
|
36
36
|
# Pagy initializer
|
|
37
|
-
Pagy::OPTIONS[:
|
|
37
|
+
Pagy::OPTIONS[:client_limit] = 100
|
|
38
38
|
|
|
39
39
|
# Sinatra setup
|
|
40
40
|
require 'sinatra/base'
|
|
@@ -56,7 +56,7 @@ class PagyRepro < Sinatra::Base
|
|
|
56
56
|
get '/' do
|
|
57
57
|
collection = MockCollection.new
|
|
58
58
|
@pagy, @records = pagy(collection) # simplest form
|
|
59
|
-
# @pagy, @records = pagy(:offset, collection, limit: 7,
|
|
59
|
+
# @pagy, @records = pagy(:offset, collection, limit: 7, client_limit: 30)
|
|
60
60
|
# @pagy, @records = pagy(:countish, collection, ttl: 20)
|
|
61
61
|
# @pagy, @records = pagy(:countless, collection)
|
|
62
62
|
# @pagy, @records = pagy(Array(1..1000))
|
data/config/pagy.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Pagy initializer file (43.
|
|
3
|
+
# Pagy initializer file (43.7.0)
|
|
4
4
|
# See https://ddnexus.github.io/pagy/toolbox/configuration/initializer/
|
|
5
5
|
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
# Examples:
|
|
10
10
|
#
|
|
11
11
|
# Pagy::OPTIONS[:limit] = 10 # Limit the items per page
|
|
12
|
-
# Pagy::OPTIONS[:
|
|
12
|
+
# Pagy::OPTIONS[:client_limit] = 100 # The client is allowed to request a limit up to 100
|
|
13
13
|
# Pagy::OPTIONS[:jsonapi] = true # Use JSON:API compliant URLs
|
|
14
14
|
|
|
15
15
|
Pagy::OPTIONS.freeze
|
data/javascripts/pagy.js
CHANGED
|
@@ -135,7 +135,7 @@ var pagy_default = (() => {
|
|
|
135
135
|
});
|
|
136
136
|
};
|
|
137
137
|
return {
|
|
138
|
-
version: "43.
|
|
138
|
+
version: "43.7.0",
|
|
139
139
|
init(arg) {
|
|
140
140
|
const target = arg instanceof HTMLElement ? arg : document, elements = target.querySelectorAll("[data-pagy]");
|
|
141
141
|
for (const element of elements) {
|
|
@@ -162,5 +162,5 @@ var pagy_default = (() => {
|
|
|
162
162
|
// pagy-shim.ts
|
|
163
163
|
window.Pagy = pagy_default;
|
|
164
164
|
|
|
165
|
-
//# debugId=
|
|
166
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsicGFneS50cyIsICJwYWd5LXNoaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiaW50ZXJmYWNlIFN5bmNEYXRhIHtcbiAgZnJvbT86IG51bWJlclxuICB0bz8gIDogbnVtYmVyXG4gIGtleSAgOiBzdHJpbmdcbiAgc3RyPyA6IHN0cmluZ1xufVxudHlwZSBJbml0QXJncyA9IFtcImtcIiwgIEtleW5hdkFyZ3NdIHwgICAgICAgICAgLy8gc2VyaWVzX25hdltfanNdIHdpdGgga2V5bmF2IGluc3RhbmNlXG4gICAgICAgICAgICAgICAgW1wic25qXCIsIFNlcmllc05hdkpzQXJnc10gfCAgICAvLyBzZXJpZXNfbmF2X2pzXG4gICAgICAgICAgICAgICAgW1wiaW5qXCIsIElucHV0TmF2SnNBcmdzXSB8ICAgICAvLyBpbnB1dF9uYXZfanNcbiAgICAgICAgICAgICAgICBbXCJsdGpcIiwgTGltaXRUYWdKc0FyZ3NdOyAgICAgIC8vIGxpbWl0X3RhZ19qc1xudHlwZSBBdWdtZW50S2V5bmF2ID0gKG5hdjpIVE1MRWxlbWVudCwga2V5bmF2QXJnczpLZXluYXZBcmdzKSA9PiBQcm9taXNlPCgocGFnZTogc3RyaW5nKSA9PiBzdHJpbmcpPjtcbnR5cGUgS2V5bmF2QXJncyA9IHJlYWRvbmx5IFtzdG9yYWdlS2V5IDogc3RyaW5nIHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290S2V5ICAgIDogc3RyaW5nIHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlS2V5ICAgIDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3QgICAgICAgOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaWNlQXJncz86IFNwbGljZUFyZ3NdO1xudHlwZSBTcGxpY2VBcmdzID0gcmVhZG9ubHkgW3N0YXJ0ICAgICAgOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlQ291bnQ6IG51bWJlciwgICAgIC8vIGl0IHdvdWxkIGJlIG9wdGlvbmFsLCBidXQgdHMgY29tcGxhaW5zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uaXRlbXM6ICAgIEN1dG9mZltdXTtcbnR5cGUgQ3V0b2ZmID0gcmVhZG9ubHkgKHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4pW107XG50eXBlIEF1Z21lbnRlZFBhZ2UgPSBbYnJvd3NlcklkICA6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICBzdG9yYWdlS2V5IDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgIHBhZ2VOdW1iZXIgOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgcGFnZXMgICAgICA6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICBwcmlvckN1dG9mZjogQ3V0b2ZmIHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICBwYWdlQ3V0b2ZmIDogQ3V0b2ZmIHwgbnVsbF07XG50eXBlIFNlcmllc05hdkpzQXJncyA9IHJlYWRvbmx5IFtOYXZKc1Rva2VucywgcGFnZVRva2VuOiBzdHJpbmcsIE5hdkpzU2VyaWVzLCBLZXluYXZBcmdzP107XG50eXBlIE5hdkpzU2VyaWVzID0gcmVhZG9ubHkgW3dpZHRoczogbnVtYmVyW10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmllczogKHN0cmluZyB8IG51bWJlcilbXVtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM6IHN0cmluZ1tdW10gfCBudWxsXTtcbnR5cGUgSW5wdXROYXZKc0FyZ3MgPSByZWFkb25seSBbdXJsVG9rZW46ICBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VUb2tlbjogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXluYXZBcmdzP107XG50eXBlIExpbWl0VGFnSnNBcmdzID0gcmVhZG9ubHkgW2Zyb20gICAgICA6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsVG9rZW4gIDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlVG9rZW4gOiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0VG9rZW46IHN0cmluZ107XG50eXBlIE5hdkpzVG9rZW5zID0gcmVhZG9ubHkgW2JlZm9yZSA6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yIDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhcCAgICA6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXIgIDogc3RyaW5nXTtcbmludGVyZmFjZSBOYXZKc0VsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gIHJlbmRlcigpOiB2b2lkXG59XG5cbi8vIFRoZSBzeW50YXggdXNlZCBpbiB0aGlzIGZpbGUgaGFzIGJlZW4gY2FyZWZ1bGx5IGNvbXBvc2VkIHRvIG1pbmltaXplXG4vLyB0aGUgcGFneS5taW4uanMgc2l6ZSBhbmQgYXZvaWQgcG9sbHV0aW9uIGluIHRoZSB3aW5kb3cgb2JqZWN0LlxuZXhwb3J0IGRlZmF1bHQgKCgpID0+IHtcbiAgY29uc3Qgc3RvcmFnZVN1cHBvcnQgPSAnc2Vzc2lvblN0b3JhZ2UnIGluIHdpbmRvdyAmJiAnQnJvYWRjYXN0Q2hhbm5lbCcgaW4gd2luZG93O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gIGxldCBwYWd5ID0gXCJwYWd5XCIsIHN0b3JhZ2U6IFN0b3JhZ2UsIHN5bmM6IEJyb2FkY2FzdENoYW5uZWwsIHRhYklkOiBudW1iZXI7XG4gIGlmIChzdG9yYWdlU3VwcG9ydCkge1xuICAgIHN0b3JhZ2UgPSBzZXNzaW9uU3RvcmFnZTsgLy8gc2hvcnRlbiB0aGUgY29tcGlsZWQgc2l6ZVxuICAgIHN5bmMgICAgPSBuZXcgQnJvYWRjYXN0Q2hhbm5lbChwYWd5KTtcbiAgICB0YWJJZCAgID0gRGF0ZS5ub3coKTtcblxuICAgIC8vIFN5bmMgdGhlIHNlc3Npb25TdG9yYWdlIGtleXMgZm9yIHRoZSBjdXRvZmZzIG9wZW5lZCBpbiBhIG5ldyB0YWIvd2luZG93XG4gICAgc3luYy5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCAoZTpNZXNzYWdlRXZlbnQ8U3luY0RhdGE+KSA9PiB7XG4gICAgICBpZiAoZS5kYXRhLmZyb20pIHsgLy8gcmVxdWVzdCBjdXRvZmZzXG4gICAgICAgIGNvbnN0IGN1dG9mZnMgPSBzdG9yYWdlLmdldEl0ZW0oZS5kYXRhLmtleSk7XG4gICAgICAgIGlmIChjdXRvZmZzKSB7XG4gICAgICAgICAgc3luYy5wb3N0TWVzc2FnZSg8U3luY0RhdGE+e3RvOiBlLmRhdGEuZnJvbSwga2V5OiBlLmRhdGEua2V5LCBzdHI6IGN1dG9mZnN9KTtcbiAgICAgICAgfSAvLyBzZW5kIHJlc3BvbnNlXG4gICAgICB9IGVsc2UgaWYgKGUuZGF0YS50bykgeyAgLy8gcmVjZWl2ZSBjdXRvZmZzXG4gICAgICAgIGlmIChlLmRhdGEudG8gPT0gdGFiSWQpIHtcbiAgICAgICAgICBzdG9yYWdlLnNldEl0ZW0oZS5kYXRhLmtleSwgPHN0cmluZz5lLmRhdGEuc3RyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8vIFRoZSBvYnNlcnZlciBpbnN0YW5jZSBmb3IgcmVzcG9uc2l2ZSBuYXZzXG4gIGNvbnN0IHJqc09ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgIGVudHJpZXMuZm9yRWFjaChlID0+IHtcbiAgICAgIGUudGFyZ2V0LnF1ZXJ5U2VsZWN0b3JBbGw8TmF2SnNFbGVtZW50PihcIi5zZXJpZXMtbmF2LWpzXCIpLmZvckVhY2goZWwgPT4ge1xuICAgICAgICBlbC5yZW5kZXIoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvKiBGdWxsIHNldCBvZiBCNjQgZnVuY3Rpb25zXG4gIGNvbnN0IEI2NEVuY29kZSAgICAgPSAodW5pY29kZTpzdHJpbmcpID0+IGJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4obmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodW5pY29kZSkpKSxcbiAgICAgICAgQjY0U2FmZSAgICAgICA9ICh1bnNhZmU6c3RyaW5nKSAgPT4gdW5zYWZlLnJlcGxhY2UoL1srLz1dL2csIChtKSA9PiBtID09IFwiK1wiID8gXCItXCIgOiBtID09IFwiL1wiID8gXCJfXCIgOiBcIlwiKSxcbiAgICAgICAgQjY0U2FmZUVuY29kZSA9ICh1bmljb2RlOnN0cmluZykgPT4gQjY0U2FmZShCNjRFbmNvZGUodW5pY29kZSkpLFxuICAgICAgICBCNjREZWNvZGUgICAgID0gKGJhc2U2NDpzdHJpbmcpICA9PiAobmV3IFRleHREZWNvZGVyKCkpLmRlY29kZShVaW50OEFycmF5LmZyb20oYXRvYihiYXNlNjQpLCBjID0+IGMuY2hhckNvZGVBdCgwKSkpLFxuICAgICAgICBCNjRVbnNhZmUgICAgID0gKHNhZmU6c3RyaW5nKSAgICA9PiBzYWZlLnJlcGxhY2UoL1stX10vZywgKG1hdGNoKSA9PiBtYXRjaCA9PSBcIi1cIiA/IFwiK1wiIDogXCIvXCIpLFxuICAgICAgICBCNjRTYWZlRGVjb2RlID0gKGJhc2U2NDpzdHJpbmcpICA9PiBCNjREZWNvZGUoQjY0VW5zYWZlKGJhc2U2NCkpXG4gICovXG4gIGNvbnN0IEI2NFNhZmVFbmNvZGUgPSAodW5pY29kZTpzdHJpbmcpID0+IGJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4obmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodW5pY29kZSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1srLz1dL2csIChtKSA9PiBtID09IFwiK1wiID8gXCItXCIgOiBtID09IFwiL1wiID8gXCJfXCIgOiBcIlwiKSxcbiAgICAgICAgQjY0RGVjb2RlICAgICA9IChiYXNlNjQ6c3RyaW5nKSAgPT4gKG5ldyBUZXh0RGVjb2RlcigpKS5kZWNvZGUoVWludDhBcnJheS5mcm9tKGF0b2IoYmFzZTY0KSwgYyA9PiBjLmNoYXJDb2RlQXQoMCkpKTtcblxuICAvLyBSZXR1cm4gYSByYW5kb20ga2V5OiAzIGNoYXJzIG1heCwgYmFzZS0zNiBudW1iZXIgPCAzNioqM1xuICBjb25zdCByYW5kS2V5ID0gKCkgPT4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMzYgKiogMykudG9TdHJpbmcoMzYpO1xuXG4gIC8vIE1hbmFnZSB0aGUgcGFnZSBhdWdtZW50YXRpb24gZm9yIEtleW5hdiwgY2FsbGVkIG9ubHkgaWYgc3RvcmFnZVN1cHBvcnRcbiAgY29uc3QgYXVnbWVudEtleW5hdjogQXVnbWVudEtleW5hdiA9IGFzeW5jIChuYXYsIFtzdG9yYWdlS2V5LCByb290S2V5LCBwYWdlS2V5LCBsYXN0LCBzcGxpY2VBcmdzXSkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBhbGlnbi1hc3NpZ25tZW50cy9hbGlnbi1hc3NpZ25tZW50c1xuICAgIGxldCBhdWdtZW50UGFnZTogKHBhZ2U6IHN0cmluZykgPT4gc3RyaW5nO1xuICAgIGNvbnN0IGJyb3dzZXJLZXkgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoLztcXHMrLykgIC8vIGl0IHdvcmtzIGV2ZW4gaWYgbWFsZm9ybWVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoKHJvdykgPT4gcm93LnN0YXJ0c1dpdGgocGFneSArIFwiPVwiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/LnNwbGl0KFwiPVwiKVsxXSA/PyByYW5kS2V5KCk7XG4gICAgZG9jdW1lbnQuY29va2llICA9IGAke3BhZ3l9PSR7YnJvd3NlcktleX1gOyAgLy8gU21hbGxlciAubWluIHNpemU6IHNldCB0aGUgY29va2llIHdpdGhvdXQgY2hlY2tpbmdcbiAgICBpZiAoc3RvcmFnZUtleSAmJiAhKHN0b3JhZ2VLZXkgaW4gc3RvcmFnZSkpIHtcbiAgICAgIC8vIFN5bmMgdGhlIHNlc3Npb25nU3RvcmFnZSBmcm9tIG90aGVyIHRhYnMvd2luZG93cyAoZS5nLiwgb3BlbiBwYWdlIGluIHRoZSBuZXcgdGFiL3dpbmRvdylcbiAgICAgIHN5bmMucG9zdE1lc3NhZ2UoPFN5bmNEYXRhPnsgZnJvbTogdGFiSWQsIGtleTogc3RvcmFnZUtleSB9KTtcbiAgICAgIC8vIFdhaXQgZm9yIHRoZSBsaXN0ZW5lciB0byBjb3B5IHRoZSBjdXRvZmZzIGluIHRoZSBjdXJyZW50IHNlc3Npb25TdG9yYWdlXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTxzdHJpbmd8bnVsbD4oKHJlc29sdmUpID0+IHNldFRpbWVvdXQoKCkgPT4geyByZXNvbHZlKFwiXCIpIH0sIDEwMCkpO1xuICAgICAgaWYgKCEoc3RvcmFnZUtleSBpbiBzdG9yYWdlKSkgeyAvLyB0aGUgc3RvcmFnZUtleSBkaWRuJ3QgZ2V0IGNvcGllZDogZmFsbGJhY2sgdG8gY291bnRsZXNzIHBhZ2luYXRpb25cbiAgICAgICAgYXVnbWVudFBhZ2UgPSAocGFnZTogc3RyaW5nKSA9PiBgJHtwYWdlfSske1N0cmluZyhsYXN0KX1gOyAgICAgIH1cbiAgICB9XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBJZiBpdCBpcyBub3QgYXNzaWduZWQgaXQgbWVhbnMgaXQgc3VwcG9ydHMga2V5bmF2XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb25cbiAgICBpZiAoIWF1Z21lbnRQYWdlKSB7IC8vIHJlZ3VsYXIga2V5bmF2IHBhZ2luYXRpb25cbiAgICAgIGlmICghc3RvcmFnZUtleSkgeyBkbyB7IHN0b3JhZ2VLZXkgPSByYW5kS2V5KCkgfSB3aGlsZSAoc3RvcmFnZUtleSBpbiBzdG9yYWdlKSB9IC8vIG5vIGR1cCBrZXlzXG4gICAgICBjb25zdCBkYXRhID0gc3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpLFxuICAgICAgICAgIGN1dG9mZnMgPSA8Q3V0b2ZmW10+KGRhdGEgPyBKU09OLnBhcnNlKGRhdGEpIDogW3VuZGVmaW5lZF0pO1xuICAgICAgaWYgKHNwbGljZUFyZ3MpIHtcbiAgICAgICAgY3V0b2Zmcy5zcGxpY2UoLi4uc3BsaWNlQXJncyk7XG4gICAgICAgIHN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeShjdXRvZmZzKSk7XG4gICAgICB9XG4gICAgICAvLyBBdWdtZW50IGZ1bmN0aW9uXG4gICAgICBhdWdtZW50UGFnZSA9IChwYWdlOnN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBwYWdlTnVtID0gcGFyc2VJbnQocGFnZSk7XG4gICAgICAgIHJldHVybiBCNjRTYWZlRW5jb2RlKEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgPEF1Z21lbnRlZFBhZ2U+W2Jyb3dzZXJLZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZUtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTnVtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1dG9mZnMubGVuZ3RoLCAgICAgICAvLyBwYWdlcy9sYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3V0b2Zmc1twYWdlTnVtIC0gMV0sIC8vIHByaW9yQ3V0b2ZmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3V0b2Zmc1twYWdlTnVtXV0pKTsgIC8vIHBhZ2VDdXRvZmZcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHNlYXJjaCA9IChyb290S2V5KSA/IGAke3Jvb3RLZXl9JTVCJHtwYWdlS2V5fSU1RGAgOiBwYWdlS2V5O1xuICAgIGNvbnN0IHJlICAgICA9IG5ldyBSZWdFeHAoYCg/PD1cXFxcPy4qKShcXFxcYiR7c2VhcmNofT0pKFxcXFxkKylgKTtcbiAgICAvLyBBdWdtZW50IHRoZSBwYWdlIHBhcmFtIG9mIGVhY2ggaHJlZlxuICAgIGZvciAoY29uc3QgYSBvZiA8Tm9kZUxpc3RPZjxIVE1MQW5jaG9yRWxlbWVudD4+PHVua25vd24+bmF2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZl0nKSkge1xuICAgICAgYS5ocmVmID0gYS5ocmVmLnJlcGxhY2UocmUsIChfbWF0Y2gsIHByZWZpeCwgZGlnaXQpOiBzdHJpbmcgPT4gYCR7U3RyaW5nKHByZWZpeCl9JHthdWdtZW50UGFnZSg8c3RyaW5nPmRpZ2l0KX1gKTtcbiAgICB9XG4gICAgLy8gUmV0dXJuIHRoZSBhdWdtZW50IGZ1bmN0aW9uIGZvciBmdXJ0aGVyIGF1Z21lbnRhdGlvbiAoaS5lLiwgdXJsIHRva2VuIGluIGlucHV0X25hdl9qcylcbiAgICByZXR1cm4gYXVnbWVudFBhZ2U7XG4gIH07XG5cbiAgLy8gQnVpbGQgdGhlIHNlcmllc19uYXZfanMgaGVscGVyXG4gIGNvbnN0IGJ1aWxkTmF2SnMgPSAobmF2Ok5hdkpzRWxlbWVudCwgW1tiZWZvcmUsIGFuY2hvciwgY3VycmVudCwgZ2FwLCBhZnRlcl0sIHBhZ2VUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbd2lkdGhzLCBzZXJpZXMsIGxhYmVsc10sIGtleW5hdkFyZ3NdOlNlcmllc05hdkpzQXJncykgPT4ge1xuICAgIGxldCBsYXN0V2lkdGggPSAtMTtcbiAgICBjb25zdCBwYXJlbnQgID0gPEhUTUxFbGVtZW50Pm5hdi5wYXJlbnRFbGVtZW50O1xuXG4gICAgbmF2LnJlbmRlciA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gd2lkdGhzLmZpbmRJbmRleCh3ID0+IHcgPCBwYXJlbnQuY2xpZW50V2lkdGgpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSB8fCB3aWR0aHNbaW5kZXhdID09PSBsYXN0V2lkdGgpIHsgcmV0dXJuIH1cblxuICAgICAgbGV0IGh0bWwgPSBiZWZvcmU7XG4gICAgICBzZXJpZXNbaW5kZXhdLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgLy8gQXZvaWQgdGhlIGlmIGJsb2NrcyBhbmQgY2hhaW4gdGhlIHJlc3VsdHMgKHNob3J0ZXIgcGFneS5taW4uanMgYW5kIGVhc2llciByZWFkaW5nKVxuICAgICAgICBodG1sICs9IGl0ZW0gPT0gXCJnYXBcIiA/IGdhcCA6XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGUgaXRlbSBtYXkgYmUgYSBudW1iZXIsIGJ1dCB0aGUgJ3JlcGxhY2UnIGNvbnZlcnRzIGl0IHRvIHN0cmluZyAoc2hvcnRlciBwYWd5Lm1pbi5qcylcbiAgICAgICAgICAgICAgICAodHlwZW9mIGl0ZW0gPT0gXCJudW1iZXJcIiA/IGFuY2hvci5yZXBsYWNlKHBhZ2VUb2tlbiwgaXRlbSkgOiBjdXJyZW50KVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShcIkw8XCIsIGxhYmVscz8uW2luZGV4XVtpXSA/PyBgJHtTdHJpbmcoaXRlbSl9PGApO1xuICAgICAgfSk7XG4gICAgICBodG1sICAgICAgICAgKz0gYWZ0ZXI7XG4gICAgICBuYXYuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgIG5hdi5pbnNlcnRBZGphY2VudEhUTUwoXCJhZnRlcmJlZ2luXCIsIGh0bWwpO1xuICAgICAgbGFzdFdpZHRoID0gd2lkdGhzW2luZGV4XTtcbiAgICAgIGlmIChrZXluYXZBcmdzICYmIHN0b3JhZ2VTdXBwb3J0KSB7IHZvaWQgYXVnbWVudEtleW5hdihuYXYsIGtleW5hdkFyZ3MpIH1cbiAgICB9O1xuXG4gICAgcmpzT2JzZXJ2ZXIub2JzZXJ2ZShwYXJlbnQpO1xuICB9O1xuXG4gIC8vIEluaXQgdGhlIGlucHV0X25hdl9qcyBoZWxwZXJzXG4gIGNvbnN0IGluaXRJbnB1dE5hdkpzID0gYXN5bmMgKG5hdjpIVE1MRWxlbWVudCwgW3VybF90b2tlbiwgcGFnZVRva2VuLCBrZXluYXZBcmdzXTpJbnB1dE5hdkpzQXJncykgPT4ge1xuICAgIGNvbnN0IGF1Z21lbnQgPSBrZXluYXZBcmdzICYmIHN0b3JhZ2VTdXBwb3J0XG4gICAgICAgICAgICAgICAgICAgID8gYXdhaXQgYXVnbWVudEtleW5hdihuYXYsIGtleW5hdkFyZ3MpXG4gICAgICAgICAgICAgICAgICAgIDogKHBhZ2U6IHN0cmluZykgPT4gcGFnZTtcbiAgICBpbml0SW5wdXQobmF2LCBpbnB1dFZhbHVlID0+IHVybF90b2tlbi5yZXBsYWNlKHBhZ2VUb2tlbiwgYXVnbWVudChpbnB1dFZhbHVlKSkpO1xuICB9O1xuXG4gIC8vIEluaXQgdGhlIGxpbWl0X3RhZ19qcyBoZWxwZXJcbiAgY29uc3QgaW5pdExpbWl0VGFnSnMgPSAoc3BhbjpIVE1MU3BhbkVsZW1lbnQsIFtmcm9tLCB1cmxfdG9rZW4sIHBhZ2VfdG9rZW4sIGxpbWl0VG9rZW5dOkxpbWl0VGFnSnNBcmdzKSA9PiB7XG4gICAgaW5pdElucHV0KHNwYW4sIGlucHV0VmFsdWUgPT4ge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGUgcGFnZSBpcyBhIG51bWJlciwgYnV0IHRoZSAncmVwbGFjZScgY29udmVydHMgaXQgdG8gc3RyaW5nIChzaG9ydGVyIHBhZ3kubWluLmpzKVxuICAgICAgcmV0dXJuIHVybF90b2tlbi5yZXBsYWNlKHBhZ2VfdG9rZW4sIE1hdGgubWF4KE1hdGguY2VpbChmcm9tIC8gcGFyc2VJbnQoaW5wdXRWYWx1ZSkpLCAxKSlcbiAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShsaW1pdFRva2VuLCBpbnB1dFZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBJbml0IHRoZSBpbnB1dCBlbGVtZW50XG4gIGNvbnN0IGluaXRJbnB1dCA9IChlbGVtZW50OkhUTUxFbGVtZW50LCBnZXRVcmw6KHY6c3RyaW5nKSA9PiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBpbnB1dCAgID0gPEhUTUxJbnB1dEVsZW1lbnQ+ZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiaW5wdXRcIiksXG4gICAgICAgICAgbGluayAgICA9IDxIVE1MQW5jaG9yRWxlbWVudD5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJhXCIpO1xuICAgIGxldCAgIGluaXRpYWwgPSBpbnB1dC52YWx1ZTtcbiAgICBjb25zdCBhY3Rpb24gID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC52YWx1ZSA9PT0gaW5pdGlhbCkgeyByZXR1cm4gfSAgLy8gbm90IGNoYW5nZWRcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBbbWluLCB2YWwsIG1heF0gPSBbaW5wdXQubWluLCBpbnB1dC52YWx1ZSwgaW5wdXQubWF4XS5tYXAobiA9PiBwYXJzZUludChuKSB8fCAwKTtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsIDwgbWluIHx8IHZhbCA+IG1heCkgeyAgLy8gcmVzZXQgaW52YWxpZC9vdXQtb2YtcmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnZhbHVlID0gaW5pdGlhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnNlbGVjdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsICAgPSBpbnB1dC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICBsaW5rLmhyZWYgPSBnZXRVcmwoaW5wdXQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgIGxpbmsuY2xpY2soKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKCkgPT4geyBpbnB1dC5zZWxlY3QoKSB9KTtcbiAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNvdXRcIiwgYWN0aW9uKTtcbiAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwia2V5cHJlc3NcIiwgZSA9PiB7IGlmIChlLmtleSA9PSBcIkVudGVyXCIpIHsgYWN0aW9uKCkgfSB9KTtcbiAgfTtcblxuICAvLyBQdWJsaWMgaW50ZXJmYWNlXG4gIHJldHVybiB7XG4gICAgdmVyc2lvbjogXCI0My42LjJcIixcblxuICAgIC8vIFNjYW4gZm9yIGVsZW1lbnRzIHdpdGggYSBcImRhdGEtcGFneVwiIGF0dHJpYnV0ZSBhbmQgY2FsbCB0aGVpciBpbml0IGZ1bmN0aW9ucyB3aXRoIHRoZSBkZWNvZGVkIGFyZ3NcbiAgICBpbml0KGFyZz86SFRNTEVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGFyZyBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ID8gYXJnIDogZG9jdW1lbnQsXG4gICAgICAgICAgICBlbGVtZW50cyA9IHRhcmdldC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtcGFneV1cIik7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgPE5vZGVMaXN0T2Y8SFRNTEVsZW1lbnQ+PmVsZW1lbnRzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgW2hlbHBlcklkLCAuLi5hcmdzXSA9IDxJbml0QXJncz5KU09OLnBhcnNlKEI2NERlY29kZSg8c3RyaW5nPmVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1wYWd5XCIpKSk7XG4gICAgICAgICAgaWYgKGhlbHBlcklkID09IFwia1wiKSB7XG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHNwcmVhZCAyIGFyZ3VtZW50cywgbm90IDMgYXMgaXQgY29tcGxhaW5zIGFib3V0XG4gICAgICAgICAgICB2b2lkIGF1Z21lbnRLZXluYXYoZWxlbWVudCwgLi4uPEtleW5hdkFyZ3M+PHVua25vd24+YXJncyk7XG4gICAgICAgICAgfSBlbHNlIGlmIChoZWxwZXJJZCA9PSBcInNualwiKSB7XG4gICAgICAgICAgICBidWlsZE5hdkpzKDxOYXZKc0VsZW1lbnQ+ZWxlbWVudCwgPFNlcmllc05hdkpzQXJncz48dW5rbm93bj5hcmdzKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGhlbHBlcklkID09IFwiaW5qXCIpIHtcbiAgICAgICAgICAgIHZvaWQgaW5pdElucHV0TmF2SnMoZWxlbWVudCwgPElucHV0TmF2SnNBcmdzPjx1bmtub3duPmFyZ3MpO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb25cbiAgICAgICAgICB9IGVsc2UgaWYgKGhlbHBlcklkID09IFwibHRqXCIpIHtcbiAgICAgICAgICAgIGluaXRMaW1pdFRhZ0pzKGVsZW1lbnQsIDxMaW1pdFRhZ0pzQXJncz48dW5rbm93bj5hcmdzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZWxzZSB7IGNvbnNvbGUud2FybihcIlBhZ3kuaW5pdDogJW9cXG5Vbmtub3duIGhlbHBlcklkICclcydcIiwgZWxlbWVudCwgaGVscGVySWQpIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7IGNvbnNvbGUud2FybihcIlBhZ3kuaW5pdDogJW9cXG4lc1wiLCBlbGVtZW50LCBlcnIpIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59KSgpO1xuIiwKICAgICJpbXBvcnQgUGFneSBmcm9tIFwiLi9wYWd5LnRzXCJcbndpbmRvdy5QYWd5ID0gUGFneVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjtBQWdEQSxJQUFnQixzQkFBTTtBQUFBLEVBQ3BCLE1BQU0saUJBQWlCLG9CQUFvQixVQUFVLHNCQUFzQjtBQUFBLEVBRTNFLElBQUksT0FBTyxRQUFRLFNBQWtCLE1BQXdCO0FBQUEsRUFDN0QsSUFBSSxnQkFBZ0I7QUFBQSxJQUNsQixVQUFVO0FBQUEsSUFDVixPQUFVLElBQUksaUJBQWlCLElBQUk7QUFBQSxJQUNuQyxRQUFVLEtBQUssSUFBSTtBQUFBLElBR25CLEtBQUssaUJBQWlCLFdBQVcsQ0FBQyxNQUE2QjtBQUFBLE1BQzdELElBQUksRUFBRSxL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
|
|
165
|
+
//# debugId=EE64B5BD0D317BA664756E2164756E21
|
|
166
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsicGFneS50cyIsICJwYWd5LXNoaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiaW50ZXJmYWNlIFN5bmNEYXRhIHtcbiAgZnJvbT86IG51bWJlclxuICB0bz8gIDogbnVtYmVyXG4gIGtleSAgOiBzdHJpbmdcbiAgc3RyPyA6IHN0cmluZ1xufVxudHlwZSBJbml0QXJncyA9IFtcImtcIiwgIEtleW5hdkFyZ3NdIHwgICAgICAgICAgLy8gc2VyaWVzX25hdltfanNdIHdpdGgga2V5bmF2IGluc3RhbmNlXG4gICAgICAgICAgICAgICAgW1wic25qXCIsIFNlcmllc05hdkpzQXJnc10gfCAgICAvLyBzZXJpZXNfbmF2X2pzXG4gICAgICAgICAgICAgICAgW1wiaW5qXCIsIElucHV0TmF2SnNBcmdzXSB8ICAgICAvLyBpbnB1dF9uYXZfanNcbiAgICAgICAgICAgICAgICBbXCJsdGpcIiwgTGltaXRUYWdKc0FyZ3NdOyAgICAgIC8vIGxpbWl0X3RhZ19qc1xudHlwZSBBdWdtZW50S2V5bmF2ID0gKG5hdjpIVE1MRWxlbWVudCwga2V5bmF2QXJnczpLZXluYXZBcmdzKSA9PiBQcm9taXNlPCgocGFnZTogc3RyaW5nKSA9PiBzdHJpbmcpPjtcbnR5cGUgS2V5bmF2QXJncyA9IHJlYWRvbmx5IFtzdG9yYWdlS2V5IDogc3RyaW5nIHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290S2V5ICAgIDogc3RyaW5nIHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlS2V5ICAgIDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3QgICAgICAgOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaWNlQXJncz86IFNwbGljZUFyZ3NdO1xudHlwZSBTcGxpY2VBcmdzID0gcmVhZG9ubHkgW3N0YXJ0ICAgICAgOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlQ291bnQ6IG51bWJlciwgICAgIC8vIGl0IHdvdWxkIGJlIG9wdGlvbmFsLCBidXQgdHMgY29tcGxhaW5zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uaXRlbXM6ICAgIEN1dG9mZltdXTtcbnR5cGUgQ3V0b2ZmID0gcmVhZG9ubHkgKHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4pW107XG50eXBlIEF1Z21lbnRlZFBhZ2UgPSBbYnJvd3NlcklkICA6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICBzdG9yYWdlS2V5IDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgIHBhZ2VOdW1iZXIgOiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgcGFnZXMgICAgICA6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICBwcmlvckN1dG9mZjogQ3V0b2ZmIHwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICBwYWdlQ3V0b2ZmIDogQ3V0b2ZmIHwgbnVsbF07XG50eXBlIFNlcmllc05hdkpzQXJncyA9IHJlYWRvbmx5IFtOYXZKc1Rva2VucywgcGFnZVRva2VuOiBzdHJpbmcsIE5hdkpzU2VyaWVzLCBLZXluYXZBcmdzP107XG50eXBlIE5hdkpzU2VyaWVzID0gcmVhZG9ubHkgW3dpZHRoczogbnVtYmVyW10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmllczogKHN0cmluZyB8IG51bWJlcilbXVtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM6IHN0cmluZ1tdW10gfCBudWxsXTtcbnR5cGUgSW5wdXROYXZKc0FyZ3MgPSByZWFkb25seSBbdXJsVG9rZW46ICBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VUb2tlbjogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXluYXZBcmdzP107XG50eXBlIExpbWl0VGFnSnNBcmdzID0gcmVhZG9ubHkgW2Zyb20gICAgICA6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsVG9rZW4gIDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlVG9rZW4gOiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0VG9rZW46IHN0cmluZ107XG50eXBlIE5hdkpzVG9rZW5zID0gcmVhZG9ubHkgW2JlZm9yZSA6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yIDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhcCAgICA6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXIgIDogc3RyaW5nXTtcbmludGVyZmFjZSBOYXZKc0VsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gIHJlbmRlcigpOiB2b2lkXG59XG5cbi8vIFRoZSBzeW50YXggdXNlZCBpbiB0aGlzIGZpbGUgaGFzIGJlZW4gY2FyZWZ1bGx5IGNvbXBvc2VkIHRvIG1pbmltaXplXG4vLyB0aGUgcGFneS5taW4uanMgc2l6ZSBhbmQgYXZvaWQgcG9sbHV0aW9uIGluIHRoZSB3aW5kb3cgb2JqZWN0LlxuZXhwb3J0IGRlZmF1bHQgKCgpID0+IHtcbiAgY29uc3Qgc3RvcmFnZVN1cHBvcnQgPSAnc2Vzc2lvblN0b3JhZ2UnIGluIHdpbmRvdyAmJiAnQnJvYWRjYXN0Q2hhbm5lbCcgaW4gd2luZG93O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gIGxldCBwYWd5ID0gXCJwYWd5XCIsIHN0b3JhZ2U6IFN0b3JhZ2UsIHN5bmM6IEJyb2FkY2FzdENoYW5uZWwsIHRhYklkOiBudW1iZXI7XG4gIGlmIChzdG9yYWdlU3VwcG9ydCkge1xuICAgIHN0b3JhZ2UgPSBzZXNzaW9uU3RvcmFnZTsgLy8gc2hvcnRlbiB0aGUgY29tcGlsZWQgc2l6ZVxuICAgIHN5bmMgICAgPSBuZXcgQnJvYWRjYXN0Q2hhbm5lbChwYWd5KTtcbiAgICB0YWJJZCAgID0gRGF0ZS5ub3coKTtcblxuICAgIC8vIFN5bmMgdGhlIHNlc3Npb25TdG9yYWdlIGtleXMgZm9yIHRoZSBjdXRvZmZzIG9wZW5lZCBpbiBhIG5ldyB0YWIvd2luZG93XG4gICAgc3luYy5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCAoZTpNZXNzYWdlRXZlbnQ8U3luY0RhdGE+KSA9PiB7XG4gICAgICBpZiAoZS5kYXRhLmZyb20pIHsgLy8gcmVxdWVzdCBjdXRvZmZzXG4gICAgICAgIGNvbnN0IGN1dG9mZnMgPSBzdG9yYWdlLmdldEl0ZW0oZS5kYXRhLmtleSk7XG4gICAgICAgIGlmIChjdXRvZmZzKSB7XG4gICAgICAgICAgc3luYy5wb3N0TWVzc2FnZSg8U3luY0RhdGE+e3RvOiBlLmRhdGEuZnJvbSwga2V5OiBlLmRhdGEua2V5LCBzdHI6IGN1dG9mZnN9KTtcbiAgICAgICAgfSAvLyBzZW5kIHJlc3BvbnNlXG4gICAgICB9IGVsc2UgaWYgKGUuZGF0YS50bykgeyAgLy8gcmVjZWl2ZSBjdXRvZmZzXG4gICAgICAgIGlmIChlLmRhdGEudG8gPT0gdGFiSWQpIHtcbiAgICAgICAgICBzdG9yYWdlLnNldEl0ZW0oZS5kYXRhLmtleSwgPHN0cmluZz5lLmRhdGEuc3RyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8vIFRoZSBvYnNlcnZlciBpbnN0YW5jZSBmb3IgcmVzcG9uc2l2ZSBuYXZzXG4gIGNvbnN0IHJqc09ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgIGVudHJpZXMuZm9yRWFjaChlID0+IHtcbiAgICAgIGUudGFyZ2V0LnF1ZXJ5U2VsZWN0b3JBbGw8TmF2SnNFbGVtZW50PihcIi5zZXJpZXMtbmF2LWpzXCIpLmZvckVhY2goZWwgPT4ge1xuICAgICAgICBlbC5yZW5kZXIoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvKiBGdWxsIHNldCBvZiBCNjQgZnVuY3Rpb25zXG4gIGNvbnN0IEI2NEVuY29kZSAgICAgPSAodW5pY29kZTpzdHJpbmcpID0+IGJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4obmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodW5pY29kZSkpKSxcbiAgICAgICAgQjY0U2FmZSAgICAgICA9ICh1bnNhZmU6c3RyaW5nKSAgPT4gdW5zYWZlLnJlcGxhY2UoL1srLz1dL2csIChtKSA9PiBtID09IFwiK1wiID8gXCItXCIgOiBtID09IFwiL1wiID8gXCJfXCIgOiBcIlwiKSxcbiAgICAgICAgQjY0U2FmZUVuY29kZSA9ICh1bmljb2RlOnN0cmluZykgPT4gQjY0U2FmZShCNjRFbmNvZGUodW5pY29kZSkpLFxuICAgICAgICBCNjREZWNvZGUgICAgID0gKGJhc2U2NDpzdHJpbmcpICA9PiAobmV3IFRleHREZWNvZGVyKCkpLmRlY29kZShVaW50OEFycmF5LmZyb20oYXRvYihiYXNlNjQpLCBjID0+IGMuY2hhckNvZGVBdCgwKSkpLFxuICAgICAgICBCNjRVbnNhZmUgICAgID0gKHNhZmU6c3RyaW5nKSAgICA9PiBzYWZlLnJlcGxhY2UoL1stX10vZywgKG1hdGNoKSA9PiBtYXRjaCA9PSBcIi1cIiA/IFwiK1wiIDogXCIvXCIpLFxuICAgICAgICBCNjRTYWZlRGVjb2RlID0gKGJhc2U2NDpzdHJpbmcpICA9PiBCNjREZWNvZGUoQjY0VW5zYWZlKGJhc2U2NCkpXG4gICovXG4gIGNvbnN0IEI2NFNhZmVFbmNvZGUgPSAodW5pY29kZTpzdHJpbmcpID0+IGJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4obmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodW5pY29kZSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1srLz1dL2csIChtKSA9PiBtID09IFwiK1wiID8gXCItXCIgOiBtID09IFwiL1wiID8gXCJfXCIgOiBcIlwiKSxcbiAgICAgICAgQjY0RGVjb2RlICAgICA9IChiYXNlNjQ6c3RyaW5nKSAgPT4gKG5ldyBUZXh0RGVjb2RlcigpKS5kZWNvZGUoVWludDhBcnJheS5mcm9tKGF0b2IoYmFzZTY0KSwgYyA9PiBjLmNoYXJDb2RlQXQoMCkpKTtcblxuICAvLyBSZXR1cm4gYSByYW5kb20ga2V5OiAzIGNoYXJzIG1heCwgYmFzZS0zNiBudW1iZXIgPCAzNioqM1xuICBjb25zdCByYW5kS2V5ID0gKCkgPT4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMzYgKiogMykudG9TdHJpbmcoMzYpO1xuXG4gIC8vIE1hbmFnZSB0aGUgcGFnZSBhdWdtZW50YXRpb24gZm9yIEtleW5hdiwgY2FsbGVkIG9ubHkgaWYgc3RvcmFnZVN1cHBvcnRcbiAgY29uc3QgYXVnbWVudEtleW5hdjogQXVnbWVudEtleW5hdiA9IGFzeW5jIChuYXYsIFtzdG9yYWdlS2V5LCByb290S2V5LCBwYWdlS2V5LCBsYXN0LCBzcGxpY2VBcmdzXSkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBhbGlnbi1hc3NpZ25tZW50cy9hbGlnbi1hc3NpZ25tZW50c1xuICAgIGxldCBhdWdtZW50UGFnZTogKHBhZ2U6IHN0cmluZykgPT4gc3RyaW5nO1xuICAgIGNvbnN0IGJyb3dzZXJLZXkgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoLztcXHMrLykgIC8vIGl0IHdvcmtzIGV2ZW4gaWYgbWFsZm9ybWVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoKHJvdykgPT4gcm93LnN0YXJ0c1dpdGgocGFneSArIFwiPVwiKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/LnNwbGl0KFwiPVwiKVsxXSA/PyByYW5kS2V5KCk7XG4gICAgZG9jdW1lbnQuY29va2llICA9IGAke3BhZ3l9PSR7YnJvd3NlcktleX1gOyAgLy8gU21hbGxlciAubWluIHNpemU6IHNldCB0aGUgY29va2llIHdpdGhvdXQgY2hlY2tpbmdcbiAgICBpZiAoc3RvcmFnZUtleSAmJiAhKHN0b3JhZ2VLZXkgaW4gc3RvcmFnZSkpIHtcbiAgICAgIC8vIFN5bmMgdGhlIHNlc3Npb25nU3RvcmFnZSBmcm9tIG90aGVyIHRhYnMvd2luZG93cyAoZS5nLiwgb3BlbiBwYWdlIGluIHRoZSBuZXcgdGFiL3dpbmRvdylcbiAgICAgIHN5bmMucG9zdE1lc3NhZ2UoPFN5bmNEYXRhPnsgZnJvbTogdGFiSWQsIGtleTogc3RvcmFnZUtleSB9KTtcbiAgICAgIC8vIFdhaXQgZm9yIHRoZSBsaXN0ZW5lciB0byBjb3B5IHRoZSBjdXRvZmZzIGluIHRoZSBjdXJyZW50IHNlc3Npb25TdG9yYWdlXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTxzdHJpbmd8bnVsbD4oKHJlc29sdmUpID0+IHNldFRpbWVvdXQoKCkgPT4geyByZXNvbHZlKFwiXCIpIH0sIDEwMCkpO1xuICAgICAgaWYgKCEoc3RvcmFnZUtleSBpbiBzdG9yYWdlKSkgeyAvLyB0aGUgc3RvcmFnZUtleSBkaWRuJ3QgZ2V0IGNvcGllZDogZmFsbGJhY2sgdG8gY291bnRsZXNzIHBhZ2luYXRpb25cbiAgICAgICAgYXVnbWVudFBhZ2UgPSAocGFnZTogc3RyaW5nKSA9PiBgJHtwYWdlfSske1N0cmluZyhsYXN0KX1gOyAgICAgIH1cbiAgICB9XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBJZiBpdCBpcyBub3QgYXNzaWduZWQgaXQgbWVhbnMgaXQgc3VwcG9ydHMga2V5bmF2XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb25cbiAgICBpZiAoIWF1Z21lbnRQYWdlKSB7IC8vIHJlZ3VsYXIga2V5bmF2IHBhZ2luYXRpb25cbiAgICAgIGlmICghc3RvcmFnZUtleSkgeyBkbyB7IHN0b3JhZ2VLZXkgPSByYW5kS2V5KCkgfSB3aGlsZSAoc3RvcmFnZUtleSBpbiBzdG9yYWdlKSB9IC8vIG5vIGR1cCBrZXlzXG4gICAgICBjb25zdCBkYXRhID0gc3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpLFxuICAgICAgICAgIGN1dG9mZnMgPSA8Q3V0b2ZmW10+KGRhdGEgPyBKU09OLnBhcnNlKGRhdGEpIDogW3VuZGVmaW5lZF0pO1xuICAgICAgaWYgKHNwbGljZUFyZ3MpIHtcbiAgICAgICAgY3V0b2Zmcy5zcGxpY2UoLi4uc3BsaWNlQXJncyk7XG4gICAgICAgIHN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeShjdXRvZmZzKSk7XG4gICAgICB9XG4gICAgICAvLyBBdWdtZW50IGZ1bmN0aW9uXG4gICAgICBhdWdtZW50UGFnZSA9IChwYWdlOnN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBwYWdlTnVtID0gcGFyc2VJbnQocGFnZSk7XG4gICAgICAgIHJldHVybiBCNjRTYWZlRW5jb2RlKEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgPEF1Z21lbnRlZFBhZ2U+W2Jyb3dzZXJLZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZUtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTnVtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1dG9mZnMubGVuZ3RoLCAgICAgICAvLyBwYWdlcy9sYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3V0b2Zmc1twYWdlTnVtIC0gMV0sIC8vIHByaW9yQ3V0b2ZmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3V0b2Zmc1twYWdlTnVtXV0pKTsgIC8vIHBhZ2VDdXRvZmZcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHNlYXJjaCA9IChyb290S2V5KSA/IGAke3Jvb3RLZXl9JTVCJHtwYWdlS2V5fSU1RGAgOiBwYWdlS2V5O1xuICAgIGNvbnN0IHJlICAgICA9IG5ldyBSZWdFeHAoYCg/PD1cXFxcPy4qKShcXFxcYiR7c2VhcmNofT0pKFxcXFxkKylgKTtcbiAgICAvLyBBdWdtZW50IHRoZSBwYWdlIHBhcmFtIG9mIGVhY2ggaHJlZlxuICAgIGZvciAoY29uc3QgYSBvZiA8Tm9kZUxpc3RPZjxIVE1MQW5jaG9yRWxlbWVudD4+PHVua25vd24+bmF2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZl0nKSkge1xuICAgICAgYS5ocmVmID0gYS5ocmVmLnJlcGxhY2UocmUsIChfbWF0Y2gsIHByZWZpeCwgZGlnaXQpOiBzdHJpbmcgPT4gYCR7U3RyaW5nKHByZWZpeCl9JHthdWdtZW50UGFnZSg8c3RyaW5nPmRpZ2l0KX1gKTtcbiAgICB9XG4gICAgLy8gUmV0dXJuIHRoZSBhdWdtZW50IGZ1bmN0aW9uIGZvciBmdXJ0aGVyIGF1Z21lbnRhdGlvbiAoaS5lLiwgdXJsIHRva2VuIGluIGlucHV0X25hdl9qcylcbiAgICByZXR1cm4gYXVnbWVudFBhZ2U7XG4gIH07XG5cbiAgLy8gQnVpbGQgdGhlIHNlcmllc19uYXZfanMgaGVscGVyXG4gIGNvbnN0IGJ1aWxkTmF2SnMgPSAobmF2Ok5hdkpzRWxlbWVudCwgW1tiZWZvcmUsIGFuY2hvciwgY3VycmVudCwgZ2FwLCBhZnRlcl0sIHBhZ2VUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbd2lkdGhzLCBzZXJpZXMsIGxhYmVsc10sIGtleW5hdkFyZ3NdOlNlcmllc05hdkpzQXJncykgPT4ge1xuICAgIGxldCBsYXN0V2lkdGggPSAtMTtcbiAgICBjb25zdCBwYXJlbnQgID0gPEhUTUxFbGVtZW50Pm5hdi5wYXJlbnRFbGVtZW50O1xuXG4gICAgbmF2LnJlbmRlciA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gd2lkdGhzLmZpbmRJbmRleCh3ID0+IHcgPCBwYXJlbnQuY2xpZW50V2lkdGgpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSB8fCB3aWR0aHNbaW5kZXhdID09PSBsYXN0V2lkdGgpIHsgcmV0dXJuIH1cblxuICAgICAgbGV0IGh0bWwgPSBiZWZvcmU7XG4gICAgICBzZXJpZXNbaW5kZXhdLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgLy8gQXZvaWQgdGhlIGlmIGJsb2NrcyBhbmQgY2hhaW4gdGhlIHJlc3VsdHMgKHNob3J0ZXIgcGFneS5taW4uanMgYW5kIGVhc2llciByZWFkaW5nKVxuICAgICAgICBodG1sICs9IGl0ZW0gPT0gXCJnYXBcIiA/IGdhcCA6XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGUgaXRlbSBtYXkgYmUgYSBudW1iZXIsIGJ1dCB0aGUgJ3JlcGxhY2UnIGNvbnZlcnRzIGl0IHRvIHN0cmluZyAoc2hvcnRlciBwYWd5Lm1pbi5qcylcbiAgICAgICAgICAgICAgICAodHlwZW9mIGl0ZW0gPT0gXCJudW1iZXJcIiA/IGFuY2hvci5yZXBsYWNlKHBhZ2VUb2tlbiwgaXRlbSkgOiBjdXJyZW50KVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShcIkw8XCIsIGxhYmVscz8uW2luZGV4XVtpXSA/PyBgJHtTdHJpbmcoaXRlbSl9PGApO1xuICAgICAgfSk7XG4gICAgICBodG1sICAgICAgICAgKz0gYWZ0ZXI7XG4gICAgICBuYXYuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgIG5hdi5pbnNlcnRBZGphY2VudEhUTUwoXCJhZnRlcmJlZ2luXCIsIGh0bWwpO1xuICAgICAgbGFzdFdpZHRoID0gd2lkdGhzW2luZGV4XTtcbiAgICAgIGlmIChrZXluYXZBcmdzICYmIHN0b3JhZ2VTdXBwb3J0KSB7IHZvaWQgYXVnbWVudEtleW5hdihuYXYsIGtleW5hdkFyZ3MpIH1cbiAgICB9O1xuXG4gICAgcmpzT2JzZXJ2ZXIub2JzZXJ2ZShwYXJlbnQpO1xuICB9O1xuXG4gIC8vIEluaXQgdGhlIGlucHV0X25hdl9qcyBoZWxwZXJzXG4gIGNvbnN0IGluaXRJbnB1dE5hdkpzID0gYXN5bmMgKG5hdjpIVE1MRWxlbWVudCwgW3VybF90b2tlbiwgcGFnZVRva2VuLCBrZXluYXZBcmdzXTpJbnB1dE5hdkpzQXJncykgPT4ge1xuICAgIGNvbnN0IGF1Z21lbnQgPSBrZXluYXZBcmdzICYmIHN0b3JhZ2VTdXBwb3J0XG4gICAgICAgICAgICAgICAgICAgID8gYXdhaXQgYXVnbWVudEtleW5hdihuYXYsIGtleW5hdkFyZ3MpXG4gICAgICAgICAgICAgICAgICAgIDogKHBhZ2U6IHN0cmluZykgPT4gcGFnZTtcbiAgICBpbml0SW5wdXQobmF2LCBpbnB1dFZhbHVlID0+IHVybF90b2tlbi5yZXBsYWNlKHBhZ2VUb2tlbiwgYXVnbWVudChpbnB1dFZhbHVlKSkpO1xuICB9O1xuXG4gIC8vIEluaXQgdGhlIGxpbWl0X3RhZ19qcyBoZWxwZXJcbiAgY29uc3QgaW5pdExpbWl0VGFnSnMgPSAoc3BhbjpIVE1MU3BhbkVsZW1lbnQsIFtmcm9tLCB1cmxfdG9rZW4sIHBhZ2VfdG9rZW4sIGxpbWl0VG9rZW5dOkxpbWl0VGFnSnNBcmdzKSA9PiB7XG4gICAgaW5pdElucHV0KHNwYW4sIGlucHV0VmFsdWUgPT4ge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGUgcGFnZSBpcyBhIG51bWJlciwgYnV0IHRoZSAncmVwbGFjZScgY29udmVydHMgaXQgdG8gc3RyaW5nIChzaG9ydGVyIHBhZ3kubWluLmpzKVxuICAgICAgcmV0dXJuIHVybF90b2tlbi5yZXBsYWNlKHBhZ2VfdG9rZW4sIE1hdGgubWF4KE1hdGguY2VpbChmcm9tIC8gcGFyc2VJbnQoaW5wdXRWYWx1ZSkpLCAxKSlcbiAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShsaW1pdFRva2VuLCBpbnB1dFZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBJbml0IHRoZSBpbnB1dCBlbGVtZW50XG4gIGNvbnN0IGluaXRJbnB1dCA9IChlbGVtZW50OkhUTUxFbGVtZW50LCBnZXRVcmw6KHY6c3RyaW5nKSA9PiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBpbnB1dCAgID0gPEhUTUxJbnB1dEVsZW1lbnQ+ZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiaW5wdXRcIiksXG4gICAgICAgICAgbGluayAgICA9IDxIVE1MQW5jaG9yRWxlbWVudD5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJhXCIpO1xuICAgIGxldCAgIGluaXRpYWwgPSBpbnB1dC52YWx1ZTtcbiAgICBjb25zdCBhY3Rpb24gID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC52YWx1ZSA9PT0gaW5pdGlhbCkgeyByZXR1cm4gfSAgLy8gbm90IGNoYW5nZWRcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBbbWluLCB2YWwsIG1heF0gPSBbaW5wdXQubWluLCBpbnB1dC52YWx1ZSwgaW5wdXQubWF4XS5tYXAobiA9PiBwYXJzZUludChuKSB8fCAwKTtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsIDwgbWluIHx8IHZhbCA+IG1heCkgeyAgLy8gcmVzZXQgaW52YWxpZC9vdXQtb2YtcmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnZhbHVlID0gaW5pdGlhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnNlbGVjdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsICAgPSBpbnB1dC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICBsaW5rLmhyZWYgPSBnZXRVcmwoaW5wdXQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgIGxpbmsuY2xpY2soKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKCkgPT4geyBpbnB1dC5zZWxlY3QoKSB9KTtcbiAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNvdXRcIiwgYWN0aW9uKTtcbiAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwia2V5cHJlc3NcIiwgZSA9PiB7IGlmIChlLmtleSA9PSBcIkVudGVyXCIpIHsgYWN0aW9uKCkgfSB9KTtcbiAgfTtcblxuICAvLyBQdWJsaWMgaW50ZXJmYWNlXG4gIHJldHVybiB7XG4gICAgdmVyc2lvbjogXCI0My43LjBcIixcblxuICAgIC8vIFNjYW4gZm9yIGVsZW1lbnRzIHdpdGggYSBcImRhdGEtcGFneVwiIGF0dHJpYnV0ZSBhbmQgY2FsbCB0aGVpciBpbml0IGZ1bmN0aW9ucyB3aXRoIHRoZSBkZWNvZGVkIGFyZ3NcbiAgICBpbml0KGFyZz86SFRNTEVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGFyZyBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ID8gYXJnIDogZG9jdW1lbnQsXG4gICAgICAgICAgICBlbGVtZW50cyA9IHRhcmdldC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtcGFneV1cIik7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgPE5vZGVMaXN0T2Y8SFRNTEVsZW1lbnQ+PmVsZW1lbnRzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgW2hlbHBlcklkLCAuLi5hcmdzXSA9IDxJbml0QXJncz5KU09OLnBhcnNlKEI2NERlY29kZSg8c3RyaW5nPmVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1wYWd5XCIpKSk7XG4gICAgICAgICAgaWYgKGhlbHBlcklkID09IFwia1wiKSB7XG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHNwcmVhZCAyIGFyZ3VtZW50cywgbm90IDMgYXMgaXQgY29tcGxhaW5zIGFib3V0XG4gICAgICAgICAgICB2b2lkIGF1Z21lbnRLZXluYXYoZWxlbWVudCwgLi4uPEtleW5hdkFyZ3M+PHVua25vd24+YXJncyk7XG4gICAgICAgICAgfSBlbHNlIGlmIChoZWxwZXJJZCA9PSBcInNualwiKSB7XG4gICAgICAgICAgICBidWlsZE5hdkpzKDxOYXZKc0VsZW1lbnQ+ZWxlbWVudCwgPFNlcmllc05hdkpzQXJncz48dW5rbm93bj5hcmdzKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGhlbHBlcklkID09IFwiaW5qXCIpIHtcbiAgICAgICAgICAgIHZvaWQgaW5pdElucHV0TmF2SnMoZWxlbWVudCwgPElucHV0TmF2SnNBcmdzPjx1bmtub3duPmFyZ3MpO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb25cbiAgICAgICAgICB9IGVsc2UgaWYgKGhlbHBlcklkID09IFwibHRqXCIpIHtcbiAgICAgICAgICAgIGluaXRMaW1pdFRhZ0pzKGVsZW1lbnQsIDxMaW1pdFRhZ0pzQXJncz48dW5rbm93bj5hcmdzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZWxzZSB7IGNvbnNvbGUud2FybihcIlBhZ3kuaW5pdDogJW9cXG5Vbmtub3duIGhlbHBlcklkICclcydcIiwgZWxlbWVudCwgaGVscGVySWQpIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7IGNvbnNvbGUud2FybihcIlBhZ3kuaW5pdDogJW9cXG4lc1wiLCBlbGVtZW50LCBlcnIpIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59KSgpO1xuIiwKICAgICJpbXBvcnQgUGFneSBmcm9tIFwiLi9wYWd5LnRzXCJcbndpbmRvdy5QYWd5ID0gUGFneVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjtBQWdEQSxJQUFnQixzQkFBTTtBQUFBLEVBQ3BCLE1BQU0saUJBQWlCLG9CQUFvQixVQUFVLHNCQUFzQjtBQUFBLEVBRTNFLElBQUksT0FBTyxRQUFRLFNBQWtCLE1BQXdCO0FBQUEsRUFDN0QsSUFBSSxnQkFBZ0I7QUFBQSxJQUNsQixVQUFVO0FBQUEsSUFDVixPQUFVLElBQUksaUJBQWlCLElBQUk7QUFBQSxJQUNuQyxRQUFVLEtBQUssSUFBSTtBQUFBLElBR25CLEtBQUssaUJBQWlCLFdBQVcsQ0FBQyxNQUE2QjtBQUFBLE1BQzdELElBQUksRUFBRSxL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
|
data/javascripts/pagy.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
window.Pagy=(()=>{let O="sessionStorage"in window&&"BroadcastChannel"in window,B="pagy",Z,L,W;if(O)Z=sessionStorage,L=new BroadcastChannel(B),W=Date.now(),L.addEventListener("message",(q)=>{if(q.data.from){let z=Z.getItem(q.data.key);if(z)L.postMessage({to:q.data.from,key:q.data.key,str:z})}else if(q.data.to){if(q.data.to==W)Z.setItem(q.data.key,q.data.str)}});let V=new ResizeObserver((q)=>{q.forEach((z)=>{z.target.querySelectorAll(".series-nav-js").forEach((C)=>{C.render()})})}),_=(q)=>btoa(String.fromCharCode(...new TextEncoder().encode(q))).replace(/[+/=]/g,(z)=>z=="+"?"-":z=="/"?"_":""),T=(q)=>new TextDecoder().decode(Uint8Array.from(atob(q),(z)=>z.charCodeAt(0))),P=()=>Math.floor(Math.random()*46656).toString(36),J=async(q,[z,C,F,H,G])=>{let Q,X=document.cookie.split(/;\s+/).find((M)=>M.startsWith(B+"="))?.split("=")[1]??P();if(document.cookie=`${B}=${X}`,z&&!(z in Z)){if(L.postMessage({from:W,key:z}),await new Promise((M)=>setTimeout(()=>{M("")},100)),!(z in Z))Q=(M)=>`${M}+${String(H)}`}if(!Q){if(!z)do z=P();while(z in Z);let M=Z.getItem(z),Y=M?JSON.parse(M):[void 0];if(G)Y.splice(...G),Z.setItem(z,JSON.stringify(Y));Q=($)=>{let R=parseInt($);return _(JSON.stringify([X,z,R,Y.length,Y[R-1],Y[R]]))}}let D=C?`${C}%5B${F}%5D`:F,E=new RegExp(`(?<=\\?.*)(\\b${D}=)(\\d+)`);for(let M of q.querySelectorAll("a[href]"))M.href=M.href.replace(E,(Y,$,R)=>`${String($)}${Q(R)}`);return Q},x=(q,[[z,C,F,H,G],Q,[X,D,E],M])=>{let Y=-1,$=q.parentElement;q.render=()=>{let R=X.findIndex((j)=>j<$.clientWidth);if(R===-1||X[R]===Y)return;let U=z;if(D[R].forEach((j,I)=>{U+=j=="gap"?H:(typeof j=="number"?C.replace(Q,j):F).replace("L<",E?.[R][I]??`${String(j)}<`)}),U+=G,q.innerHTML="",q.insertAdjacentHTML("afterbegin",U),Y=X[R],M&&O)J(q,M)},V.observe($)},w=async(q,[z,C,F])=>{let H=F&&O?await J(q,F):(G)=>G;S(q,(G)=>z.replace(C,H(G)))},A=(q,[z,C,F,H])=>{S(q,(G)=>{return C.replace(F,Math.max(Math.ceil(z/parseInt(G)),1)).replace(H,G)})},S=(q,z)=>{let C=q.querySelector("input"),F=q.querySelector("a"),H=C.value,G=()=>{if(C.value===H)return;let[Q,X,D]=[C.min,C.value,C.max].map((E)=>parseInt(E)||0);if(X<Q||X>D){C.value=H,C.select();return}H=C.value,F.href=z(C.value),F.click()};C.addEventListener("focus",()=>{C.select()}),C.addEventListener("focusout",G),C.addEventListener("keypress",(Q)=>{if(Q.key=="Enter")G()})};return{version:"43.
|
|
1
|
+
window.Pagy=(()=>{let O="sessionStorage"in window&&"BroadcastChannel"in window,B="pagy",Z,L,W;if(O)Z=sessionStorage,L=new BroadcastChannel(B),W=Date.now(),L.addEventListener("message",(q)=>{if(q.data.from){let z=Z.getItem(q.data.key);if(z)L.postMessage({to:q.data.from,key:q.data.key,str:z})}else if(q.data.to){if(q.data.to==W)Z.setItem(q.data.key,q.data.str)}});let V=new ResizeObserver((q)=>{q.forEach((z)=>{z.target.querySelectorAll(".series-nav-js").forEach((C)=>{C.render()})})}),_=(q)=>btoa(String.fromCharCode(...new TextEncoder().encode(q))).replace(/[+/=]/g,(z)=>z=="+"?"-":z=="/"?"_":""),T=(q)=>new TextDecoder().decode(Uint8Array.from(atob(q),(z)=>z.charCodeAt(0))),P=()=>Math.floor(Math.random()*46656).toString(36),J=async(q,[z,C,F,H,G])=>{let Q,X=document.cookie.split(/;\s+/).find((M)=>M.startsWith(B+"="))?.split("=")[1]??P();if(document.cookie=`${B}=${X}`,z&&!(z in Z)){if(L.postMessage({from:W,key:z}),await new Promise((M)=>setTimeout(()=>{M("")},100)),!(z in Z))Q=(M)=>`${M}+${String(H)}`}if(!Q){if(!z)do z=P();while(z in Z);let M=Z.getItem(z),Y=M?JSON.parse(M):[void 0];if(G)Y.splice(...G),Z.setItem(z,JSON.stringify(Y));Q=($)=>{let R=parseInt($);return _(JSON.stringify([X,z,R,Y.length,Y[R-1],Y[R]]))}}let D=C?`${C}%5B${F}%5D`:F,E=new RegExp(`(?<=\\?.*)(\\b${D}=)(\\d+)`);for(let M of q.querySelectorAll("a[href]"))M.href=M.href.replace(E,(Y,$,R)=>`${String($)}${Q(R)}`);return Q},x=(q,[[z,C,F,H,G],Q,[X,D,E],M])=>{let Y=-1,$=q.parentElement;q.render=()=>{let R=X.findIndex((j)=>j<$.clientWidth);if(R===-1||X[R]===Y)return;let U=z;if(D[R].forEach((j,I)=>{U+=j=="gap"?H:(typeof j=="number"?C.replace(Q,j):F).replace("L<",E?.[R][I]??`${String(j)}<`)}),U+=G,q.innerHTML="",q.insertAdjacentHTML("afterbegin",U),Y=X[R],M&&O)J(q,M)},V.observe($)},w=async(q,[z,C,F])=>{let H=F&&O?await J(q,F):(G)=>G;S(q,(G)=>z.replace(C,H(G)))},A=(q,[z,C,F,H])=>{S(q,(G)=>{return C.replace(F,Math.max(Math.ceil(z/parseInt(G)),1)).replace(H,G)})},S=(q,z)=>{let C=q.querySelector("input"),F=q.querySelector("a"),H=C.value,G=()=>{if(C.value===H)return;let[Q,X,D]=[C.min,C.value,C.max].map((E)=>parseInt(E)||0);if(X<Q||X>D){C.value=H,C.select();return}H=C.value,F.href=z(C.value),F.click()};C.addEventListener("focus",()=>{C.select()}),C.addEventListener("focusout",G),C.addEventListener("keypress",(Q)=>{if(Q.key=="Enter")G()})};return{version:"43.7.0",init(q){let z=q instanceof HTMLElement?q:document,C=z.querySelectorAll("[data-pagy]");for(let F of C)try{let[H,...G]=JSON.parse(T(F.getAttribute("data-pagy")));if(H=="k")J(F,...G);else if(H=="snj")x(F,G);else if(H=="inj")w(F,G);else if(H=="ltj")A(F,G)}catch(H){console.warn(`Pagy.init: %o
|
|
2
2
|
%s`,F,H)}}}})();
|
data/javascripts/pagy.mjs
CHANGED
|
@@ -134,7 +134,7 @@ export default (() => {
|
|
|
134
134
|
});
|
|
135
135
|
};
|
|
136
136
|
return {
|
|
137
|
-
version: "43.
|
|
137
|
+
version: "43.7.0",
|
|
138
138
|
init(arg) {
|
|
139
139
|
const target = arg instanceof HTMLElement ? arg : document, elements = target.querySelectorAll("[data-pagy]");
|
|
140
140
|
for (const element of elements) {
|
|
@@ -2,15 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
4
|
module Search
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def
|
|
5
|
+
# Collect the search arguments and record the chained calls, applied later by the paginators.
|
|
6
|
+
# It is not an Array, so methods like filter, reject, sort, etc. get recorded as well
|
|
7
|
+
class Arguments
|
|
8
|
+
def initialize(*arguments)
|
|
9
|
+
@arguments = arguments
|
|
10
|
+
@calls = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Destructure as [model, arguments, options, block, calls]
|
|
14
|
+
def to_ary = [*@arguments, @calls]
|
|
15
|
+
|
|
16
|
+
# Conversion methods are not recorded
|
|
17
|
+
def respond_to_missing?(name, *) = !name.start_with?('to_')
|
|
18
|
+
|
|
19
|
+
def method_missing(name, *args, **kwargs, &block)
|
|
20
|
+
return super if name.start_with?('to_')
|
|
21
|
+
|
|
22
|
+
@calls << [name, args, kwargs, block]
|
|
23
|
+
self
|
|
24
|
+
end
|
|
9
25
|
end
|
|
10
26
|
|
|
11
27
|
# Collect the search arguments to pass to the actual search
|
|
12
28
|
def pagy_search(*arguments, **options, &block)
|
|
13
|
-
Arguments.new(
|
|
29
|
+
Arguments.new(self, arguments, options, block)
|
|
14
30
|
end
|
|
15
31
|
end
|
|
16
32
|
|
|
@@ -20,6 +36,10 @@ class Pagy
|
|
|
20
36
|
def search? = true
|
|
21
37
|
end
|
|
22
38
|
|
|
39
|
+
class RailsActiveSearch < SearchBase
|
|
40
|
+
DEFAULT = { search_method: :search }.freeze
|
|
41
|
+
end
|
|
42
|
+
|
|
23
43
|
class ElasticsearchRails < SearchBase
|
|
24
44
|
DEFAULT = { search_method: :search,
|
|
25
45
|
max_result_window: 10_000 }.freeze
|
data/lib/pagy/classes/request.rb
CHANGED
|
@@ -27,13 +27,13 @@ class Pagy
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def resolve_limit
|
|
30
|
-
default
|
|
31
|
-
|
|
32
|
-
return default unless
|
|
30
|
+
default = @options[:limit] || DEFAULT[:limit]
|
|
31
|
+
client_limit = @options[:client_limit]
|
|
32
|
+
return default unless client_limit
|
|
33
33
|
|
|
34
34
|
limit_key = @options[:limit_key] || DEFAULT[:limit_key]
|
|
35
35
|
limit = (@params.dig(@options[:root_key], limit_key) || @params[limit_key]).to_s.to_i
|
|
36
|
-
limit.zero? ? default : [limit,
|
|
36
|
+
limit.zero? ? default : [limit, client_limit].min
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
private
|
data/lib/pagy/cli.rb
CHANGED
|
@@ -23,7 +23,7 @@ class Pagy
|
|
|
23
23
|
|
|
24
24
|
parser = OptionParser.new do |opts|
|
|
25
25
|
opts.banner = <<~BANNER
|
|
26
|
-
Pagy #{VERSION} (https://ddnexus.github.io/pagy/playground)
|
|
26
|
+
Pagy #{VERSION} (https://ddnexus.github.io/pagy/sandbox/playground)
|
|
27
27
|
Playground to showcase, clone and develop Pagy APPs
|
|
28
28
|
|
|
29
29
|
Usage:
|
data/lib/pagy/deprecated.rb
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
class Pagy
|
|
7
7
|
module Deprecated
|
|
8
8
|
def self.client_max_limit(options)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
warn
|
|
9
|
+
options[:client_limit] ||= options[:max_limit] || options[:client_max_limit]
|
|
10
|
+
%i[max_limit client_max_limit].each do |key|
|
|
11
|
+
warn "[PAGY] the #{key.inspect} option is deprecated: use :client_limit instead." if options.delete(key)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -53,7 +53,7 @@ class Pagy
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
{ opts[:page_key] => compose_page_param(page),
|
|
56
|
-
opts[:limit_key] => opts[:
|
|
56
|
+
opts[:limit_key] => opts[:client_limit] && opts[:limit] }.each do |k, v|
|
|
57
57
|
v ? container[k] = v : container.delete(k)
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -6,15 +6,22 @@ class Pagy
|
|
|
6
6
|
|
|
7
7
|
# Common search logic
|
|
8
8
|
def wrap(search_arguments, options)
|
|
9
|
-
options
|
|
10
|
-
options[:limit] = options[:request].resolve_limit
|
|
11
|
-
|
|
9
|
+
resolve(options)
|
|
12
10
|
pagy, results = yield
|
|
11
|
+
*, calls = search_arguments
|
|
12
|
+
|
|
13
|
+
[pagy, chain(results, calls)]
|
|
14
|
+
end
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
# Resolve the page and limit from the request
|
|
17
|
+
def resolve(options)
|
|
18
|
+
options[:page] ||= options[:request].resolve_page
|
|
19
|
+
options[:limit] = options[:request].resolve_limit
|
|
20
|
+
end
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
# Apply the calls recorded by Search::Arguments
|
|
23
|
+
def chain(receiver, calls)
|
|
24
|
+
calls.reduce(receiver) { |object, (name, args, kwargs, block)| object.send(name, *args, **kwargs, &block) }
|
|
18
25
|
end
|
|
19
26
|
end
|
|
20
27
|
end
|
data/lib/pagy/next.rb
CHANGED
|
@@ -14,7 +14,7 @@ class Pagy
|
|
|
14
14
|
module Discontinued
|
|
15
15
|
# Ensure a discontinued option won't pass unnoticed shadowing a bug
|
|
16
16
|
def assign_options(**options)
|
|
17
|
-
discontinued = options.keys & %i[max_pages client_max_limit]
|
|
17
|
+
discontinued = options.keys & %i[max_pages client_max_limit max_limit]
|
|
18
18
|
return super if discontinued.empty?
|
|
19
19
|
|
|
20
20
|
raise NextError, "discontinued #{discontinued.map(&:inspect).join(', ')}: " \
|
|
@@ -11,7 +11,9 @@ class Pagy
|
|
|
11
11
|
|
|
12
12
|
# Generate a hash of RFC-8288-compliant http headers
|
|
13
13
|
def headers_hash(headers_map: @options[:headers_map] || DEFAULT_HEADERS_MAP, **)
|
|
14
|
-
links = urls_hash(**, absolute: true).map
|
|
14
|
+
links = urls_hash(**, absolute: true).map do |key, url|
|
|
15
|
+
%(<#{url}>; rel="#{key == :previous ? :prev : key}")
|
|
16
|
+
end.join(', ')
|
|
15
17
|
|
|
16
18
|
headers_map.each_with_object('link' => links) do |(key, name), hash|
|
|
17
19
|
next unless name
|
|
@@ -4,10 +4,10 @@ require_relative 'support/data_pagy_attribute'
|
|
|
4
4
|
|
|
5
5
|
class Pagy
|
|
6
6
|
module NumericHelpers
|
|
7
|
-
def limit_tag_js(id: nil, item_name: nil,
|
|
8
|
-
raise OptionError.new(self, :
|
|
7
|
+
def limit_tag_js(id: nil, item_name: nil, client_limit: @options[:client_limit], **)
|
|
8
|
+
raise OptionError.new(self, :client_limit, 'to be truthy', client_limit) unless client_limit
|
|
9
9
|
|
|
10
|
-
limit_input = %(<input name="limit" type="number" min="1" max="#{
|
|
10
|
+
limit_input = %(<input name="limit" type="number" min="1" max="#{client_limit}" value="#{
|
|
11
11
|
@limit}" style="padding: 0; text-align: center; width: #{@limit.to_s.length + 1}rem;">#{A_TAG})
|
|
12
12
|
|
|
13
13
|
url_token = compose_page_url(PAGE_TOKEN, limit: LIMIT_TOKEN)
|
|
@@ -9,11 +9,11 @@ class Pagy
|
|
|
9
9
|
private
|
|
10
10
|
|
|
11
11
|
# The reverse-sorted array of widths, series, and labels generated from the :steps hash.
|
|
12
|
-
# If :steps is
|
|
13
|
-
def sequels(
|
|
12
|
+
# If :steps is not set it will use the single {0 => slots} step; :compact applies to all the steps
|
|
13
|
+
def sequels(slots: @options[:slots] || SERIES_SLOTS, compact: @options[:compact], steps: @options[:steps] || { 0 => slots }, **)
|
|
14
14
|
raise OptionError.new(self, :steps, 'to define the 0 width', steps) unless steps.key?(0)
|
|
15
15
|
|
|
16
|
-
widths, series = steps.sort.reverse.map { |width,
|
|
16
|
+
widths, series = steps.sort.reverse.map { |width, step_slots| [width, series(slots: step_slots, compact:)] }.transpose
|
|
17
17
|
[widths, series, page_labels(series)]
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -4,9 +4,10 @@ class Pagy
|
|
|
4
4
|
def urls_hash(**)
|
|
5
5
|
template = compose_page_url(PAGE_TOKEN, **)
|
|
6
6
|
|
|
7
|
-
{ first: compose_page_url(nil, **),
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
urls = { first: compose_page_url(nil, **),
|
|
8
|
+
previous: @previous && template.sub(PAGE_TOKEN, @previous.to_s),
|
|
9
|
+
next: @next && template.sub(PAGE_TOKEN, @next.to_s),
|
|
10
|
+
last: @count && template.sub(PAGE_TOKEN, @last.to_s) }.compact
|
|
11
|
+
@options[:jsonapi] ? urls.transform_keys(previous: :prev) : urls # JSON:API requires :prev
|
|
11
12
|
end
|
|
12
13
|
end
|
|
@@ -11,6 +11,7 @@ class Pagy
|
|
|
11
11
|
calendar: :CalendarPaginator,
|
|
12
12
|
elasticsearch_rails: :ElasticsearchRailsPaginator,
|
|
13
13
|
meilisearch: :MeilisearchPaginator,
|
|
14
|
+
rails_active_search: :RailsActiveSearchPaginator,
|
|
14
15
|
searchkick: :SearchkickPaginator,
|
|
15
16
|
typesense_rails: :TypesenseRailsPaginator }.freeze
|
|
16
17
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../modules/searcher'
|
|
4
|
+
|
|
5
|
+
class Pagy
|
|
6
|
+
module RailsActiveSearchPaginator
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
def paginate(search, options)
|
|
10
|
+
if search.is_a?(Search::Arguments) # Active mode
|
|
11
|
+
Searcher.resolve(options)
|
|
12
|
+
model, arguments, search_options, block, calls = search
|
|
13
|
+
|
|
14
|
+
method = options[:search_method] || RailsActiveSearch::DEFAULT[:search_method]
|
|
15
|
+
# The chained calls build the ActiveSearch::Query, so they apply before executing it
|
|
16
|
+
query = Searcher.chain(model.send(method, *arguments, **search_options, &block), calls)
|
|
17
|
+
results = query.limit(options[:limit])
|
|
18
|
+
.offset(options[:limit] * (options[:page] - 1))
|
|
19
|
+
.results
|
|
20
|
+
options[:count] = results.total
|
|
21
|
+
|
|
22
|
+
[RailsActiveSearch.new(**options), results]
|
|
23
|
+
else # Passive mode (ActiveSearch::Results)
|
|
24
|
+
# TODO: use the public readers when ActiveSearch::Results will provide them
|
|
25
|
+
limit = search.instance_variable_get(:@limit)
|
|
26
|
+
offset = search.instance_variable_get(:@offset).to_i # nil when not set
|
|
27
|
+
options[:limit] = limit
|
|
28
|
+
options[:page] = (offset / limit) + 1
|
|
29
|
+
options[:count] = search.total
|
|
30
|
+
|
|
31
|
+
RailsActiveSearch.new(**options)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/pagy.rb
CHANGED
|
@@ -9,7 +9,7 @@ require_relative 'pagy/toolbox/helpers/loaders'
|
|
|
9
9
|
|
|
10
10
|
# Top superclass
|
|
11
11
|
class Pagy
|
|
12
|
-
VERSION = '43.
|
|
12
|
+
VERSION = '43.7.0'
|
|
13
13
|
ROOT = Pathname.new(__dir__).parent.freeze
|
|
14
14
|
DEFAULT = { limit: 20, limit_key: 'limit', page_key: 'page' }.freeze
|
|
15
15
|
PAGE_TOKEN = EscapedValue.new('P ')
|
|
@@ -24,6 +24,7 @@ class Pagy
|
|
|
24
24
|
autoload :Calendar, path.join('classes/calendar/calendar')
|
|
25
25
|
autoload :Offset, path.join('classes/offset/offset')
|
|
26
26
|
autoload :Search, path.join('classes/offset/search')
|
|
27
|
+
autoload :RailsActiveSearch, path.join('classes/offset/search')
|
|
27
28
|
autoload :ElasticsearchRails, path.join('classes/offset/search')
|
|
28
29
|
autoload :Meilisearch, path.join('classes/offset/search')
|
|
29
30
|
autoload :Searchkick, path.join('classes/offset/search')
|
|
@@ -74,8 +75,8 @@ class Pagy
|
|
|
74
75
|
@request = options.delete(:request) # internal object
|
|
75
76
|
validate_string_values(options)
|
|
76
77
|
|
|
77
|
-
default
|
|
78
|
-
current
|
|
78
|
+
default = {}
|
|
79
|
+
current = self.class
|
|
79
80
|
|
|
80
81
|
loop do
|
|
81
82
|
default = current::DEFAULT.merge(default)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pagy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 43.
|
|
4
|
+
version: 43.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Domizio Demichelis
|
|
@@ -60,6 +60,7 @@ extensions: []
|
|
|
60
60
|
extra_rdoc_files: []
|
|
61
61
|
files:
|
|
62
62
|
- LICENSE.txt
|
|
63
|
+
- apps/active_search.ru
|
|
63
64
|
- apps/calendar.ru
|
|
64
65
|
- apps/demo.ru
|
|
65
66
|
- apps/enable_rails_page_segment.rb
|
|
@@ -153,6 +154,7 @@ files:
|
|
|
153
154
|
- lib/pagy/toolbox/paginators/meilisearch.rb
|
|
154
155
|
- lib/pagy/toolbox/paginators/method.rb
|
|
155
156
|
- lib/pagy/toolbox/paginators/offset.rb
|
|
157
|
+
- lib/pagy/toolbox/paginators/rails_active_search.rb
|
|
156
158
|
- lib/pagy/toolbox/paginators/searchkick.rb
|
|
157
159
|
- lib/pagy/toolbox/paginators/typesense_rails.rb
|
|
158
160
|
- locales/ar.yml
|
|
@@ -220,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
220
222
|
- !ruby/object:Gem::Version
|
|
221
223
|
version: '0'
|
|
222
224
|
requirements: []
|
|
223
|
-
rubygems_version: 4.0.
|
|
225
|
+
rubygems_version: 4.0.20
|
|
224
226
|
specification_version: 4
|
|
225
227
|
summary: "Pagy \U0001F438 The Leaping Gem!"
|
|
226
228
|
test_files: []
|