kabk 0.2.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.

Potentially problematic release.


This version of kabk might be problematic. Click here for more details.

Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +27 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +108 -0
  5. data/Kabk_logo.svg +33 -0
  6. data/LICENSE +21 -0
  7. data/README.md +101 -0
  8. data/doc/Kabk/Adapters/Base.html +854 -0
  9. data/doc/Kabk/Adapters/SequelAdapter.html +948 -0
  10. data/doc/Kabk/Adapters.html +120 -0
  11. data/doc/Kabk/ApiError.html +511 -0
  12. data/doc/Kabk/Auth/JwtStrategy.html +551 -0
  13. data/doc/Kabk/Auth.html +118 -0
  14. data/doc/Kabk/Concurrency.html +297 -0
  15. data/doc/Kabk/ConcurrencyConflictError.html +225 -0
  16. data/doc/Kabk/Error.html +140 -0
  17. data/doc/Kabk/ExportHandler.html +381 -0
  18. data/doc/Kabk/Field.html +2160 -0
  19. data/doc/Kabk/ForbiddenError.html +225 -0
  20. data/doc/Kabk/InvalidFieldError.html +136 -0
  21. data/doc/Kabk/InvalidOldPasswordError.html +225 -0
  22. data/doc/Kabk/NotFoundError.html +225 -0
  23. data/doc/Kabk/QueryBuilder.html +551 -0
  24. data/doc/Kabk/Registry.html +608 -0
  25. data/doc/Kabk/RelationHydrator.html +480 -0
  26. data/doc/Kabk/Resource.html +1986 -0
  27. data/doc/Kabk/ResourceBuilder.html +1002 -0
  28. data/doc/Kabk/RestEngine.html +879 -0
  29. data/doc/Kabk/SchemaRenderer.html +318 -0
  30. data/doc/Kabk/UnauthorizedError.html +225 -0
  31. data/doc/Kabk/UploadHandler.html +308 -0
  32. data/doc/Kabk/ValidationError.html +225 -0
  33. data/doc/Kabk/Validator.html +380 -0
  34. data/doc/Kabk.html +330 -0
  35. data/doc/_index.html +376 -0
  36. data/doc/class_list.html +54 -0
  37. data/doc/css/common.css +1 -0
  38. data/doc/css/full_list.css +206 -0
  39. data/doc/css/style.css +1089 -0
  40. data/doc/file.README.html +149 -0
  41. data/doc/file_list.html +59 -0
  42. data/doc/frames.html +22 -0
  43. data/doc/index.html +149 -0
  44. data/doc/js/app.js +801 -0
  45. data/doc/js/full_list.js +334 -0
  46. data/doc/js/jquery.js +4 -0
  47. data/doc/method_list.html +910 -0
  48. data/doc/top-level-namespace.html +112 -0
  49. data/docs/API_REFERENCE.md +241 -0
  50. data/lib/kabk/adapters/base.rb +45 -0
  51. data/lib/kabk/adapters/sequel_adapter.rb +125 -0
  52. data/lib/kabk/concurrency.rb +30 -0
  53. data/lib/kabk/errors.rb +62 -0
  54. data/lib/kabk/export_handler.rb +43 -0
  55. data/lib/kabk/field.rb +97 -0
  56. data/lib/kabk/query_builder.rb +72 -0
  57. data/lib/kabk/registry.rb +41 -0
  58. data/lib/kabk/relation_hydrator.rb +107 -0
  59. data/lib/kabk/resource.rb +88 -0
  60. data/lib/kabk/resource_builder.rb +93 -0
  61. data/lib/kabk/rest_engine.rb +84 -0
  62. data/lib/kabk/schema_renderer.rb +69 -0
  63. data/lib/kabk/upload_handler.rb +24 -0
  64. data/lib/kabk/validator.rb +64 -0
  65. data/lib/kabk/version.rb +6 -0
  66. data/lib/kabk.rb +51 -0
  67. metadata +193 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3954d99af8659cf0ee20137b531564ed8f20e66db66e0af6766627e5c3eb4053
4
+ data.tar.gz: 9f88462586786e0fd2d3b1fb0af329067906e8132602a96208e1686ffdbb1350
5
+ SHA512:
6
+ metadata.gz: d49f7ae60123f5d1f1b2515d9956a2146432f419cff8eda363b6abfffcb3d23bf757aad05a8001973ab62f4d7ea7780fa8e51d2f076f7eaa8c4aa8a57f6ce40b
7
+ data.tar.gz: 52a0f4aeb9002ddfe5f92fdc125fb3f5cabf515f88d636e52625c13ef6faed591c220f10d14ae67f2af8b257e233b39aad8119f3088696d29d343020b4029bf4
data/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0] - 2026-08-11
9
+
10
+ ### Added
11
+ - **Lifecycle Hooks:** Added support for `before_create`, `after_create`, `before_update`, `after_update`, `before_delete`, and `after_delete` callbacks in `Kabk.register`. Hooks execute inside `RestEngine`, receive host context, and can mutate parameters or halt execution.
12
+
13
+ ### Changed
14
+ - **BREAKING:** `Kabk::RestEngine` methods (`create`, `update`, `delete`) now capture `Kabk::ApiError` exceptions and return standard error payloads (`{ success: false, error: ... }`) instead of raising exceptions.
15
+ - **BREAKING:** Kabk is now ORM-agnostic. All direct `Sequel` queries have been moved to `Kabk::Adapters::SequelAdapter`.
16
+ - **BREAKING:** `Kabk::RestEngine` methods (`list`, `get`, `create`, `update`, `delete`) now accept an optional `context:` keyword argument for passing host data (e.g., `current_user`).
17
+
18
+ ### Removed
19
+ - **BREAKING:** Completely removed the built-in JWT authentication strategy and `jwt` dependency. Authentication is now strictly the responsibility of the host application.
20
+
21
+ ## [0.1.1] - 2026-08-07
22
+
23
+ ### Added
24
+ - Initial public release of the `kabk` gem.
25
+ - Framework-agnostic engine for resource registration.
26
+ - Generic REST engine for CRUD operations.
27
+ - Server-side validation, pagination, and sorting functionality.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "sqlite3"
6
+ gem "rspec"
data/Gemfile.lock ADDED
@@ -0,0 +1,108 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ kabk (0.1.2)
5
+ concurrent-ruby (~> 1.1)
6
+ csv
7
+ sequel (~> 5.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ast (2.4.3)
13
+ bigdecimal (4.0.1)
14
+ concurrent-ruby (1.3.8)
15
+ csv (3.3.6)
16
+ diff-lcs (1.6.2)
17
+ json (2.21.2)
18
+ language_server-protocol (3.17.0.6)
19
+ lint_roller (1.1.0)
20
+ parallel (2.1.0)
21
+ parser (3.3.12.0)
22
+ ast (~> 2.4.1)
23
+ racc
24
+ prism (1.9.0)
25
+ racc (1.8.1)
26
+ rainbow (3.1.1)
27
+ regexp_parser (2.12.0)
28
+ rspec (3.13.2)
29
+ rspec-core (~> 3.13.0)
30
+ rspec-expectations (~> 3.13.0)
31
+ rspec-mocks (~> 3.13.0)
32
+ rspec-core (3.13.6)
33
+ rspec-support (~> 3.13.0)
34
+ rspec-expectations (3.13.5)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.13.0)
37
+ rspec-mocks (3.13.8)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.13.0)
40
+ rspec-support (3.13.7)
41
+ rubocop (1.89.0)
42
+ json (~> 2.3)
43
+ language_server-protocol (~> 3.17.0.2)
44
+ lint_roller (~> 1.1.0)
45
+ parallel (>= 1.10)
46
+ parser (>= 3.3.0.2)
47
+ rainbow (>= 2.2.2, < 4.0)
48
+ regexp_parser (>= 2.9.3, < 3.0)
49
+ rubocop-ast (>= 1.49.0, < 2.0)
50
+ ruby-progressbar (~> 1.7)
51
+ unicode-display_width (>= 2.4.0, < 4.0)
52
+ rubocop-ast (1.50.0)
53
+ parser (>= 3.3.7.2)
54
+ prism (~> 1.7)
55
+ ruby-progressbar (1.13.0)
56
+ sequel (5.107.0)
57
+ bigdecimal
58
+ sqlite3 (2.9.5-x64-mingw-ucrt)
59
+ unicode-display_width (3.2.0)
60
+ unicode-emoji (~> 4.1)
61
+ unicode-emoji (4.2.0)
62
+ webrick (1.9.2)
63
+ yard (0.9.45)
64
+
65
+ PLATFORMS
66
+ x64-mingw-ucrt
67
+
68
+ DEPENDENCIES
69
+ kabk!
70
+ rspec
71
+ rubocop (~> 1.21)
72
+ sqlite3
73
+ webrick
74
+ yard (~> 0.9)
75
+
76
+ CHECKSUMS
77
+ ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
78
+ bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
79
+ concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
80
+ csv (3.3.6) sha256=aba61e7e507a66f03d45cb1f3c4b6359861c3504038b422962875dce099e4456
81
+ diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
82
+ json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
83
+ kabk (0.1.2)
84
+ language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
85
+ lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
86
+ parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356
87
+ parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828
88
+ prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
89
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
90
+ rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
91
+ regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
92
+ rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
93
+ rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
94
+ rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
95
+ rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
96
+ rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
97
+ rubocop (1.89.0) sha256=4dee8e3ee9c45e474834efd9e8d6fd031e8331c8dacdff0de4ad65ae0a6faae7
98
+ rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db
99
+ ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
100
+ sequel (5.107.0) sha256=019629313205295b007f6df2c5eab19ddc40710d549fd445ac300f2853a370db
101
+ sqlite3 (2.9.5-x64-mingw-ucrt) sha256=b00d5697994ee8589b6096694a2130aa5567db64373baca55ea98c9bf958f46a
102
+ unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
103
+ unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
104
+ webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131
105
+ yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51
106
+
107
+ BUNDLED WITH
108
+ 4.0.16
data/Kabk_logo.svg ADDED
@@ -0,0 +1,33 @@
1
+ <svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 395 395.6" width="700" height="701.7721518987341">
2
+ <defs>
3
+ <linearGradient id="g1" x2="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(263.757,275.126,-433.936,452.641,65,4)">
4
+ <stop offset="0" stop-color="#e0334f"/>
5
+ <stop offset=".45" stop-color="#c41e3a"/>
6
+ <stop offset="1" stop-color="#7a1128"/>
7
+ </linearGradient>
8
+ <linearGradient id="g2" x2="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(9.217,8.903,-9.218,8.904,280.9,21.68)">
9
+ <stop offset="0" stop-color="#e0334f"/>
10
+ <stop offset=".45" stop-color="#c41e3a"/>
11
+ <stop offset="1" stop-color="#7a1128"/>
12
+ </linearGradient>
13
+ <linearGradient id="g3" x2="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(331.999,81.601,-330.561,81.247,36.979,287.999)">
14
+ <stop offset="0" stop-color="#e0334f"/>
15
+ <stop offset=".45" stop-color="#c41e3a"/>
16
+ <stop offset="1" stop-color="#7a1128"/>
17
+ </linearGradient>
18
+ </defs>
19
+ <style>
20
+ .s0 { fill: url(#g1) }
21
+ .s1 { fill: url(#g2) }
22
+ .s2 { fill: url(#g3) }
23
+ </style>
24
+ <g>
25
+ <g>
26
+ <path class="s0" d="m278.28 4.04c-0.18 0.04-1.11 0.19-2.08 0.32-0.96 0.13-2.29 0.4-2.94 0.57q-3.27 0.88-4.31 1.33c-0.37 0.16-0.78 0.29-0.91 0.29-0.55 0-5.9 2.77-7.56 3.91-4.33 2.95-8.96 7.36-11.03 10.5-0.18 0.27-0.59 0.88-0.94 1.34-2.08 2.92-4.7 8.05-6.16 11.99-0.15 0.41-0.41 1.15-0.61 1.63-0.68 1.86-1.92 6.12-2.49 8.52-0.68 2.99-0.96 4.2-1.14 4.92-0.08 0.41-0.28 1.11-0.41 1.53-0.15 0.41-0.46 1.35-0.7 2.07-0.22 0.72-0.63 1.86-0.87 2.51-0.27 0.66-0.55 1.47-0.66 1.77-0.28 0.94-0.85 1.68-1.42 1.81-0.26 0.07-0.96 0.64-1.51 1.25l-1 1.11v1.09c0 1.45-0.37 2.06-2.12 3.61-3.65 3.21-8.93 5.98-15.68 8.25-0.83 0.29-2.08 0.75-2.73 0.99-0.66 0.26-1.88 0.7-2.73 0.98-0.83 0.28-2.08 0.72-2.73 0.98-2.64 1.01-2.97 1.14-3.39 1.23-0.24 0.06-0.63 0.21-0.87 0.3-0.24 0.11-0.98 0.42-1.64 0.66-1.29 0.5-3.97 1.59-5.24 2.12-1.01 0.41-1.33 0.54-3.34 1.46-0.92 0.44-1.75 0.79-1.82 0.79-0.45 0-10.59 5.32-14.28 7.49-5.66 3.34-14.55 9.54-18.87 13.12-8.26 6.91-14.18 12.74-19.81 19.57-0.66 0.79-1.4 1.66-1.66 1.97-1.84 2.07-7.54 9.81-9.59 12.99-1.31 2.01-5.55 9.07-6.38 10.6-0.35 0.65-0.87 1.59-1.13 2.07-0.59 1.03-2.67 5.18-3.78 7.54-1.29 2.73-1.75 3.82-3.84 8.84-0.11 0.24-0.51 1.16-0.88 2.06-0.37 0.87-0.68 1.7-0.68 1.81 0 0.13-0.13 0.52-0.3 0.89-0.42 0.97-1.09 2.76-1.99 5.18-0.96 2.58-2.64 6.2-3.93 8.41-0.41 0.72-0.85 1.55-0.98 1.83-0.13 0.29-0.51 0.92-0.85 1.42-0.35 0.48-0.99 1.45-1.4 2.1-0.44 0.66-1.18 1.79-1.66 2.51-0.5 0.72-1.01 1.51-1.16 1.73-0.46 0.68-2.82 3.93-4.22 5.83-0.72 0.96-1.52 2.07-1.81 2.45-0.26 0.39-0.68 0.94-0.92 1.24-0.96 1.25-4.21 5.4-4.58 5.81-0.22 0.26-0.99 1.25-1.73 2.18-0.74 0.97-1.9 2.43-2.6 3.3-0.67 0.85-1.72 2.19-2.33 2.95-0.59 0.77-1.62 2.01-2.25 2.8-1.25 1.5-1.4 1.66-2.78 3.38-0.46 0.61-0.91 1.14-0.98 1.2-0.52 0.44-4.85 6.49-6.22 8.74l-0.62 0.96-0.02 1.55-0.02 1.53 0.44 0.59c1.48 1.97 5.02 1.44 9.39-1.35 0.37-0.24 0.81-0.51 0.98-0.59 0.44-0.22 3.15-2.08 4.28-2.93l0.9-0.66 1.02 0.27 1.03 0.26 2.34-0.11 2.33-0.11 0.88-0.39c2.14-0.94 3.86-1.82 5.79-2.95 1.13-0.68 2.22-1.29 2.4-1.38 0.17-0.08 0.63-0.35 0.98-0.59 0.37-0.24 0.81-0.5 0.98-0.59 0.18-0.06 0.73-0.39 1.21-0.7 0.48-0.3 1.04-0.65 1.24-0.78 1.94-1.14 6.77-4.17 8.65-5.46 8.45-5.7 8.37-5.66 11.84-6.23 0.92-0.15 2.38-0.5 4.8-1.11 0.55-0.13 1.58-0.39 2.3-0.57 0.72-0.17 1.85-0.46 2.51-0.65 0.65-0.18 1.7-0.46 2.29-0.62q3.41-0.91 4.37-1.24c0.37-0.13 0.92-0.28 1.24-0.33l0.59-0.11 0.83 0.64c1.75 1.35 7.41 4.32 11.32 5.94 0.96 0.39 2.05 0.85 2.4 1 0.37 0.15 1.01 0.35 1.42 0.44 0.42 0.09 0.87 0.24 0.98 0.33 0.22 0.17 3.45 1.22 5.57 1.81 1.12 0.33 1.84 0.48 5.9 1.35 0.79 0.18 2.4 0.48 3.6 0.68 1.2 0.22 2.32 0.48 2.47 0.59l0.26 0.2v1.2c0 2.36 1.05 4.89 3.83 9.13 0.39 0.59 0.76 1.37 0.83 1.74 0.04 0.35 0.19 0.94 0.32 1.32 0.13 0.34 0.4 1.24 0.61 1.96 0.2 0.72 0.51 1.79 0.68 2.4 0.42 1.42 0.81 2.76 1.27 4.37 0.2 0.72 0.46 1.6 0.59 1.97 0.11 0.35 0.3 1 0.39 1.42 0.11 0.41 0.39 1.44 0.63 2.29 0.27 0.83 0.57 1.92 0.68 2.4 0.11 0.48 0.35 1.47 0.53 2.19 0.17 0.72 0.41 1.59 0.52 1.96 0.11 0.35 0.37 1.2 0.57 1.86 0.17 0.65 0.5 1.7 0.68 2.34l0.34 1.13-0.3 0.61c-0.59 1.14-2.25 2.21-3.87 2.49-2.42 0.44-3.93 0.83-5.13 1.4l-1.31 0.63-1.22 1.25-1.25 1.24-0.59 1.25c-0.61 1.31-1.11 2.93-1.33 4.3l-0.13 0.79 0.39 0.19 0.42 0.22 6.11-0.17 6.12-0.15 1.64-0.35c0.89-0.18 2.22-0.48 2.94-0.68 0.73-0.22 1.62-0.42 2.01-0.48l0.7-0.11 1.82 0.55c1 0.3 2.55 0.69 3.45 0.87 0.89 0.2 2.38 0.5 3.27 0.68l1.64 0.35h16.12 16.12l0.46-0.24 0.43-0.24-0.15-1.29-0.15-1.29 0.33-0.13c0.17-0.07 0.89 0.04 1.59 0.22l1.29 0.32 15.29 0.02c8.41 0.03 15.42 0.03 15.57 0.03l0.26-0.03v-1.52-1.51l-0.37-0.83c-0.63-1.38-2.18-3.28-3.52-4.26-1.55-1.18-3.34-2.05-5.28-2.58l-0.98-0.26-7.65-0.17c-15.05-0.33-16.9-1.07-21.97-8.85-1.99-3.04-2.82-4.39-2.82-4.54 0-0.07-0.28-0.57-0.65-1.09-0.35-0.55-0.66-1.05-0.66-1.12 0-0.06-0.39-0.79-0.89-1.57-0.48-0.81-0.99-1.68-1.1-1.92-0.1-0.27-0.39-0.77-0.63-1.12-0.24-0.37-0.52-0.85-0.65-1.09-0.11-0.24-0.55-1.03-0.97-1.75-0.41-0.72-1.02-1.81-1.33-2.4-0.33-0.61-0.89-1.68-1.31-2.4-1.18-2.1-1.64-3.06-1.64-3.41 0.03-0.44 2.19-4.69 3.3-6.42 0.22-0.37 0.48-0.79 0.57-0.96 0.68-1.42 3.14-4.44 5.96-7.23 3.85-3.87 6.14-5.42 10.81-7.32 2.21-0.91 3-1.29 7.65-3.49 1.81-0.88 3.43-1.64 3.6-1.73 0.33-0.13 0.57-0.28 3.63-2.12 0.98-0.59 1.85-1.07 1.92-1.07 0.07 0 0.55-0.28 1.05-0.65 0.48-0.37 0.96-0.66 1.05-0.66 0.19 0 4.82-3.08 5.92-3.95 0.43-0.35 0.87-0.63 0.96-0.63 0.13 0 1.81-1.25 2.07-1.53 0.07-0.07 1.01-0.81 2.08-1.64 7.23-5.55 16.6-15.59 21.55-23.13 1.58-2.4 4-6.42 4.9-8.1 3.62-6.93 5.06-10.22 7.09-16.49 0.62-1.86 1.25-3.74 1.4-4.15 0.48-1.31 1.38-4.9 1.64-6.51 0.11-0.64 0.28-1.62 0.41-2.19 0.79-3.53 1.27-7.27 1.69-13.25l0.32-4.81-0.1-3.38c-0.25-6.32-0.66-11.21-1.36-15.51-0.3-1.92-0.48-2.78-1.16-5.46-0.15-0.55-0.46-2.51-0.7-4.37-0.45-3.49-0.96-5.31-1.81-6.44-0.65-0.92-1.13-1.97-1.55-3.5-0.22-0.72-0.61-2.01-0.92-2.84-0.28-0.85-0.59-1.72-0.65-1.96-0.05-0.24-0.2-0.64-0.31-0.88-1.15-2.62-2.36-8.56-2.09-10.28 0.06-0.48 0.21-1.44 0.35-2.19 0.21-1.53 1.02-3.34 2.27-5.22l0.89-1.31 5.03-5 5.04-5.02 2.29-0.29c1.27-0.15 3.28-0.37 4.48-0.48 1.2-0.13 2.78-0.3 3.5-0.43 0.72-0.14 2.14-0.24 3.14-0.24h1.84l1.07 0.65c4.95 3.06 2.92-7.03-2.56-12.69-1.11-1.16-6.05-5-6.42-5-0.11 0-0.79-0.31-1.51-0.66-0.74-0.37-1.44-0.65-1.55-0.65-0.13 0-0.68-0.22-1.22-0.48l-0.98-0.48-0.46-1.01c-0.92-2.01-1.2-2.53-2.14-4.15-1.77-2.99-3.15-4.5-6.29-6.77-2.43-1.79-7.47-4.26-9.57-4.69-0.35-0.07-1.2-0.27-1.86-0.44-0.65-0.15-1.74-0.42-2.4-0.57l-1.2-0.26-4.59-0.07c-2.51-0.02-4.74-0.02-4.91 0.03zm9.5 4.43c0.85 0.11 1.88 0.31 2.29 0.44 0.42 0.13 1.51 0.46 2.41 0.72 0.89 0.28 1.79 0.57 1.96 0.65 1.55 0.72 3.71 1.84 4.26 2.17 0.37 0.24 0.81 0.5 0.98 0.58 1.4 0.62 5.44 4.7 6.29 6.34 0.53 1 0.7 1.37 0.64 1.37-0.02 0-0.83-0.24-1.77-0.54-2.01-0.63-2.78-0.68-4.72-0.2l-1.42 0.35h-2.45-2.42l-0.5-0.28c-0.29-0.16-0.81-0.35-1.18-0.44-0.35-0.09-1.2-0.37-1.86-0.63-0.65-0.26-1.83-0.61-2.62-0.77l-1.42-0.28-1.86 0.22-1.85 0.19-1.53 0.77c-0.83 0.39-1.99 1.11-2.56 1.55-2.9 2.36-3.73 2.95-4.78 3.49-0.63 0.31-1.46 0.64-1.81 0.75-0.81 0.19-1.95 0.56-2.93 0.98-0.39 0.17-0.89 0.3-1.13 0.3-0.22 0-0.68 0.14-1.03 0.31-0.33 0.18-1.01 0.48-1.49 0.68-1.5 0.61-3.6 1.72-3.6 1.88 0 0.08-0.22 0.24-0.48 0.32-0.63 0.2-2.77 2.25-3.87 3.69-2.49 3.26-3.75 6.64-4.17 11.08l-0.19 2.14 0.19 2.12c0.66 7.25 5 14.35 12.45 20.35 2.86 2.3 7.91 6.69 9.59 8.32 1.2 1.18 3.52 3.91 4.8 5.68l1.36 1.86 1.55 3.17c3.19 6.53 5.68 10.18 7.69 11.25l1.02 0.54h0.99 0.96l0.85-0.52c1.59-1.01 3.04-3.54 4.28-7.49 0.44-1.38 0.7-1.6 0.98-0.83l0.22 0.59-0.19 1.22c-0.49 2.84-1.08 5-1.69 6.2-0.17 0.31-0.3 0.7-0.3 0.83 0 0.53-2.91 6.27-4.09 8.04-2.73 4.17-7.42 9-8.73 9-0.09 0-0.33 0.17-0.57 0.37l-0.42 0.39-1.35-0.02h-1.35l-0.64-0.35c-0.37-0.17-1-0.48-1.42-0.65-1.68-0.75-4.72-2.28-5.39-2.73-0.42-0.29-1.05-0.66-1.42-0.86-6.14-3.16-23.02-19.63-27.54-26.86-0.31-0.48-0.68-1.03-0.86-1.2-0.17-0.18-0.54-0.7-0.83-1.18-0.28-0.48-0.61-0.98-0.72-1.09-1.63-1.99-7.2-12.78-7.66-14.9l-0.16-0.7 0.75-0.83c1.24-1.4 4.08-6.22 4.08-6.97 0-0.06 0.13-0.43 0.31-0.8 0.59-1.4 0.81-1.97 1.22-3.28 0.92-2.88 1.57-5.24 2.08-7.58 0.39-1.81 0.85-3.52 1.33-5.04 0.15-0.57 0.3-1.18 0.3-1.38 0-0.18 0.13-0.66 0.31-1.05 0.15-0.39 0.5-1.35 0.74-2.14 2.89-8.98 8.06-16.71 14.81-22.12 0.85-0.68 1.62-1.25 1.68-1.25 0.07 0 0.61-0.35 1.25-0.76 0.96-0.66 3.86-2.14 5.35-2.76 3.32-1.35 5.57-1.98 8.41-2.38 1.02-0.13 1.9-0.3 1.96-0.37 0.16-0.15 6.84 0.09 8.63 0.33zm1.42 13.13c1.44 0.85 2.34 1.68 3.63 3.34l0.96 1.24 0.13 1.31 0.15 1.31 0.33 0.14 0.33 0.1 0.43-0.37c0.64-0.56 1.09-1.74 1.23-3.12l0.13-1.2 0.76-0.37 0.77-0.37 2.51-0.14 2.51-0.13 0.33 0.22 0.32 0.22-0.39 0.66-0.37 0.63v1.35 1.34l0.57 0.76c0.65 0.85 0.59 1.22-0.29 1.66-5.28 2.66-9.17 5.9-9.58 7.99l-0.14 0.64 0.4 0.37 0.37 0.37 1.11-0.13c0.61-0.09 1.29-0.26 1.51-0.37 0.22-0.11 1.24-0.26 2.29-0.33l1.92-0.13 0.86 0.46c0.48 0.24 1.02 0.61 1.22 0.83l0.35 0.41 0.13 1.36 0.11 1.33-1.03 0.87c-0.54 0.48-1.31 1.16-1.68 1.51-0.37 0.33-1.09 0.96-1.62 1.38-3.25 2.62-6.15 7.09-7.16 11.03l-0.33 1.31-0.08 2.64-0.09 2.64 0.41 2.05c0.64 2.95 0.92 4.15 1.27 4.96 0.18 0.4 0.31 0.85 0.31 1.03 0 0.17 0.13 0.63 0.3 1.03 0.18 0.39 0.64 1.74 1.01 3.01 0.39 1.27 0.83 2.64 0.98 3.06 1.51 4.32 1.62 4.98 1.18 7.62-0.63 3.84-1.99 7.78-3.17 9.17l-0.57 0.68h-0.94-0.96l-0.63-0.79c-0.59-0.72-2.1-3.51-2.8-5.22-0.15-0.37-0.43-1.04-0.63-1.52-1.13-2.76-4.61-8.78-5.9-10.29-0.1-0.13-0.37-0.48-0.54-0.77-1.6-2.44-5.57-6.16-13.87-12.93-1.88-1.53-5.13-5-6.29-6.68-1.18-1.75-3.21-5.61-3.21-6.14 0-0.17-0.13-0.7-0.31-1.2-1.07-3.12-1.02-7.45 0.09-10.94 1.81-5.61 5.37-9.15 11.25-11.21l1.29-0.45h1.33c1.35 0 2.88 0.39 4.21 1.04 1.16 0.59 0.86 1.14-0.83 1.53-6.05 1.4-11.2 6.32-12.77 12.19l-0.37 1.33 0.11 2.6 0.1 2.6 0.33 1.11c1.31 4.4 4.35 8.13 10.03 12.32 3.05 2.27 2.99 2.21 4.43 3.39 1.01 0.81 1.94 1.62 3.71 3.27 0.81 0.75 2.95 3.57 2.95 3.87 0 0.11 0.35 0.74 0.79 1.4l0.79 1.18 0.21-0.13 0.22-0.13-0.11-0.7c-0.24-1.38-0.57-2.73-0.78-3.13-0.13-0.21-0.4-0.78-0.59-1.26-0.22-0.48-0.77-1.53-1.23-2.34l-0.85-1.44-1.9-1.95c-1.05-1.07-3.17-2.9-4.74-4.1-4.45-3.41-7.53-6.71-8.49-9.07-0.22-0.54-0.51-1.18-0.62-1.39-0.13-0.22-0.35-1.27-0.5-2.3l-0.26-1.88 0.28-1.63c1.03-5.94 7.26-11.21 13.89-11.73l1.45-0.11 1.18 0.39 1.15 0.37 2.08 0.03 2.07 0.02 1.64-0.64 1.64-0.63 1.14-1.16c1.13-1.13 1.55-1.96 1.28-2.6l-0.11-0.32-0.93 0.41c-0.53 0.22-1.6 0.81-2.41 1.29l-1.46 0.9-1.31 0.26-1.33 0.28-1.36-0.28c-1.55-0.31-2.16-0.61-3.89-1.88-0.65-0.5-2-1.42-2.99-2.05l-1.77-1.16 0.11-0.31c0.13-0.35 5.33-4.26 6.4-4.78 1.31-0.68 1.79-0.77 3.93-0.68l2.08 0.07zm19.35 3.62c0.35 0.18 0.81 0.33 1 0.33 0.55 0 4.33 1.75 5.75 2.64 0.37 0.22 0.81 0.48 0.98 0.57 1.92 0.85 6.77 6.12 7.32 7.89l0.15 0.52-0.52-0.15c-0.27-0.09-0.94-0.35-1.49-0.59-2.31-1.03-3.51-1.44-5.79-1.95l-1.31-0.3-4.26 0.02h-4.25l-0.88 0.24c-0.48 0.15-1.59 0.33-2.44 0.42l-1.6 0.15v-0.35-0.35l1.16-0.59c1.79-0.92 2.14-1.09 3.45-1.7 0.68-0.31 1.31-0.57 1.4-0.57 0.39 0 1.64-1.14 1.64-1.49 0-0.22-0.59-0.94-1.32-1.64-0.72-0.69-1.37-1.5-1.44-1.81l-0.13-0.52 0.35-0.55 0.35-0.54h0.63c0.35 0 0.92 0.15 1.25 0.32zm7.8 11.8c2.64 0.76 1.96 0.98-5.4 1.64-1.31 0.13-2.71 0.3-3.08 0.41l-0.7 0.2-0.32-0.2c-0.18-0.09-0.81-0.61-1.4-1.16l-1.05-0.98 0.31-0.11c0.74-0.26 2.07-0.3 6.13-0.24l4.28 0.09zm-83.21 33.66c0.22 0.69 0.54 1.57 0.7 1.94 0.15 0.35 0.43 1.05 0.65 1.53 1.66 3.93 8.43 14.5 10.86 16.95 0.17 0.17 0.41 0.46 0.52 0.65 0.99 1.71 11.73 12.91 15.05 15.71 0.61 0.5 1.33 1.13 1.64 1.39 0.3 0.27 1.16 0.94 1.9 1.51 0.74 0.57 1.48 1.16 1.64 1.31 0.43 0.39 4.43 3.15 5.52 3.8 1.25 0.74 7.54 3.78 7.82 3.78 0.18 0 0.53 0.17 0.79 0.37l0.46 0.39 0.13 0.9 0.13 0.9-0.35 0.32-0.35 0.35-1.94-0.02-1.95-0.02-0.72 0.76c-1.88 1.95-4.56 5.03-5.17 5.9l-0.31 0.44 0.11 1.46c0.09 1.57 0.48 4.48 0.83 6.27 0.13 0.59 0.3 1.77 0.41 2.62 0.22 1.77 0.68 4 1.1 5.24l0.26 0.88 3.49 3.42c1.92 1.9 4.11 3.98 4.85 4.66l1.38 1.2h0.54 0.53l2.07-1.9c1.14-1.05 3.26-3.08 4.7-4.55l2.66-2.62 0.33-1.2c0.2-0.65 0.46-1.79 0.59-2.51 0.13-0.72 0.37-2.14 0.57-3.17 0.17-1.02 0.41-2.44 0.52-3.16 0.11-0.72 0.29-1.75 0.42-2.3 0.13-0.54 0.24-1.81 0.24-2.84v-1.85l-1.68-1.97c-0.92-1.09-2.28-2.58-3-3.34l-1.31-1.35h-2.12-2.11l-0.24-0.31-0.24-0.28 0.13-1.05 0.15-1.03 0.52-0.63c0.31-0.35 0.64-0.64 0.72-0.64 1.16 0 8.52-7.25 8.52-8.38 0-0.07 0.29-0.53 0.64-1.05 1.35-1.99 3.91-7.62 4.47-9.81 0.31-1.24 0.57-1.48 0.99-0.98l0.26 0.33 0.19 2.47c0.11 1.35 0.31 3.34 0.44 4.43 0.26 2.51 0.26 15.2-0.02 17.36-0.11 0.9-0.31 2.65-0.42 3.89-0.1 1.22-0.26 2.34-0.32 2.45-0.09 0.13-0.22 0.98-0.33 1.92-0.11 0.92-0.31 2.07-0.42 2.55-0.1 0.48-0.37 1.66-0.59 2.63-0.19 0.96-0.48 2.14-0.63 2.62-0.15 0.48-0.46 1.5-0.65 2.29-0.2 0.79-0.48 1.66-0.59 1.97-0.13 0.3-0.31 0.83-0.42 1.2-0.09 0.35-0.5 1.59-0.92 2.73-0.41 1.13-0.83 2.27-0.91 2.51-0.09 0.24-0.42 1.11-0.77 1.96-0.35 0.83-0.67 1.69-0.74 1.86-0.07 0.18-0.22 0.48-0.31 0.66-0.11 0.17-0.37 0.72-0.59 1.2-0.19 0.48-0.45 1.02-0.56 1.2-0.22 0.39-0.96 1.94-1.16 2.4-0.07 0.18-0.48 0.92-0.9 1.64-0.41 0.72-0.85 1.51-0.96 1.75-0.85 1.96-7.27 11.64-8.32 12.55-0.09 0.07-0.81 0.94-1.64 1.97-3.25 3.98-9.37 10.09-12.99 12.97-1.82 1.47-7.84 6.03-7.95 6.03-0.05 0-1.18 0.75-2.51 1.64-1.36 0.9-2.49 1.64-2.56 1.64-0.07 0-0.44 0.24-0.81 0.52-0.39 0.31-0.94 0.64-1.24 0.77-0.31 0.13-0.9 0.46-1.31 0.7-1.23 0.74-4.39 2.42-5.03 2.68-0.17 0.07-0.72 0.37-1.2 0.68-0.48 0.28-1 0.52-1.16 0.55-0.15 0-0.63 0.24-1.09 0.52-0.76 0.48-2.01 1.05-5.94 2.75-2.71 1.18-2.9 1.27-3.93 1.64-0.55 0.2-1.27 0.5-1.59 0.68-0.35 0.17-0.79 0.3-1.01 0.3-0.2 0-0.48 0.11-0.61 0.24-0.13 0.13-0.57 0.31-0.96 0.42-0.42 0.11-1.29 0.39-1.95 0.65-0.65 0.27-1.48 0.55-1.85 0.66-0.88 0.24-2.1 0.68-2.56 0.89-0.22 0.11-0.74 0.29-1.2 0.4-0.46 0.11-1.16 0.3-1.53 0.43-0.39 0.14-1.05 0.35-1.42 0.48-0.39 0.14-1 0.31-1.37 0.42-0.88 0.24-3.21 1.07-4.37 1.55-0.24 0.09-0.98 0.39-1.64 0.66-1.42 0.54-2.49 1-3.34 1.42-0.35 0.17-0.7 0.3-0.81 0.3-0.11 0-0.94 0.44-1.83 0.98-0.92 0.55-1.73 0.99-1.77 0.99-0.31 0-3.65 2.46-5.2 3.82-2.14 1.88-3.47 3.34-5.13 5.66-0.68 0.93-1.62 2.14-2.1 2.66l-0.85 0.96h-1.49-1.48l-0.83-0.37c-2.41-1.05-2.86-1.31-3.67-2.12-0.77-0.76-1.18-1.44-2.3-3.6-0.11-0.2-0.32-0.88-0.52-1.53l-0.35-1.16v-2.42-2.41l-0.37-0.41-0.35-0.39h-1.03c-0.56 0-1.57-0.11-2.2-0.24-0.66-0.11-1.99-0.31-2.99-0.42-0.99-0.11-2.12-0.28-2.52-0.41-0.65-0.2-1.57-0.42-3.84-0.92-0.55-0.11-1.29-0.29-1.64-0.39-0.37-0.11-1.22-0.35-1.88-0.55-2.33-0.66-4.26-1.29-4.47-1.49-0.11-0.08-0.38-0.17-0.59-0.17-0.22 0-0.97-0.28-1.64-0.66-0.68-0.37-1.31-0.65-1.42-0.65-0.9 0-8.17-3.8-11.25-5.85-1.88-1.29-2.73-1.6-3.01-1.16-0.07 0.11-0.44 0.28-0.83 0.37-0.38 0.06-0.99 0.26-1.36 0.41-0.83 0.35-1.92 0.73-3.17 1.1-0.54 0.15-1.52 0.43-2.18 0.65-0.65 0.2-1.97 0.48-2.88 0.64l-1.71 0.28v-0.28c0-0.42 0.88-1.18 4.26-3.76 1.68-1.27 3.1-2.36 3.17-2.45 0.07-0.06 0.46-0.37 0.87-0.65 1.58-1.07 7.32-5.7 8.89-7.17 0.37-0.35 1.82-1.64 3.21-2.86l2.52-2.25 5.08-0.04 5.09-0.07 3.5-0.32c1.92-0.2 4.23-0.46 5.13-0.62 0.9-0.13 2.62-0.39 3.82-0.56 1.2-0.18 2.8-0.46 3.54-0.64 0.74-0.17 1.57-0.33 1.86-0.33 0.46 0 1.66-0.24 4.54-0.91 0.55-0.13 1.38-0.31 1.86-0.4 1.33-0.24 3.01-0.67 3.43-0.89 0.21-0.11 0.74-0.28 1.2-0.39 2.14-0.55 2.84-0.77 3.49-1.03 0.37-0.18 0.88-0.31 1.12-0.31 0.26 0 0.5-0.08 0.59-0.19 0.06-0.11 0.43-0.29 0.83-0.37 0.37-0.07 0.98-0.27 1.35-0.42 0.35-0.15 1.09-0.46 1.64-0.65 1.18-0.46 1.61-0.64 2.62-1.07 0.41-0.18 1.75-0.73 2.93-1.23 1.17-0.5 2.31-1 2.51-1.09 0.19-0.11 0.78-0.39 1.33-0.66 5.92-2.81 12.6-7.33 18.87-12.75 2.47-2.14 9.74-10.64 9.74-11.38 0-0.09 0.24-0.46 0.55-0.85 0.91-1.2 4.52-8.24 4.8-9.37 0.09-0.33 0.24-0.66 0.35-0.72 0.11-0.07 0.2-0.31 0.2-0.53 0-0.24 0.13-0.74 0.3-1.13 0.9-2.19 2.01-7.25 2.63-12.08 0.54-4.19 0.21-11.69-0.62-14.5-0.17-0.55-0.48-1.79-0.7-2.75-0.19-0.97-0.45-1.9-0.54-2.08-0.11-0.17-0.39-0.83-0.63-1.42-1.08-2.53-2.54-5.35-2.78-5.35-0.15 0-0.35 0.26-0.41 0.59l-0.16 0.59 0.29 1.22c0.46 1.99 0.89 4.79 1.11 7.1 0.11 1.2 0.31 2.86 0.44 3.71 0.13 0.83 0.28 2.69 0.35 4.11l0.13 2.58-0.37 3.86c-0.22 2.12-0.53 4.5-0.7 5.29-0.18 0.78-0.31 1.61-0.31 1.83 0 0.24-0.15 0.96-0.35 1.64-0.87 3.1-1.05 3.71-1.46 4.94-0.66 1.98-1 2.9-1.22 3.34-0.11 0.2-0.42 0.81-0.68 1.35-0.26 0.55-0.81 1.58-1.22 2.3-0.4 0.72-0.83 1.53-0.94 1.79-0.42 0.89-3.67 5.52-4.26 6.07-0.15 0.11-0.7 0.81-1.27 1.53-1.09 1.42-5.72 6-7.49 7.42-2.47 1.97-5.5 4.18-7.82 5.62-0.83 0.52-1.75 1.11-2.07 1.31-0.33 0.22-0.79 0.48-1.03 0.61-0.24 0.13-1.03 0.57-1.75 0.98-1.53 0.85-2.25 1.23-5.24 2.62-2.88 1.34-3.34 1.55-4.37 1.93-1.35 0.5-2.77 1.04-3.49 1.35-1.2 0.52-3.41 1.29-5.03 1.77-0.59 0.17-1.37 0.41-1.74 0.52-3.93 1.18-5.53 1.62-7.41 1.97-0.57 0.11-1.35 0.3-1.74 0.41-0.38 0.13-1.32 0.27-2.08 0.29l-1.4 0.06-0.08-0.24c-0.05-0.11 0.43-0.46 1.07-0.74 7.99-3.52 14.91-7.69 21.36-12.86 2.03-1.64 5.91-5.16 7.55-6.84l1.58-1.6 1.04-0.41c1.62-0.61 2.54-1 3.15-1.33 0.3-0.16 0.89-0.46 1.31-0.7 0.41-0.22 0.81-0.44 0.87-0.53 0.07-0.06 0.53-0.32 1.05-0.59 0.53-0.26 1.07-0.59 1.2-0.72 0.16-0.11 0.94-0.7 1.79-1.31 3.78-2.66 7.91-7.6 9.81-11.66 0.46-0.96 0.92-1.92 1.03-2.12 0.26-0.52 0.26-1.27-0.02-1.27-0.14 0-0.29 0.16-0.35 0.33-0.09 0.18-0.24 0.33-0.4 0.33-0.13 0-0.43 0.28-0.67 0.61-4.79 6.68-14.05 13.74-21.41 16.32-0.59 0.22-1.4 0.52-1.79 0.67-0.37 0.18-0.81 0.31-0.96 0.31-0.15 0-0.77 0.13-1.38 0.31-0.61 0.17-1.85 0.48-2.73 0.67l-1.64 0.35-4.71 0.13c-4.65 0.13-5.9 0.05-5.9-0.37 0-0.24 1.73-1.4 3.19-2.16 0.98-0.52 3.28-2.32 4.98-3.91 1.09-1 5.37-6.36 5.37-6.71 0-0.08 0.31-0.52 0.66-0.98 0.37-0.46 0.65-1.02 0.65-1.29v-0.46h-0.28c-0.15 0-1.47 1.16-2.91 2.56-3.6 3.56-6.59 6.14-7.73 6.68-0.39 0.2-0.81 0.46-2.4 1.49-1.25 0.81-3.15 1.75-5.24 2.6-0.66 0.26-1.4 0.59-1.64 0.72-0.24 0.13-0.79 0.3-1.2 0.39-0.42 0.09-1.16 0.26-1.64 0.39-0.48 0.11-1.62 0.38-2.51 0.57l-1.64 0.33h-2.51-2.51l-1.97-0.35c-1.07-0.17-2.05-0.41-2.16-0.52l-0.18-0.18 1.93-1.83c5.24-4.96 7.55-7.8 10.17-12.52 0.13-0.24 0.33-0.59 0.44-0.76 0.09-0.18 0.26-0.55 0.37-0.81 0.13-0.24 0.33-0.52 0.44-0.61 0.13-0.07 0.24-0.42 0.24-0.77v-0.61l-0.31-0.11c-0.35-0.13-0.78 0.24-0.78 0.66 0 0.15-0.09 0.28-0.18 0.28-0.11 0-0.43 0.35-0.74 0.77-2.1 2.95-10.46 11.29-14.15 14.08-0.55 0.42-1.03 0.81-1.1 0.9-0.13 0.15-3.82 2.93-4.91 3.69-0.44 0.31-0.92 0.66-1.05 0.77-0.37 0.32-5.07 3.4-6.33 4.17-0.59 0.35-1.33 0.8-1.64 1-0.33 0.22-0.74 0.46-0.92 0.55-0.17 0.08-1.16 0.65-2.18 1.26-1.03 0.62-2.34 1.38-2.95 1.69-0.59 0.3-1.64 0.87-2.29 1.24-0.66 0.37-2.34 1.22-3.72 1.9-1.37 0.68-2.66 1.31-2.84 1.42-0.17 0.11-0.54 0.31-0.83 0.42-0.28 0.11-1.07 0.48-1.74 0.78-1.64 0.79-3.91 1.82-4.85 2.23-0.42 0.17-0.94 0.41-1.14 0.5-0.61 0.31-2.14 0.85-3.25 1.16l-1.01 0.26-0.48-0.15-0.46-0.18v-0.76c0-0.39 0.16-1.03 0.33-1.35 0.18-0.35 0.33-0.79 0.33-0.99 0-0.17 0.15-0.52 0.33-0.76 0.17-0.22 0.32-0.59 0.32-0.81 0-0.24 0.14-0.68 0.31-0.98 0.18-0.33 0.96-1.92 1.77-3.54 0.79-1.62 1.53-3.1 1.64-3.28 5-8.36 4.74-7.9 5.81-9.5 1.4-2.09 1.92-2.84 2.12-2.9 0.08-0.05 0.15-0.18 0.15-0.31 0-0.13 0.28-0.59 0.63-1.03 0.33-0.43 1.27-1.76 2.08-2.97 0.81-1.2 2.62-3.71 4.02-5.61l2.55-3.45 0.33 0.07 0.33 0.06-0.05 0.53c-0.04 0.3-0.19 1.02-0.37 1.63-0.2 0.59-0.48 1.77-0.68 2.6l-0.34 1.51 0.37 1.18 0.37 1.18 0.81 0.63 0.83 0.66h1.37l1.4-0.02 1-0.7c0.57-0.4 1.64-1.27 2.41-1.97 1.74-1.62 7.27-6.84 8.08-7.64 0.33-0.33 1.02-0.94 1.55-1.36 3.01-2.42 5.33-4.23 6.25-4.87 0.56-0.41 1.52-1.11 2.14-1.57 2.86-2.14 9.3-5.68 14.06-7.71 0.42-0.18 1.14-0.48 1.6-0.68 0.45-0.19 1-0.35 1.2-0.35 0.22 0 0.48-0.08 0.61-0.19 0.2-0.18 2.16-0.81 4.67-1.47 0.79-0.19 1.84-0.5 2.36-0.65 0.5-0.18 1.12-0.31 1.36-0.31 0.21 0 0.63-0.09 0.91-0.19 0.29-0.11 1.44-0.42 2.58-0.68 1.14-0.26 2.51-0.61 3.06-0.77 0.54-0.15 1.57-0.45 2.29-0.65 0.72-0.2 1.62-0.5 2.01-0.68 0.37-0.17 0.81-0.3 0.96-0.3 0.15 0 0.68-0.14 1.18-0.31 0.48-0.17 1.46-0.48 2.19-0.68 0.72-0.22 1.61-0.52 2-0.7 0.38-0.15 0.73-0.28 0.79-0.28 0.15 0 2.71-1.16 4.52-2.05 0.79-0.37 2.4-1.34 3.61-2.12 1.2-0.79 2.42-1.57 2.73-1.73 1.37-0.72 8.08-7.88 8.08-8.62 0-0.16 0.41-0.66 0.94-1.16 0.19-0.2 0.37-0.53 0.37-0.72 0-0.2 0.15-0.42 0.33-0.51l0.32-0.1v-0.68-0.66h-0.41-0.42l-0.74 0.92c-0.7 0.87-3.36 3.54-4.46 4.48-0.26 0.22-0.98 0.85-1.59 1.42-0.63 0.59-1.22 1.05-1.29 1.05-0.09 0-0.41 0.24-0.72 0.52-0.85 0.79-3.25 2.42-4.8 3.25-2.17 1.18-2.62 1.4-3.91 1.97-0.66 0.31-1.66 0.74-2.23 1.01-0.57 0.24-1.16 0.45-1.31 0.45-0.15 0-0.48 0.16-0.7 0.33-0.24 0.18-0.59 0.33-0.81 0.33-0.2 0-0.65 0.15-0.98 0.33-0.35 0.17-0.9 0.32-1.22 0.32-0.33 0-0.64 0.09-0.7 0.2-0.07 0.11-0.51 0.26-0.94 0.33-0.46 0.09-1.23 0.28-1.71 0.44-1.09 0.37-2.86 0.87-4.69 1.33-0.79 0.19-1.71 0.43-2.08 0.54-0.35 0.11-1.2 0.29-1.85 0.42-0.66 0.11-1.49 0.3-1.82 0.44-0.35 0.13-0.89 0.24-1.24 0.24-0.35 0-0.68 0.08-0.74 0.19-0.09 0.11-0.55 0.26-1.07 0.35-1.14 0.18-3.08 0.72-4.02 1.12-0.37 0.17-0.83 0.3-1.01 0.3-0.17 0-0.61 0.15-0.94 0.33-0.35 0.17-0.81 0.33-1 0.33-0.2 0-0.42 0.08-0.5 0.19-0.07 0.11-0.44 0.29-0.83 0.37-0.88 0.18-1.53 0.46-5.07 2.19-4.13 2.01-6.09 3.12-9.72 5.52-2.45 1.6-6.2 4.33-7.54 5.46-0.37 0.31-1.2 1.01-1.85 1.56-2.34 1.96-3.91 3.42-7.65 7.12l-3.84 3.77-0.61 0.16-0.59 0.15-0.26-0.26-0.24-0.24 0.37-1.16c0.19-0.66 0.37-1.42 0.37-1.75 0-0.3 0.09-0.61 0.19-0.7 0.11-0.06 0.27-0.43 0.35-0.83 0.22-0.96 3.37-7.6 5.03-10.52 0.41-0.72 0.85-1.51 0.98-1.75 0.24-0.46 0.39-0.74 1.38-2.25 0.32-0.52 0.59-0.98 0.59-1.03 0-0.08 1.07-1.66 3.45-5.04 0.67-0.99 1.64-2.25 2.12-2.82 3.86-4.65 4.06-4.87 6.59-7.36 2.71-2.69 2.97-2.93 4.98-4.54 0.81-0.66 1.64-1.36 1.84-1.55 0.63-0.64 7.71-5.66 7.97-5.66 0.04 0 0.74-0.44 1.57-0.98 0.81-0.55 1.55-0.99 1.66-0.99 0.09 0 0.68-0.3 1.31-0.7 1.51-0.89 6.12-3.23 6.38-3.23 0.11 0 0.85-0.3 1.64-0.68 2.05-0.96 2.12-0.98 4.06-1.72 0.94-0.35 2.05-0.72 2.45-0.79 0.39-0.06 0.78-0.22 0.85-0.32 0.06-0.11 0.28-0.2 0.48-0.2 0.19 0 0.65-0.15 1-0.33 0.33-0.17 0.79-0.33 0.99-0.33 0.19 0 0.63-0.15 0.98-0.32 0.33-0.18 0.94-0.33 1.31-0.33 0.37 0 0.87-0.13 1.11-0.31 0.24-0.15 0.7-0.35 1.05-0.43 0.33-0.07 0.59-0.29 0.59-0.44 0-0.46-0.96-0.61-2.01-0.33-0.52 0.13-1.57 0.31-2.36 0.42-0.78 0.08-1.66 0.26-1.96 0.37-0.31 0.13-1.01 0.28-1.58 0.37-0.56 0.09-1.09 0.24-1.15 0.33-0.05 0.11-0.57 0.26-1.14 0.35-0.59 0.08-1.13 0.21-1.27 0.32-0.1 0.09-0.56 0.24-0.98 0.33-0.41 0.09-0.85 0.24-0.98 0.31-0.11 0.08-0.9 0.39-1.75 0.65-0.83 0.26-1.83 0.64-2.23 0.81-0.37 0.18-0.83 0.31-1.02 0.31-0.2 0-0.53 0.08-0.75 0.21-0.19 0.11-0.72 0.35-1.13 0.53-3.69 1.55-5.64 2.53-8.39 4.19-1.16 0.7-2.27 1.4-2.49 1.51-8.08 4.8-18 14.35-24.09 23.15-0.39 0.59-0.79 1.14-0.85 1.2-0.07 0.07-0.61 0.88-1.2 1.82-1.03 1.61-3.89 5.24-5.11 6.5-1.07 1.07-2.32 2.47-2.86 3.17-0.31 0.37-1.77 2.14-3.24 3.89-1.48 1.77-3.38 4.1-4.21 5.22-0.83 1.11-1.57 2.1-1.66 2.23-0.11 0.11-0.5 0.63-0.9 1.11-0.37 0.5-0.7 1.03-0.7 1.16 0 0.15-0.15 0.3-0.32 0.37-0.18 0.09-0.33 0.24-0.33 0.35 0 0.13-0.26 0.59-0.59 1.03-0.35 0.43-0.7 0.96-0.83 1.15-0.11 0.2-1.16 1.77-2.32 3.5-3.86 5.79-5.72 8.93-8.27 14.15-1.05 2.16-1.27 2.64-2.04 4.43-0.28 0.68-0.72 2.06-1.22 4-0.78 2.95 0.29 5.51 2.82 6.77 1.35 0.68 3.78 1.4 4.69 1.4 0.73 0 1.64 0.52 1.64 0.92 0 0.13-1.07 1.33-2.36 2.66-1.31 1.33-4.17 4.33-6.37 6.64-2.21 2.32-4.26 4.41-4.57 4.65-0.3 0.27-2.18 2.03-4.17 3.98-6.29 6.14-9.61 9.3-11.99 11.36-1.27 1.11-2.6 2.29-2.97 2.66-0.39 0.35-1.42 1.27-2.32 2.01-0.89 0.72-1.81 1.51-2.05 1.75-1.07 0.96-3.17 2.68-4.48 3.69-0.78 0.59-1.66 1.29-1.96 1.55-0.57 0.5-2.19 1.64-5.24 3.71-1.03 0.68-1.9 1.31-1.97 1.38-0.07 0.09-0.26 0.22-0.44 0.28-0.17 0.09-0.61 0.35-0.98 0.59-1.27 0.83-2.73 1.36-2.73 0.98 0-0.67 2.95-4.71 6.44-8.86 0.35-0.42 1.05-1.25 1.53-1.84 0.48-0.59 1.18-1.42 1.53-1.85 1.03-1.18 2.32-2.78 3.32-4.11 0.5-0.66 1.29-1.59 1.75-2.1 0.78-0.83 2.2-2.57 3.56-4.37 1.92-2.53 5.59-7.27 5.85-7.53 0.15-0.18 0.55-0.72 0.85-1.2 0.33-0.5 0.99-1.44 1.49-2.1 0.89-1.18 1.86-2.55 4.13-5.9 0.61-0.89 1.18-1.68 1.26-1.7 0.11-0.04 0.18-0.17 0.18-0.28 0-0.11 0.43-0.83 0.98-1.64 0.55-0.79 0.98-1.49 0.98-1.55 0-0.09 0.13-0.31 0.31-0.48 0.15-0.2 0.68-1.05 1.14-1.88 0.43-0.85 1-1.84 1.22-2.18 0.22-0.38 0.46-0.81 0.52-0.99 0.18-0.43 1.29-2.84 2.08-4.48 0.35-0.72 0.63-1.46 0.63-1.65 0-0.18 0.15-0.53 0.33-0.77 0.17-0.22 0.33-0.61 0.33-0.87 0-0.24 0.15-0.64 0.32-0.88 0.18-0.22 0.33-0.59 0.33-0.78 0-0.22 0.13-0.7 0.31-1.1 0.17-0.39 0.48-1.15 0.67-1.7 0.22-0.54 0.53-1.31 0.68-1.7 0.18-0.37 0.44-1.03 0.61-1.42 0.16-0.37 0.46-1.14 0.68-1.68 0.41-1.07 0.61-1.55 1.62-3.78 0.37-0.81 0.67-1.51 0.67-1.57 0-0.14 2.56-5.57 2.84-6.01 0.11-0.18 0.59-1.12 1.09-2.08 0.51-0.96 0.99-1.9 1.1-2.07 0.11-0.18 0.24-0.48 0.3-0.66 0.09-0.17 0.35-0.67 0.59-1.09 0.26-0.41 0.72-1.24 1.05-1.81 0.68-1.25 0.83-1.51 1.62-2.71 0.32-0.52 0.59-0.98 0.59-1.05 0-0.06 0.26-0.52 0.59-1.05 0.32-0.5 0.7-1.09 0.83-1.28 0.11-0.2 0.63-1.05 1.15-1.86 0.51-0.81 1.05-1.68 1.2-1.92 0.14-0.24 0.57-0.83 0.92-1.34 0.37-0.5 0.81-1.13 0.99-1.42 0.56-0.85 5.52-7.49 6.02-8.05 0.51-0.55 1.42-1.66 3.04-3.63 4.76-5.77 13.98-14.66 19.74-19.05 2.17-1.66 2.8-2.14 4.7-3.64 1-0.79 5.02-3.59 5.98-4.15 0.2-0.13 1.21-0.77 2.23-1.44 2.54-1.66 4.09-2.58 7.25-4.31 0.59-0.32 1.84-1 2.76-1.5 1.41-0.79 6.33-3.26 8.67-4.33 0.37-0.17 1.61-0.76 2.77-1.31 1.16-0.55 2.23-0.98 2.34-0.98 0.13 0 0.41-0.09 0.63-0.22 0.5-0.28 4-1.6 5.61-2.1 0.72-0.22 1.51-0.52 1.75-0.67 0.24-0.16 0.59-0.29 0.79-0.29 0.19 0 0.65-0.15 0.98-0.33 0.35-0.17 0.79-0.32 0.96-0.32 0.2 0 0.44-0.09 0.55-0.2 0.13-0.11 0.56-0.31 0.98-0.42 1.07-0.3 3.34-1.11 4.48-1.59 0.48-0.2 2.33-0.92 3.71-1.44 0.48-0.2 1.18-0.48 1.57-0.63 0.37-0.18 0.81-0.31 0.99-0.31 0.15 0 0.48-0.15 0.69-0.33 0.24-0.17 0.59-0.33 0.79-0.33 0.35 0 1.31-0.39 2.25-0.89 0.22-0.11 0.96-0.53 1.64-0.87 1.66-0.9 3.25-1.95 5.48-3.63 2.16-1.62 2.14-1.62 2.71 0.07zm54.6 54.03l0.2 0.18-0.81 1.65-0.83 1.66h-3.1-3.1l-0.31-0.39c-0.37-0.44-1.51-2.75-1.51-3.08 0-0.39 9.05-0.41 9.46-0.02zm-10.48 1.42c0.11 0.35 0.35 0.98 0.5 1.38 0.18 0.39 0.31 0.98 0.31 1.31v0.61l-0.94 1.07-0.96 1.07-1.55-0.77c-0.88-0.39-1.62-0.87-1.69-1.02l-0.11-0.26 1.71-2.08 1.68-2.05 0.44 0.04 0.43 0.04zm16.03 3.59c-0.08 0.5-2.94 1.85-3.49 1.63-0.35-0.13-1.9-2.42-1.9-2.79 0-0.44 0.87-2.36 1.29-2.84l0.35-0.39 1.9 2.03c1.05 1.13 1.9 2.18 1.85 2.36zm-6.46 0.52c0.76 0.74 1.44 1.57 1.77 2.23l0.3 0.57-0.39 2.22c-0.22 1.23-0.5 3.06-0.63 4.09-0.13 1.03-0.33 1.94-0.44 2.05-0.11 0.13-0.2 0.42-0.2 0.64v0.41l-1.9 1.83c-1.04 1.01-2.05 1.84-2.25 1.84-0.37 0-3.34-2.56-3.9-3.36-0.35-0.46-0.49-1.12-1.01-4.72-0.17-1.27-0.41-2.73-0.52-3.28-0.13-0.54-0.22-1.29-0.24-1.66v-0.68l1.26-1.33 1.25-1.35h3.19 3.19zm-12.76 2.01c0.59 0.28 1.25 0.7 1.44 0.92l0.35 0.41 0.22 1.51c0.13 0.85 0.37 2.47 0.57 3.6 0.17 1.14 0.39 2.45 0.48 2.88l0.13 0.83-0.52 0.44c-0.29 0.22-0.86 0.53-1.25 0.68l-0.74 0.24-0.22-0.22c-0.11-0.11-0.31-0.79-0.39-1.49-0.2-1.46-0.55-3.4-0.99-5.65-0.52-2.69-0.61-4.7-0.19-4.7 0.02 0 0.52 0.24 1.11 0.55zm19.59-0.37c0.07 0.11 0.02 0.72-0.09 1.37-0.13 0.66-0.28 1.58-0.34 2.06-0.35 2.66-1.42 8.01-1.64 8.27l-0.18 0.2-0.98-0.5c-0.57-0.26-1.11-0.68-1.25-0.92l-0.21-0.41 0.43-2.34c0.22-1.29 0.48-2.91 0.57-3.61 0.09-0.69 0.26-1.63 0.42-2.07l0.28-0.79 1.29-0.7c1.42-0.78 1.53-0.83 1.7-0.56zm-14.28 13.36c0.54 0.48 1.31 1.16 1.7 1.47 0.39 0.32 0.88 0.85 1.05 1.18l0.31 0.61v1.66 1.66l-0.31-0.07c-0.17-0.04-1.25-0.96-2.36-2.03-1.11-1.09-2.55-2.45-3.19-3.01-1.18-1.1-1.4-1.6-0.74-1.84 0.2-0.06 0.52-0.26 0.7-0.39 0.85-0.72 1.4-0.57 2.84 0.76zm10.79-0.63l0.78 0.46-0.43 0.61c-0.68 0.96-6.16 6.12-6.38 5.98-0.09-0.06-0.18-0.96-0.18-1.98v-1.88l1.05-1.01c0.57-0.54 1.44-1.37 1.97-1.83l0.92-0.81h0.74c0.41 0 1.11 0.2 1.53 0.46zm-125.46 19.59c0.55 0.15 1.79 0.42 2.8 0.59l1.79 0.33 2.36-0.02c1.29 0 2.84-0.09 3.43-0.2 0.61-0.13 1.61-0.28 2.25-0.35l1.13-0.15v0.3c0 0.24-2.25 1.95-3.89 2.93-0.19 0.13-0.96 0.59-1.66 1.05-0.69 0.46-1.48 0.94-1.74 1.05-0.27 0.11-0.81 0.41-1.23 0.65-2.01 1.23-3.99 2.25-7.09 3.69-1.08 0.51-2.6 1.23-3.39 1.6-1.92 0.89-2.51 1.13-5.57 2.27-0.48 0.17-1.16 0.44-1.53 0.59-0.81 0.33-4.83 1.59-6.38 2.01-3.95 1.07-5.24 1.37-6.61 1.61-0.55 0.11-1.27 0.29-1.6 0.42-0.35 0.13-0.94 0.24-1.33 0.24-0.39 0-1.01 0.11-1.38 0.22-0.83 0.3-3.99 0.83-6.68 1.13l-2.14 0.24-0.35-0.34-0.35-0.35 0.96-0.42c0.53-0.24 1.51-0.65 2.16-0.92 0.66-0.26 1.29-0.56 1.42-0.67 0.11-0.11 0.33-0.2 0.48-0.2 0.57 0 10.44-4.78 12.96-6.27 2.18-1.31 2.07-1.24 3.82-2.16 1.92-1.01 10-6.33 11.44-7.54 2.36-2.01 2.8-2.09 5.92-1.33zm35.38 0.57c0 1.35-12.16 10.18-18.67 13.5-2.64 1.35-5.22 2.64-5.94 2.95-0.39 0.15-1.09 0.45-1.53 0.65-0.46 0.2-1.11 0.48-1.48 0.63-0.35 0.14-1.01 0.42-1.42 0.59-0.92 0.4-2.06 0.79-2.95 1.03-0.85 0.24-1.99 0.63-2.91 1.01-0.39 0.17-0.94 0.3-1.2 0.3-0.26 0.02-0.72 0.15-1.03 0.33-0.3 0.17-0.76 0.3-1.04 0.33-0.29 0-0.97 0.13-1.53 0.3-3.02 0.9-7.41 1.12-13.96 0.7-3.01-0.2-6.36-0.35-7.43-0.37-1.04 0-2.11-0.09-2.33-0.17l-0.42-0.16 0.77-0.48c0.41-0.26 1.05-0.48 1.37-0.48 0.33 0 1.29-0.15 2.17-0.33 0.85-0.19 2.29-0.5 3.18-0.67 1.6-0.33 3.11-0.72 4.92-1.29 0.48-0.16 1.46-0.44 2.18-0.66 0.72-0.22 1.64-0.52 2.03-0.67 0.4-0.18 0.9-0.31 1.14-0.31 0.22 0 0.46-0.09 0.55-0.2 0.06-0.11 0.43-0.28 0.83-0.37 0.37-0.06 1.04-0.28 1.46-0.48 0.81-0.35 0.94-0.39 2.84-1.16 0.65-0.26 2.71-1.2 4.52-2.09 1.83-0.88 3.43-1.6 3.56-1.6 0.11 0 0.22-0.08 0.22-0.19 0-0.11 0.26-0.31 0.61-0.44 0.7-0.26 3.49-1.81 4.74-2.62 0.48-0.31 0.98-0.61 1.09-0.68 0.13-0.06 0.94-0.61 1.81-1.2 0.9-0.61 1.77-1.2 1.97-1.31 0.22-0.13 0.81-0.57 1.33-0.98 0.55-0.42 1.33-0.99 1.75-1.27 0.41-0.28 1.05-0.79 1.38-1.11l0.61-0.57 6.83-0.02h6.82l0.98-0.35c0.55-0.2 1.25-0.35 1.59-0.37l0.59-0.03zm-69.01 24.97c0.17 0.04 1.31 0.17 2.51 0.28 1.2 0.11 3.12 0.31 4.26 0.42 1.13 0.13 2.99 0.24 4.1 0.24h2.03l-0.06 0.48-0.07 0.48-1.31 1.07c-0.72 0.59-2.49 2.01-3.93 3.17-1.44 1.15-2.66 2.16-2.73 2.25-0.06 0.06-0.78 0.65-1.64 1.31-0.83 0.63-1.72 1.33-1.98 1.55-1.31 1.15-11.19 8.67-13.26 10.11-0.68 0.48-2.05 1.44-3.06 2.14-0.98 0.7-2.42 1.72-3.21 2.25-0.79 0.54-2.16 1.48-3.08 2.12-0.92 0.63-1.81 1.22-1.99 1.35-0.19 0.11-1.46 0.96-2.81 1.88-2.17 1.44-3.04 2.01-4.96 3.15-0.2 0.13-0.96 0.61-1.68 1.09-1.64 1.07-2.1 1.35-2.52 1.55-0.26 0.13-2.64 1.5-3.93 2.27-2.16 1.29-4.58 2.12-4.58 1.57 0-0.19 0.78-1.02 1.66-1.79 0.34-0.3 1.33-1.13 2.16-1.88 0.85-0.72 1.79-1.5 2.12-1.77 0.32-0.24 1.15-0.94 1.85-1.55 0.7-0.61 1.77-1.53 2.36-2.03 4.81-4.04 9.26-8.25 19.44-18.43 3.36-3.37 6.6-6.71 7.21-7.43 1.02-1.27 2.58-2.97 4.65-5.17l0.96-1.05 0.59 0.13c0.31 0.06 0.72 0.17 0.9 0.24zm91.38 28.5c-0.07 0.28-0.79 1.22-1.59 2.12-3.02 3.34-5.18 6.77-6.8 10.72-0.67 1.66-1 2.1-1.85 2.49l-0.72 0.35h-1.53-1.55l-0.83-0.48c-1.93-1.11-4.87-5.15-4.87-6.7v-0.66l0.72-0.52c0.37-0.29 1.22-0.79 1.87-1.12 0.66-0.35 1.36-0.7 1.53-0.78 0.83-0.44 3.32-1.53 3.5-1.53 0.11 0 0.48-0.13 0.83-0.31 0.33-0.17 0.98-0.46 1.44-0.65 0.44-0.2 1.14-0.48 1.53-0.66 0.37-0.15 1.13-0.46 1.68-0.67 0.55-0.2 1.31-0.51 1.7-0.68 0.4-0.18 0.88-0.31 1.05-0.31 0.2 0 0.66-0.13 1.03-0.3 0.68-0.29 2.16-0.7 2.73-0.77l0.28-0.02zm-22.14 12.78c0.98 1.61 1.98 3.1 2.79 4.1 0.09 0.11 0.46 0.66 0.83 1.2 0.37 0.55 1.12 1.62 1.64 2.41 0.55 0.78 1.05 1.57 1.14 1.74 0.08 0.18 0.24 0.49 0.37 0.66 0.48 0.74 3.34 5.59 3.53 6.01 0.22 0.45 0.42 0.8 1.29 2.18 0.31 0.48 0.64 1.03 0.7 1.2 0.09 0.18 0.46 0.81 0.83 1.42 0.35 0.59 0.81 1.38 0.99 1.75 0.17 0.35 0.65 1.24 1.07 1.96 1.41 2.54 2.11 3.94 2.4 4.9l0.3 0.94-0.19 0.52c-0.31 0.76-0.96 1.33-2.36 2.03-1.2 0.61-1.66 0.83-4.52 2.1-0.72 0.3-1.58 0.72-1.9 0.89l-0.57 0.31h-1.4-1.4l-1.18-0.42c-1.94-0.69-2.53-1.07-3.77-2.4l-1.18-1.29-0.33-0.94c-0.18-0.52-0.57-1.66-0.83-2.49-0.29-0.85-0.64-1.83-0.79-2.22-0.17-0.38-0.3-0.88-0.3-1.1 0-0.21-0.09-0.5-0.22-0.63-0.11-0.11-0.31-0.65-0.42-1.18-0.11-0.54-0.3-1.29-0.41-1.64-0.13-0.37-0.4-1.24-0.59-1.96-0.31-1.2-0.55-2.03-1.31-4.7q-0.79-2.74-1.31-4.69c-0.2-0.72-0.46-1.62-0.59-1.97-0.13-0.37-0.29-1.07-0.33-1.57l-0.11-0.94 0.63-0.81c0.35-0.46 0.77-1.05 0.94-1.29 0.57-0.83 3.13-4.1 3.48-4.48 0.19-0.19 0.56-0.61 0.83-0.93 0.76-0.88 1-0.73 2.25 1.33zm13.08 5.15c0.13 0.18 0.72 1.23 1.31 2.36 0.57 1.14 1.31 2.49 1.64 3.04 0.3 0.54 0.63 1.13 0.72 1.31 0.09 0.17 0.57 1.02 1.07 1.88 0.5 0.87 1.29 2.25 1.75 3.05 1.22 2.25 1.37 2.54 1.83 3.26 0.24 0.35 0.52 0.85 0.66 1.09 0.13 0.24 0.41 0.72 0.65 1.09 0.24 0.35 0.52 0.85 0.66 1.09 0.13 0.24 0.39 0.7 0.61 1.03 0.19 0.33 0.76 1.2 1.22 1.97 4.28 6.9 5.64 8.23 10.29 10.24 2.2 0.94 7.05 1.48 13.65 1.51 6.9 0.04 10.09 0.46 12.49 1.63 1.31 0.64 2.32 1.53 2.05 1.8-0.06 0.08-5.87 0.13-12.86 0.08l-12.71-0.04-1.31-0.33c-2.01-0.5-3.65-1-4.41-1.33-0.38-0.15-0.79-0.28-0.92-0.28-0.22 0-1.29-0.44-2.43-0.99-2.59-1.22-5.7-1.66-9.93-1.37l-1.95 0.15-0.28-0.24c-0.46-0.37-0.35-0.55 0.74-1.07 0.55-0.26 1.62-1.09 2.38-1.84l1.38-1.33 0.06-1.09c0.09-1.44-0.13-3.52-0.48-4.46-0.39-1-2.33-4.95-2.86-5.78-0.22-0.37-0.5-0.86-0.63-1.1-0.11-0.24-0.31-0.59-0.42-0.76-0.48-0.76-2.14-3.63-2.27-3.93-0.09-0.18-0.35-0.63-0.59-0.98-0.24-0.38-0.52-0.86-0.63-1.1-0.11-0.24-0.98-1.74-1.97-3.32-0.96-1.59-1.94-3.27-2.18-3.75l-0.44-0.85 0.26-0.24c0.53-0.42 1.36-0.66 2.47-0.66l1.14-0.02zm-26.54 1.94l1.27 0.24 0.41 0.96c0.22 0.55 0.42 1.18 0.42 1.42 0 0.26 0.15 1.01 0.35 1.68 0.17 0.68 0.48 1.77 0.65 2.43 0.2 0.65 0.46 1.68 0.64 2.29 0.15 0.59 0.45 1.73 0.65 2.51 0.22 0.79 0.53 1.88 0.68 2.45 0.17 0.59 0.44 1.51 0.61 2.08 0.87 3.05 1.07 3.73 1.31 4.32 0.37 0.9 0.79 2.05 1.01 2.84 0.1 0.35 0.39 1.2 0.65 1.86 0.26 0.65 0.52 1.39 0.59 1.63 0.2 0.68 1.51 2.58 2.21 3.21 0.69 0.62 4.63 2.58 5.15 2.58 0.18 0 0.66 0.13 1.05 0.31 0.39 0.17 1.55 0.46 2.58 0.65l1.85 0.35h7.49 7.52l1.22 0.35c2.43 0.68 4.67 2.12 4.28 2.73l-0.11 0.2-12.71-0.02h-12.71l-1.09-0.2c-0.59-0.11-1.58-0.26-2.19-0.35-1.02-0.11-2.31-0.46-4.04-1.07-3.54-1.24-5.15-1.24-8.73 0-0.42 0.15-1.45 0.44-2.3 0.61l-1.53 0.35-2.99 0.09c-1.66 0.04-3.12 0-3.25-0.07l-0.24-0.17 0.13-0.44c0.17-0.52 2.29-2.01 2.9-2.01 0.22-0.02 0.64-0.15 0.94-0.33 0.31-0.17 0.85-0.3 1.2-0.32 0.7 0 2.47-0.51 3.45-1.01 0.35-0.17 0.72-0.3 0.83-0.3 0.14 0 0.75-0.4 1.38-0.88l1.14-0.87 0.45-0.92c0.27-0.52 0.59-1.42 0.75-2.01l0.26-1.07-0.37-1.66c-0.22-0.92-0.53-2.18-0.7-2.82-0.18-0.61-0.44-1.66-0.61-2.29-0.18-0.61-0.46-1.7-0.66-2.4-0.17-0.68-0.48-1.77-0.65-2.4-0.42-1.55-1.01-3.59-1.34-4.63-0.13-0.48-0.43-1.47-0.63-2.19-0.22-0.72-0.52-1.75-0.68-2.29-0.17-0.55-0.37-1.31-0.43-1.68-0.09-0.4-0.24-0.77-0.35-0.83-0.11-0.09-0.2-0.4-0.2-0.72-0.02-0.33-0.15-0.83-0.33-1.14-0.17-0.31-0.3-0.72-0.32-0.94v-0.37h0.94c0.52 0 1.52 0.11 2.2 0.26z"/>
27
+ <path class="s1" d="m284.02 22.01c-1.15 0.48-2.29 1.46-2.77 2.38l-0.35 0.7v1.07c0 5.24 8.23 6.14 9.06 0.98l0.16-0.91-0.27-1.2-0.24-1.23-0.67-0.65c-1.42-1.42-3.19-1.84-4.92-1.14zm1.12 1.81l0.57 0.44v0.46c0 1.07-0.94 1.53-1.86 0.92l-0.55-0.35v-0.53c0-0.5 0.68-1.39 1.07-1.39 0.09 0 0.44 0.19 0.77 0.45z"/>
28
+ </g>
29
+ </g>
30
+ <g>
31
+ <path class="s2" d="m36.98 288h11.03v34.49l36.62-34.49h14.22l-40.49 38.04 43.38 43.56h-14.53l-39.2-39.3v39.3h-11.03zm112.45 0h12.52l31.09 81.6h-11.47l-7.43-20.93h-36.78l-7.43 20.93h-11.65zm6.24 10.88l-14.98 40.6h30zm64.02-10.87h28.22q12.62 0 19.44 5.24 6.83 5.25 6.83 14.92 0 7.5-3.5 11.93-3.49 4.42-10.27 5.51 8.15 1.75 12.66 7.31 4.51 5.54 4.51 13.84 0 10.94-7.44 16.9-7.43 5.95-21.16 5.95h-29.29zm11.04 9.07v24.59h16.35q8.08 0 12.03-3.02 3.97-3.04 3.97-9.27 0-6.17-3.97-9.23-3.95-3.07-12.03-3.07zm0 33.57v29.88h17.71q8.9 0 13.19-3.69 4.31-3.69 4.31-11.27 0-7.67-4.31-11.28-4.29-3.64-13.19-3.64zm73.5-42.64h11.04v34.49l36.62-34.49h14.22l-40.5 38.04 43.38 43.56h-14.53l-39.19-39.3v39.3h-11.04z"/>
32
+ </g>
33
+ </svg>
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Parham Taheri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ <h1 align="center">
2
+ <img src="https://raw.githubusercontent.com/par-taheri/Kabk/main/Kabk_logo.svg" alt="Kabk Logo" width="200" />
3
+ </h1>
4
+
5
+ <p align="center">
6
+ <a href="https://rubygems.org/gems/kabk"><img src="https://img.shields.io/gem/v/kabk.svg?color=blue" alt="Gem Version"></a>
7
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
8
+ </p>
9
+
10
+ > **Kabk carries the Ruby to Simorgh**
11
+
12
+ The framework-agnostic Ruby backend engine designed exclusively to power the Simurgh Panel.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'kabk'
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ This gem manages the metadata registry, schema manifest generation, server-side validation, pagination, and concurrency control. Kabk is ORM-agnostic and relies on the Adapter pattern to interface with your database (e.g., via Sequel). It operates entirely on plain Ruby hashes and assumes your host application (like Roda or Rails) handles authentication and authorization.
25
+
26
+ ### Registering a Resource
27
+
28
+ ```ruby
29
+ require 'kabk'
30
+
31
+ # Assuming you have a Sequel Model
32
+ class NewsItem < Sequel::Model; end
33
+
34
+ # Kabk automatically detects Sequel models and uses the Kabk::Adapters::SequelAdapter
35
+
36
+ Kabk.register(name: 'news_item', table: NewsItem) do
37
+ title fa: 'اخبار و اطلاعیه‌ها', en: 'News & Announcements'
38
+ icon 'Newspaper'
39
+ plural_name 'news'
40
+ api_path '/api/admin/news'
41
+
42
+ field :id, type: :number, form_type: :number, primary_key: true, hidden_in_form: true
43
+ field :title, type: :string, form_type: :text, required: true, validation: { min_length: 5 }
44
+ field :content, type: :string, form_type: :wysiwyg
45
+ field :publish_date, type: :datetime, form_type: :datetime, calendar: :jalali
46
+
47
+ # Lifecycle Hooks
48
+ before_create do |params, context|
49
+ params["created_by"] = context[:current_user_id]
50
+ end
51
+
52
+ after_create do |record, context|
53
+ # trigger background job
54
+ end
55
+ end
56
+ ```
57
+
58
+ ### Generic REST Engine
59
+
60
+ The `Kabk::RestEngine` class orchestrates validation and delegates CRUD operations to the configured ORM adapter. It returns standardized raw hashes that your HTTP layer can easily convert to JSON.
61
+
62
+ ```ruby
63
+ engine = Kabk::RestEngine.new('news_item')
64
+
65
+ # Pagination, Filtering, Sorting, and Hydration are automatic
66
+ result = engine.list("page" => 1, "per_page" => 15, "sort" => "-created_at")
67
+ # => { success: true, data: [...], meta: { ... } }
68
+
69
+ # Validation and OCC automatically applied
70
+ result = engine.update(1, { "title" => "New Title", "updated_at" => "2026-03-15T11:00:00Z" })
71
+ ```
72
+
73
+ ### System Configuration (Protocol v1.6.0)
74
+
75
+ Kabk generates a JSON schema manifest containing dynamic system configuration and UI settings. You can override these defaults by passing a custom hash to the `SchemaRenderer`. Ensure you inject your authentication endpoints here, as Kabk itself does not provide them.
76
+
77
+ ```ruby
78
+ renderer = Kabk::SchemaRenderer.new(
79
+ system_config: {
80
+ title: { fa: "پنل مدیریت", en: "My Custom Admin" },
81
+ logo_url: "/custom-logo.png",
82
+ endpoints: {
83
+ login: "/auth/admin_login",
84
+ me: "/auth/admin_me",
85
+ logout: "/auth/admin_logout",
86
+ refresh: "/auth/admin_refresh",
87
+ upload: "/api/files"
88
+ }
89
+ }
90
+ )
91
+ schema = renderer.render
92
+ ```
93
+
94
+ ## Testing
95
+
96
+ ```bash
97
+ bundle install
98
+ bundle exec rspec
99
+ ```
100
+
101
+