lexxy-variables 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +85 -60
  3. data/lib/lexxy_variables/configuration.rb +1 -3
  4. data/lib/lexxy_variables/helper.rb +4 -17
  5. data/lib/lexxy_variables/renderers/liquid.rb +8 -12
  6. data/lib/lexxy_variables/renderers/substitution.rb +6 -8
  7. data/lib/lexxy_variables/{pipeline.rb → resolver.rb} +29 -23
  8. data/lib/lexxy_variables/version.rb +1 -1
  9. data/lib/lexxy_variables/with_variables.rb +31 -0
  10. data/lib/lexxy_variables.rb +4 -4
  11. data/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.8.gem +0 -0
  12. data/vendor/bundle/ruby/3.4.0/cache/erb-6.0.5.gem +0 -0
  13. data/vendor/bundle/ruby/3.4.0/cache/lexxy-0.9.25.gem +0 -0
  14. data/vendor/bundle/ruby/3.4.0/cache/loofah-2.25.2.gem +0 -0
  15. data/vendor/bundle/ruby/3.4.0/cache/parser-3.3.12.0.gem +0 -0
  16. data/vendor/bundle/ruby/3.4.0/cache/rails-html-sanitizer-1.7.1.gem +0 -0
  17. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{erb-6.0.4 → erb-6.0.5}/erb/escape.so +0 -0
  18. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-6.0.5/gem_make.out +19 -0
  19. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{lexxy-0.9.24 → lexxy-0.9.25}/gem_make.out +2 -2
  20. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/CHANGELOG.md +6 -0
  21. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  22. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/constants.rb +1 -1
  23. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/promises.rb +8 -2
  24. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/version.rb +1 -1
  25. data/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/Gemfile +16 -0
  26. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/NEWS.md +17 -1
  27. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/escape.so +0 -0
  28. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/version.rb +1 -1
  29. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb.rb +11 -3
  30. data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/javascript/lexxy.js +66 -9
  31. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.js.br +0 -0
  32. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.js.gz +0 -0
  33. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.js.map +1 -0
  34. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.min.js +11 -0
  35. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.min.js.br +0 -0
  36. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.min.js.gz +0 -0
  37. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/lib/lexxy/version.rb +3 -0
  38. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/CHANGELOG.md +15 -0
  39. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/safelist.rb +6 -2
  40. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/scrub.rb +86 -13
  41. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/version.rb +1 -1
  42. data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/current.rb +1 -1
  43. data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/version.rb +1 -1
  44. data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/CHANGELOG.md +15 -0
  45. data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails/html/sanitizer/version.rb +1 -1
  46. data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails/html/scrubbers.rb +1 -1
  47. data/vendor/bundle/ruby/3.4.0/specifications/{concurrent-ruby-1.3.7.gemspec → concurrent-ruby-1.3.8.gemspec} +3 -3
  48. data/vendor/bundle/ruby/3.4.0/specifications/{erb-6.0.4.gemspec → erb-6.0.5.gemspec} +3 -3
  49. data/vendor/bundle/ruby/3.4.0/specifications/{lexxy-0.9.24.gemspec → lexxy-0.9.25.gemspec} +2 -2
  50. data/vendor/bundle/ruby/3.4.0/specifications/{loofah-2.25.1.gemspec → loofah-2.25.2.gemspec} +3 -3
  51. data/vendor/bundle/ruby/3.4.0/specifications/{parser-3.3.11.1.gemspec → parser-3.3.12.0.gemspec} +4 -4
  52. data/vendor/bundle/ruby/3.4.0/specifications/{rails-html-sanitizer-1.7.0.gemspec → rails-html-sanitizer-1.7.1.gemspec} +5 -5
  53. metadata +325 -327
  54. data/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.7.gem +0 -0
  55. data/vendor/bundle/ruby/3.4.0/cache/erb-6.0.4.gem +0 -0
  56. data/vendor/bundle/ruby/3.4.0/cache/lexxy-0.9.24.gem +0 -0
  57. data/vendor/bundle/ruby/3.4.0/cache/loofah-2.25.1.gem +0 -0
  58. data/vendor/bundle/ruby/3.4.0/cache/parser-3.3.11.1.gem +0 -0
  59. data/vendor/bundle/ruby/3.4.0/cache/rails-html-sanitizer-1.7.0.gem +0 -0
  60. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-6.0.4/gem_make.out +0 -19
  61. data/vendor/bundle/ruby/3.4.0/gems/erb-6.0.4/Gemfile +0 -11
  62. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.js.br +0 -0
  63. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.js.gz +0 -0
  64. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.js.map +0 -1
  65. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.min.js +0 -11
  66. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.min.js.br +0 -0
  67. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.min.js.gz +0 -0
  68. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/lib/lexxy/version.rb +0 -3
  69. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/rails_api_test.rb +0 -101
  70. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/sanitizer_test.rb +0 -1284
  71. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/scrubbers_test.rb +0 -294
  72. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/test_helper.rb +0 -7
  73. /data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{erb-6.0.4 → erb-6.0.5}/gem.build_complete +0 -0
  74. /data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{erb-6.0.4 → erb-6.0.5}/mkmf.log +0 -0
  75. /data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{lexxy-0.9.24 → lexxy-0.9.25}/gem.build_complete +0 -0
  76. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/Gemfile +0 -0
  77. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/LICENSE.txt +0 -0
  78. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/README.md +0 -0
  79. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/Rakefile +0 -0
  80. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/ConcurrentRubyService.java +0 -0
  81. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +0 -0
  82. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +0 -0
  83. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +0 -0
  84. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +0 -0
  85. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +0 -0
  86. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +0 -0
  87. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +0 -0
  88. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +0 -0
  89. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +0 -0
  90. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +0 -0
  91. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +0 -0
  92. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +0 -0
  93. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +0 -0
  94. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +0 -0
  95. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/agent.rb +0 -0
  96. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/array.rb +0 -0
  97. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/async.rb +0 -0
  98. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atom.rb +0 -0
  99. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +0 -0
  100. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +0 -0
  101. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +0 -0
  102. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +0 -0
  103. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb +0 -0
  104. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +0 -0
  105. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/event.rb +0 -0
  106. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +0 -0
  107. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +0 -0
  108. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/locals.rb +0 -0
  109. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +0 -0
  110. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +0 -0
  111. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +0 -0
  112. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +0 -0
  113. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +0 -0
  114. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +0 -0
  115. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +0 -0
  116. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +0 -0
  117. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +0 -0
  118. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +0 -0
  119. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +0 -0
  120. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +0 -0
  121. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomics.rb +0 -0
  122. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +0 -0
  123. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +0 -0
  124. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb +0 -0
  125. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +0 -0
  126. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +0 -0
  127. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +0 -0
  128. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +0 -0
  129. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +0 -0
  130. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb +0 -0
  131. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb +0 -0
  132. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb +0 -0
  133. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb +0 -0
  134. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/deprecation.rb +0 -0
  135. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb +0 -0
  136. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/logging.rb +0 -0
  137. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/obligation.rb +0 -0
  138. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/observable.rb +0 -0
  139. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/configuration.rb +0 -0
  140. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/dataflow.rb +0 -0
  141. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/delay.rb +0 -0
  142. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/errors.rb +0 -0
  143. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/exchanger.rb +0 -0
  144. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +0 -0
  145. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb +0 -0
  146. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/executor_service.rb +0 -0
  147. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +0 -0
  148. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb +0 -0
  149. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb +0 -0
  150. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +0 -0
  151. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb +0 -0
  152. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +0 -0
  153. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb +0 -0
  154. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb +0 -0
  155. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +0 -0
  156. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +0 -0
  157. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb +0 -0
  158. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +0 -0
  159. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb +0 -0
  160. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +0 -0
  161. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb +0 -0
  162. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb +0 -0
  163. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/timer_set.rb +0 -0
  164. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executors.rb +0 -0
  165. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/future.rb +0 -0
  166. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/hash.rb +0 -0
  167. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/immutable_struct.rb +0 -0
  168. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/ivar.rb +0 -0
  169. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/map.rb +0 -0
  170. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/maybe.rb +0 -0
  171. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/mutable_struct.rb +0 -0
  172. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/mvar.rb +0 -0
  173. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/options.rb +0 -0
  174. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/promise.rb +0 -0
  175. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/re_include.rb +0 -0
  176. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/scheduled_task.rb +0 -0
  177. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/set.rb +0 -0
  178. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/settable_struct.rb +0 -0
  179. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +0 -0
  180. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +0 -0
  181. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +0 -0
  182. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/condition.rb +0 -0
  183. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +0 -0
  184. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +0 -0
  185. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/lock.rb +0 -0
  186. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +0 -0
  187. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +0 -0
  188. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/object.rb +0 -0
  189. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +0 -0
  190. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +0 -0
  191. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization.rb +0 -0
  192. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +0 -0
  193. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb +0 -0
  194. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +0 -0
  195. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb +0 -0
  196. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb +0 -0
  197. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb +0 -0
  198. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb +0 -0
  199. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util.rb +0 -0
  200. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/timer_task.rb +0 -0
  201. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/tuple.rb +0 -0
  202. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/tvar.rb +0 -0
  203. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/engine.rb +0 -0
  204. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +0 -0
  205. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +0 -0
  206. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/native_integer.rb +0 -0
  207. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +0 -0
  208. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent-ruby.rb +0 -0
  209. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent.rb +0 -0
  210. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/BSDL +0 -0
  211. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/COPYING +0 -0
  212. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/LICENSE.txt +0 -0
  213. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/README.md +0 -0
  214. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/Rakefile +0 -0
  215. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/_doc/cgi.rb +0 -0
  216. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/_doc/erb_executable.md +0 -0
  217. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/bin/console +0 -0
  218. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/bin/setup +0 -0
  219. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/erb.gemspec +0 -0
  220. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/ext/erb/escape/Makefile +0 -0
  221. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/ext/erb/escape/escape.c +0 -0
  222. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/ext/erb/escape/extconf.rb +0 -0
  223. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/compiler.rb +0 -0
  224. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/def_method.rb +0 -0
  225. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/util.rb +0 -0
  226. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/libexec/erb +0 -0
  227. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/MIT-LICENSE +0 -0
  228. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/README.md +0 -0
  229. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/Rakefile +0 -0
  230. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy-content.css +0 -0
  231. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy-editor.css +0 -0
  232. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy-variables.css +0 -0
  233. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy.css +0 -0
  234. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/views/action_text/attachables/_remote_video.html.erb +0 -0
  235. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/config/ci.rb +0 -0
  236. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/ext/Rakefile +0 -0
  237. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/action_text/attachables/remote_video.rb +0 -0
  238. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/action_text/editor/lexxy_editor.rb +0 -0
  239. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/active_storage/blob_with_preview_url.rb +0 -0
  240. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/action_text_tag.rb +0 -0
  241. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/attachable.rb +0 -0
  242. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/engine.rb +0 -0
  243. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/form_builder.rb +0 -0
  244. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/form_helper.rb +0 -0
  245. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/rich_text_area_tag.rb +0 -0
  246. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy.rb +0 -0
  247. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/tasks/actiontext/lexical_tasks.rake +0 -0
  248. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/MIT-LICENSE.txt +0 -0
  249. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/README.md +0 -0
  250. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/SECURITY.md +0 -0
  251. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/concerns.rb +0 -0
  252. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/elements.rb +0 -0
  253. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/helpers.rb +0 -0
  254. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html4/document.rb +0 -0
  255. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html4/document_fragment.rb +0 -0
  256. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/document.rb +0 -0
  257. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/document_fragment.rb +0 -0
  258. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/libxml2_workarounds.rb +0 -0
  259. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/metahelpers.rb +0 -0
  260. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/scrubber.rb +0 -0
  261. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/scrubbers.rb +0 -0
  262. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/xml/document.rb +0 -0
  263. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/xml/document_fragment.rb +0 -0
  264. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah.rb +0 -0
  265. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/LICENSE.txt +0 -0
  266. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/bin/ruby-parse +0 -0
  267. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/bin/ruby-rewrite +0 -0
  268. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/gauntlet_parser.rb +0 -0
  269. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/all.rb +0 -0
  270. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ast/node.rb +0 -0
  271. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ast/processor.rb +0 -0
  272. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/base.rb +0 -0
  273. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/builders/default.rb +0 -0
  274. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/clobbering_error.rb +0 -0
  275. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/color.rb +0 -0
  276. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/context.rb +0 -0
  277. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/current_arg_stack.rb +0 -0
  278. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/deprecation.rb +0 -0
  279. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/diagnostic/engine.rb +0 -0
  280. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/diagnostic.rb +0 -0
  281. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/dedenter.rb +0 -0
  282. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/explanation.rb +0 -0
  283. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/literal.rb +0 -0
  284. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/stack_state.rb +0 -0
  285. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer-F0.rb +0 -0
  286. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer-F1.rb +0 -0
  287. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer-strings.rb +0 -0
  288. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/macruby.rb +0 -0
  289. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/max_numparam_stack.rb +0 -0
  290. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/messages.rb +0 -0
  291. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/meta.rb +0 -0
  292. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/rewriter.rb +0 -0
  293. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby18.rb +0 -0
  294. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby19.rb +0 -0
  295. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby20.rb +0 -0
  296. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby21.rb +0 -0
  297. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby22.rb +0 -0
  298. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby23.rb +0 -0
  299. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby24.rb +0 -0
  300. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby25.rb +0 -0
  301. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby26.rb +0 -0
  302. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby27.rb +0 -0
  303. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby30.rb +0 -0
  304. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby31.rb +0 -0
  305. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby32.rb +0 -0
  306. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby33.rb +0 -0
  307. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby34.rb +0 -0
  308. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/rubymotion.rb +0 -0
  309. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/runner/ruby_parse.rb +0 -0
  310. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/runner/ruby_rewrite.rb +0 -0
  311. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/runner.rb +0 -0
  312. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/buffer.rb +0 -0
  313. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/comment/associator.rb +0 -0
  314. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/comment.rb +0 -0
  315. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/collection.rb +0 -0
  316. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/condition.rb +0 -0
  317. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/constant.rb +0 -0
  318. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/definition.rb +0 -0
  319. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/for.rb +0 -0
  320. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/heredoc.rb +0 -0
  321. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/index.rb +0 -0
  322. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/keyword.rb +0 -0
  323. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/method_definition.rb +0 -0
  324. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/objc_kwarg.rb +0 -0
  325. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/operator.rb +0 -0
  326. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/rescue_body.rb +0 -0
  327. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/send.rb +0 -0
  328. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/ternary.rb +0 -0
  329. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/variable.rb +0 -0
  330. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map.rb +0 -0
  331. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/range.rb +0 -0
  332. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/rewriter/action.rb +0 -0
  333. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/rewriter.rb +0 -0
  334. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/tree_rewriter/action.rb +0 -0
  335. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/tree_rewriter.rb +0 -0
  336. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/static_environment.rb +0 -0
  337. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/syntax_error.rb +0 -0
  338. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/tree_rewriter.rb +0 -0
  339. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/unknown_encoding_in_magic_comment_error.rb +0 -0
  340. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/variables_stack.rb +0 -0
  341. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser.rb +0 -0
  342. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/parser.gemspec +0 -0
  343. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/MIT-LICENSE +0 -0
  344. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/README.md +0 -0
  345. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails/html/sanitizer.rb +0 -0
  346. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails-html-sanitizer.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20e1253a50b9ac063ff88624785d48c6103842a46c07256ab867db405497f38a
4
- data.tar.gz: 6c9097c35bd39c7a81b204de9f68599c56be4fcd319ec660cbcfb5aaa4432f85
3
+ metadata.gz: a109be7d8f0e268e60ce7fbaa71cf752d492f6d08f04300b52418016a54c7fdf
4
+ data.tar.gz: a84a11352b3b3d9701719e66428574c8693e05e36a8fff2f3d140022076ee930
5
5
  SHA512:
6
- metadata.gz: c6d6291c6770026b75e2b167262f39d3419fdcb23ba255969391f3a96adce42abb2c3a2f7e73cd775855832483fc7158ab9dd655b481caf80042791262638931
7
- data.tar.gz: 343e6f7cc524a95b4c5aca8a0230d091acf16a3ef7147cc2324172fc545ca3bc1db91bae1907ef344b6d06fd255874c741b770393d609ee7c4a3124c0f59dbf9
6
+ metadata.gz: 2ccc7224904bf969b37d41449bbd8efd42654a345483242ca3dc898e278a2de8c641735db757815d7ba79482b9c85f670e43d14d1c64e5493539bd7b8ff8617c
7
+ data.tar.gz: 74066919264113eb0370da5d0e740a05cecfb5ffd6036fedf0e448115e8dbaa4b856dfdc2a5ca7b1cbeaaf270bf5d7c1c74bb49df4d768aba55bebb23b332d05
data/README.md CHANGED
@@ -9,9 +9,9 @@ an `<action-text-attachment>` chip with its own content type, not as literal
9
9
  You decide what variables exist and what they turn into.
10
10
 
11
11
  Because variables are just Action Text attachments, you can register new
12
- chip types with `register_attachment` (see [Full configuration](#full-configuration)):
13
- a chip that renders as `:text` resolves to an escaped string, one that renders
14
- as `:html` splices rich content in before sanitization.
12
+ chip types with `register_attachment` (see [Full configuration](#full-configuration)).
13
+ A `:text` chip resolves to an escaped string. An `:html` chip splices rich
14
+ content in before sanitization.
15
15
 
16
16
  Liquid is **optional**. The default renderer is plain, injection-safe string
17
17
  substitution and pulls in no template engine.
@@ -82,9 +82,6 @@ LexxyVariables.configure do |c|
82
82
  end
83
83
  ```
84
84
 
85
- The gem adds two view helpers, one for each side of the workflow: one to author
86
- content and one to display it.
87
-
88
85
  On the **editor page** (the form where content is composed), render the prompt
89
86
  *inside* the Lexxy editor. The editor extension looks for the `<lexxy-prompt>`
90
87
  within the `<lexxy-editor>` element, so it must be nested in the `rich_text_area`
@@ -107,10 +104,11 @@ for picking from the same list. Inserted variables appear as chips in the editor
107
104
  </p>
108
105
 
109
106
  On the **display page** (where the saved content is shown to readers), resolve
110
- the stored rich text. This is what swaps each variable chip for its value:
107
+ the stored rich text with `with_variables`. This is what swaps each variable
108
+ chip for its value:
111
109
 
112
110
  ```erb
113
- <%= render_variable_content(@record.body) %>
111
+ <%= @record.body.with_variables %>
114
112
  ```
115
113
 
116
114
  Each chip resolves to its value, so the reader sees finished text:
@@ -152,16 +150,20 @@ Editor page:
152
150
  Display page:
153
151
 
154
152
  ```erb
155
- <%= render_variable_content(@message.body,
153
+ <%= @message.body.with_variables(
156
154
  first_name: @user.first_name,
157
155
  last_name: @user.last_name) %>
158
156
  ```
159
157
 
160
- The catalog entries have no `value` because it's supplied at render time, so the same saved content renders differently per user. The default renderer escapes the values automatically. When a variable name would collide with `context:` or `locale:`, use an `assigns:` hash instead (see [Helper options](#helper-options)).
158
+ The catalog entries have no `value` because it's supplied at render time, so the same saved content renders differently per user. Values are escaped for HTML automatically. When a variable name would collide with `context:` or `locale:`, use an `assigns:` hash instead:
159
+
160
+ ```erb
161
+ <%= @message.body.with_variables(assigns: { locale: @user.locale }) %>
162
+ ```
161
163
 
162
164
  ### Static values from config
163
165
 
164
- When a value is the same for everyone, it can live on the catalog item itself. With no `assigns` set, the gem reads `value` off the catalog and the helper takes no extra arguments:
166
+ When a value is the same for everyone, it can live on the catalog item itself. With no `assigns` set, the gem reads `value` off the catalog and `with_variables` takes no arguments:
165
167
 
166
168
  ```ruby
167
169
  LexxyVariables.configure do |c|
@@ -170,27 +172,25 @@ end
170
172
  ```
171
173
 
172
174
  ```erb
173
- <%= render_variable_content(@message.body) %>
175
+ <%= @message.body.with_variables %>
174
176
  ```
175
177
 
176
178
  ### Liquid drops and dotted access
177
179
 
178
- Liquid enables dotted access like `{{ user.first_name }}`, filters, and drops that expose a whole object. A drop is a small class that defines which methods Liquid can call, and escapes what it returns:
180
+ Liquid enables dotted access like `{{ user.first_name }}`, filters, and drops that expose a whole object. A drop is a small class that defines which methods Liquid can call:
179
181
 
180
182
  ```ruby
181
183
  # app/drops/user_drop.rb
182
- # Liquid output is emitted html_safe after sanitization,
183
- # so a drop must escape its own values.
184
184
  class UserDrop < Liquid::Drop
185
185
  def initialize(user) = @user = user
186
186
 
187
- def first_name = ERB::Util.html_escape(@user.first_name).to_s
188
- def full_name = ERB::Util.html_escape(@user.full_name).to_s
189
- def email = ERB::Util.html_escape(@user.email).to_s
187
+ def first_name = @user.first_name
188
+ def full_name = @user.full_name
189
+ def email = @user.email
190
190
  end
191
191
  ```
192
192
 
193
- The dotted keys go in the catalog so they can be inserted, the Liquid renderer is switched on, and `assigns` returns the drop under the name the keys use (`user`):
193
+ The dotted keys go in the catalog, the Liquid renderer is used, and `assigns` returns the drop under the name the keys use (`user`):
194
194
 
195
195
  ```ruby
196
196
  LexxyVariables.configure do |c|
@@ -207,10 +207,54 @@ end
207
207
  ```
208
208
 
209
209
  ```erb
210
- <%= render_variable_content(@message.body) %>
210
+ <%= @message.body.with_variables %>
211
+ ```
212
+
213
+ A `user.first_name` chip becomes `{{ user.first_name }}`, which Liquid runs through the drop. Liquid can only call the methods the drop defines. Return raw values and let the gem handle the escaping.
214
+
215
+ ## Plain text and Markdown
216
+
217
+ `with_variables` returns a plain `ActionText::Content` with every chip
218
+ resolved, so Action Text's own conversions chain from it:
219
+
220
+ ```ruby
221
+ @message.body.with_variables(first_name: @user.first_name).to_plain_text
222
+ # => "Hi Ada, welcome aboard!"
223
+
224
+ @message.body.with_variables(first_name: "Ada").to_markdown # Rails 8.2+
225
+ ```
226
+
227
+ Each format handles its own escaping. Values come out raw in `to_plain_text`
228
+ and `to_markdown`, and escaped in HTML. No view is required, so it works in
229
+ mailers (the text part of an email), background jobs, and exports:
230
+
231
+ ```ruby
232
+ mail.text_part = @message.body.with_variables(assigns).to_plain_text
211
233
  ```
212
234
 
213
- A `user.first_name` chip becomes `{{ user.first_name }}`, which Liquid runs through the drop. Only the methods defined on the drop are reachable, not arbitrary attributes on the user. Liquid doesn't escape output the way the default renderer does, so the drop escapes its own values. The same goes for any plain string returned from `assigns` or passed inline.
235
+ Rendering works the same as on any rich text body. During a request Rails
236
+ renders it with the current controller, so helpers and URLs resolve as usual.
237
+ Outside a request it uses Rails' offline renderer.
238
+
239
+ ## Locales
240
+
241
+ `with_variables` takes a `locale:`. Resolution runs inside `I18n.with_locale`,
242
+ so anything that calls `I18n.t` along the way (assigns, resolvers, drops) sees
243
+ that locale. Leave it off to use the current locale. The previous locale is
244
+ restored afterward.
245
+
246
+ ```ruby
247
+ @message.body.with_variables(locale: recipient.locale).to_plain_text
248
+ ```
249
+
250
+ `with_variables` resolves right away, but the conversion you chain on it runs
251
+ later under whatever locale is current then. If the content has attachments
252
+ with translated partials, wrap the conversion too:
253
+
254
+ ```ruby
255
+ resolved = @message.body.with_variables(locale: :fr)
256
+ I18n.with_locale(:fr) { resolved.to_s }
257
+ ```
214
258
 
215
259
  ## Full configuration
216
260
 
@@ -218,7 +262,7 @@ A `user.first_name` chip becomes `{{ user.first_name }}`, which Liquid runs thro
218
262
 
219
263
  ```ruby
220
264
  LexxyVariables.configure do |c|
221
- # What users can insert: the {{ prompt and the toolbar dropdown read this.
265
+ # What users can insert. The {{ prompt and the toolbar dropdown read this.
222
266
  c.catalog = ->(context) { context.variables + BuiltinVariable.all }
223
267
 
224
268
  # What each used key resolves to at render time.
@@ -227,7 +271,7 @@ LexxyVariables.configure do |c|
227
271
  # Opt into Liquid for dotted access, drops, and filters.
228
272
  c.renderer = LexxyVariables::Renderers::Liquid.new
229
273
 
230
- # A second chip type: snippets expand to rich HTML instead of an escaped value.
274
+ # A second chip type. Snippets expand to rich HTML instead of an escaped value.
231
275
  c.register_attachment(
232
276
  content_type: "application/vnd.actiontext.snippet",
233
277
  renders_as: :html,
@@ -242,42 +286,21 @@ end
242
286
  | Option | Default | What it does |
243
287
  | --- | --- | --- |
244
288
  | `catalog` | `[]` | The insertable items shown in the `{{` prompt and the toolbar dropdown. A list, a zero-arg lambda, or a `->(context)` lambda. Items respond to `#key` and `#name`, and optionally `#value` and `#attachable_sgid`. |
245
- | `assigns` | reads `#value` off catalog items | The render-time lookup. A `->(context, used_keys)` or `->(used_keys)` lambda that receives only the keys used in the content being rendered and returns a `{ key => value }` hash. Per-render values can also be passed straight to `render_variable_content` (see [Helper options](#helper-options)). |
246
- | `renderer` | `Renderers::Substitution.new` | How placeholders become values. The default is plain, escaped string substitution with no template engine. Swap in `Renderers::Liquid.new` for dotted access, drops, and filters. |
289
+ | `assigns` | reads `#value` off catalog items | The render-time lookup. A `->(context, used_keys)` or `->(used_keys)` lambda that receives only the keys used in the content being rendered and returns a `{ key => value }` hash. Per-render values can also be passed straight to `with_variables` (see [Examples](#examples)). |
290
+ | `renderer` | `Renderers::Substitution.new` | How a chip's key becomes a value. The default is a plain hash lookup with no template engine. Swap in `Renderers::Liquid.new` for dotted access, drops, and filters. |
247
291
  | `sort` | `:name` | How the catalog is ordered in the prompt and dropdown. `:name` (case-insensitive alphabetical), `:key`, `false` to keep the catalog's given order, or a lambda (a `->(item)` sort key or a `->(a, b)` comparator). |
248
292
  | `max_fragment_depth` | `1` | How many levels of `renders_as: :html` chips expand. The default resolves the variables inside a snippet but drops a snippet nested inside another snippet. Raise it to allow deeper nesting. |
249
- | `content_layout` | `"layouts/action_text/contents/content"` | The Action Text layout that wraps rendered output. Point it at your own partial to change the wrapper, for example when rendering into emails. |
250
- | `register_attachment(content_type:, resolve:, renders_as:, label:)` | variable type pre-registered | Adds or replaces a chip type. `renders_as:` is `:text` (default, the resolver returns a key whose escaped value is substituted in) or `:html` (splices rich HTML in pre-sanitize, resolving inner `:text` chips in the same pass, bounded by `max_fragment_depth`). `label:` is the badge shown in the prompt when the list mixes types. Re-registering a content type (including the built-in variable type) replaces it, which is how you'd swap in a custom variable resolver. |
293
+ | `register_attachment(content_type:, resolve:, renders_as:, label:)` | variable type pre-registered | Adds or replaces a chip type. `renders_as:` is `:text` (default, the resolver returns a key whose value is substituted in as inert text) or `:html` (splices rich HTML in pre-sanitize, resolving inner `:text` chips in the same pass, bounded by `max_fragment_depth`). `label:` is the badge shown in the prompt when the list mixes types. Re-registering a content type (including the built-in variable type) replaces it, which is how you'd swap in a custom variable resolver. |
251
294
 
252
- ### Helper options
295
+ ### Prompt options
253
296
 
254
- Both view helpers take `context:` (see [Multi-tenancy](#multi-tenancy)). Beyond
255
- that, `lexxy_variables_prompt` lets you change the trigger characters and the
256
- empty state, and `render_variable_content` can render under a specific locale by
257
- wrapping the whole pass in `I18n.with_locale`.
297
+ `lexxy_variables_prompt` takes `context:` (see [Multi-tenancy](#multi-tenancy))
298
+ and lets you change the trigger characters and the empty state:
258
299
 
259
300
  ```erb
260
301
  <%= lexxy_variables_prompt(trigger: "%%", empty_results: t(".no_variables")) %>
261
-
262
- <%= render_variable_content(@record.body, locale: recipient.locale) %>
263
302
  ```
264
303
 
265
- You can also pass a variable's value straight to `render_variable_content`, as
266
- keyword arguments or an `assigns:` hash. These win over whatever the configured
267
- `assigns` returns, and a value for a key that isn't used in the content is just
268
- ignored:
269
-
270
- ```erb
271
- <%# keyword arguments %>
272
- <%= render_variable_content(@record.body, first_name: @user.first_name) %>
273
-
274
- <%# same thing, for a name that would clash with context: or locale: %>
275
- <%= render_variable_content(@record.body, assigns: { first_name: @user.first_name }) %>
276
- ```
277
-
278
- The default renderer escapes these values for you. Liquid doesn't, so escape
279
- them yourself or pass a drop.
280
-
281
304
  ## Multi-tenancy
282
305
 
283
306
  Tenancy is optional. If your app is multi-tenant, pass the tenant through as
@@ -290,7 +313,7 @@ LexxyVariables.configure do |c|
290
313
  end
291
314
  ```
292
315
 
293
- Both view helpers take the same `context:`. Pass the tenant on the editor page:
316
+ Pass the tenant on the editor page:
294
317
 
295
318
  ```erb
296
319
  <%= form.rich_text_area :body do %>
@@ -301,7 +324,7 @@ Both view helpers take the same `context:`. Pass the tenant on the editor page:
301
324
  and again on the display page:
302
325
 
303
326
  ```erb
304
- <%= render_variable_content(@record.body, context: ActsAsTenant.current_tenant) %>
327
+ <%= @record.body.with_variables(context: ActsAsTenant.current_tenant) %>
305
328
  ```
306
329
 
307
330
  Or skip `context` entirely and rely on acts_as_tenant scoping queries to the
@@ -369,14 +392,16 @@ popup and the dropdown:
369
392
 
370
393
  ## Security model
371
394
 
372
- - Every render gets a fresh random nonce that guards the placeholder tokens, so an
373
- author can't fake a substitution by typing the token pattern into the body.
374
- - Chips are swapped for those nonce tokens before the HTML is sanitized, and the
375
- real values go in afterward. A `:text` chip resolves to HTML-escaped text that
376
- can't do anything, while an `:html` chip is spliced in before sanitizing so the
377
- sanitizer still scrubs it.
378
- - Only the Liquid renderer deals with template-engine braces (`{{ }}` and `{% %}`).
379
- The default renderer runs no engine at all, so there's nothing there to inject into.
395
+ - Every resolution gets a fresh random nonce that guards the placeholder tokens,
396
+ so an author can't fake a substitution by typing the token pattern into the body.
397
+ - Resolved values are injected as DOM text nodes, never parsed as markup. HTML
398
+ output escapes them at serialization and still runs the sanitizer at render
399
+ time, so a value can't reintroduce markup. Plain-text and Markdown output read
400
+ them raw. An `:html` chip is spliced in before that render-time sanitization,
401
+ so the sanitizer still scrubs it.
402
+ - Only the Liquid renderer runs a template engine, and it only ever parses chip
403
+ keys, never body text, so `{{ }}` or `{% %}` an author types stays literal. The
404
+ default renderer runs no engine at all, so there's nothing there to inject into.
380
405
 
381
406
  ## Contributing
382
407
 
@@ -14,20 +14,18 @@ module LexxyVariables
14
14
  # renderer: Renderers::Substitution (default, no Liquid) or Renderers::Liquid.
15
15
  # max_fragment_depth: how deep :html chips (e.g. snippets) expand. The
16
16
  # default of 1 resolves a snippet's inner variables and drops nested snippets.
17
- # content_layout: the ActionText content layout wrapper for rendered output.
18
17
  # sort: how the catalog is ordered in the prompt and dropdown. Defaults to
19
18
  # :name (case-insensitive alphabetical). Use :key to sort by key, false to
20
19
  # preserve the catalog's given order, or a callable: a ->(item) sort key, or
21
20
  # a ->(a, b) comparator.
22
21
  class Configuration
23
- attr_accessor :assigns, :renderer, :content_layout, :max_fragment_depth, :sort
22
+ attr_accessor :assigns, :renderer, :max_fragment_depth, :sort
24
23
  attr_reader :registry
25
24
  attr_writer :catalog
26
25
 
27
26
  def initialize
28
27
  @registry = Registry.new
29
28
  @renderer = Renderers::Substitution.new
30
- @content_layout = "layouts/action_text/contents/content"
31
29
  @max_fragment_depth = 1
32
30
  @catalog = []
33
31
  @sort = :name
@@ -1,22 +1,9 @@
1
1
  module LexxyVariables
2
- # Mixed into Action View by the engine. `context` is opaque to the gem and is
3
- # passed straight through to the host's catalog/assigns/resolve callables.
2
+ # Editor-side view helpers. LexxyVariables::Engine includes this module into
3
+ # Action View when the host app boots, so lexxy_variables_prompt and
4
+ # lexxy_variable_chip are callable from any view with no setup. `context` is
5
+ # opaque to the gem and is passed straight through to the host's catalog.
4
6
  module Helper
5
- # `assigns:` (and any extra keyword args) are per-render values merged on top
6
- # of the configured `assigns`, so a caller can supply a key's value inline:
7
- #
8
- # render_variable_content(@record.body, first_name: @user.first_name)
9
- #
10
- # Inline values win over the configured assigns. Keys not used by any chip in
11
- # the body are ignored. Under the default renderer inline values are
12
- # HTML-escaped; under Liquid they are emitted as-is, so pre-escape them or
13
- # pass a drop.
14
- def render_variable_content(rich_text, context: nil, locale: I18n.locale, assigns: {}, **inline_assigns)
15
- LexxyVariables::Pipeline.new(self).call(
16
- rich_text, context: context, locale: locale, assigns: assigns.merge(inline_assigns)
17
- )
18
- end
19
-
20
7
  # Renders the <lexxy-prompt> the editor extension reads, built from the
21
8
  # configured catalog. `context` is passed to the catalog callable.
22
9
  def lexxy_variables_prompt(context: nil, trigger: "{{", empty_results: "No variables found")
@@ -1,29 +1,25 @@
1
1
  module LexxyVariables
2
2
  module Renderers
3
- # Opt-in renderer that resolves placeholders through Liquid, enabling dotted
3
+ # Opt-in renderer that resolves each key through Liquid, enabling dotted
4
4
  # access, drops (e.g. {{ company.name }}), and filters. Requires the `liquid`
5
5
  # gem. It is loaded here, when a host instantiates this renderer, so apps on
6
6
  # the default renderer never pull it in.
7
7
  #
8
- # Security: because Liquid does interpret {{ }} and {% %}, any such syntax the
9
- # author typed as plain text is entity-escaped BEFORE our own placeholders are
10
- # revealed, so users cannot forge Liquid. Only the nonce-protected placeholders
11
- # this pipeline emitted become real Liquid tags.
8
+ # Security: only the chip's key is parsed as a Liquid template, never body
9
+ # text, so {{ }} or {% %} an author types stays literal. The resolved value
10
+ # is injected as a DOM text node and escaped per output format by the
11
+ # resolver, so drops must NOT pre-escape their values.
12
12
  #
13
13
  # `assigns` is the Hash passed to Liquid: string values and/or Liquid::Drop
14
- # instances. Drops must escape their own output, since Liquid output is emitted
15
- # html_safe after sanitization.
14
+ # instances.
16
15
  class Liquid
17
16
  def initialize(error_mode: :lax)
18
17
  require "liquid"
19
18
  @error_mode = error_mode
20
19
  end
21
20
 
22
- def render(html, nonce:, assigns:)
23
- html = html.gsub("{{", "&#123;&#123;").gsub("{%", "&#123;%")
24
- html = html.gsub(Placeholder.pattern(nonce)) { "{{ #{$1} }}" }
25
-
26
- ::Liquid::Template.parse(html, error_mode: @error_mode).render(assigns)
21
+ def resolve_value(key, assigns)
22
+ ::Liquid::Template.parse("{{ #{key} }}", error_mode: @error_mode).render(assigns)
27
23
  end
28
24
  end
29
25
  end
@@ -1,14 +1,12 @@
1
1
  module LexxyVariables
2
2
  module Renderers
3
- # Default renderer. Replaces nonce placeholders with resolved values by plain
4
- # string substitution. There is no template engine, so author-typed text can
5
- # never be interpreted as code. Each value is HTML-escaped, so it is inert and
6
- # cannot reintroduce markup the sanitizer already stripped.
7
- #
8
- # `assigns` is a Hash of key => value. Values are coerced to escaped strings.
3
+ # Default renderer. Looks each key up in the assigns hash, no template
4
+ # engine, so author-typed text can never be interpreted as code. The value
5
+ # is returned raw: the resolver injects it as a DOM text node, where HTML
6
+ # serialization escapes it and plain-text/markdown conversions read it as-is.
9
7
  class Substitution
10
- def render(html, nonce:, assigns:)
11
- html.gsub(Placeholder.pattern(nonce)) { ERB::Util.html_escape(assigns[$1].to_s) }
8
+ def resolve_value(key, assigns)
9
+ assigns[key].to_s
12
10
  end
13
11
  end
14
12
  end
@@ -1,42 +1,35 @@
1
1
  module LexxyVariables
2
- # Turns stored rich text into rendered HTML with attachment chips resolved.
2
+ # Resolves the attachment chips in stored rich text, returning a new
3
+ # ActionText::Content with every chip replaced by its value. The result is a
4
+ # plain content object, so Action Text's own conversions chain from it:
5
+ # #to_s (sanitized HTML), #to_plain_text, #to_markdown, #to_html.
3
6
  #
4
7
  # Security invariants (do not weaken):
5
8
  # 1. A random per-render nonce guards placeholder tokens, so an author cannot
6
9
  # forge a substitution by typing the token pattern into the body.
7
- # 2. Attachments are swapped for nonce tokens BEFORE sanitization and resolved
8
- # values are injected AFTER. :text output is HTML-escaped and therefore
9
- # inert. :html output is spliced pre-sanitize so the sanitizer cleans it.
10
- # 3. Any template-engine escaping (Liquid braces) lives only in that renderer.
10
+ # 2. Resolved values are injected as DOM text nodes, never parsed as markup.
11
+ # HTML serialization escapes them, and the sanitizer still runs when the
12
+ # content is rendered. :html output is spliced as markup here, before that
13
+ # render-time sanitization, so the sanitizer cleans it too.
14
+ # 3. Any template-engine parsing (Liquid) sees only chip keys, never body text.
11
15
  #
12
- # Needs a view context (self, from the helper) for Action Text rendering.
13
- # Build a fresh Pipeline per render, as the helper does. #call stores
14
- # per-render state on the instance.
15
- class Pipeline
16
- def initialize(view, config = LexxyVariables.config)
17
- @view = view
16
+ # Build a fresh Resolver per call. #call stores per-render state on the instance.
17
+ class Resolver
18
+ def initialize(config = LexxyVariables.config)
18
19
  @config = config
19
20
  end
20
21
 
21
- def call(rich_text, context: nil, locale: I18n.locale, assigns: {})
22
- body = rich_text&.body
23
- return "".html_safe if body.blank?
24
-
22
+ def call(content, context: nil, locale: nil, assigns: {})
25
23
  @context = context
26
24
  @nonce = SecureRandom.hex(8)
27
25
  @used_keys = []
28
26
 
29
27
  I18n.with_locale(locale || I18n.locale) do
30
- fragment = substitute(body.fragment, 0)
31
- html = @view.render_action_text_content(
32
- ActionText::Content.new(fragment.to_html, canonicalize: false)
33
- )
34
-
28
+ fragment = substitute(content.fragment, 0)
35
29
  resolved = @config.resolve_assigns(@context, @used_keys.uniq)
36
30
  resolved = resolved.merge(assigns.transform_keys(&:to_s)) if assigns.any?
37
- rendered = @config.renderer.render(html, nonce: @nonce, assigns: resolved)
38
-
39
- @view.render(layout: @config.content_layout) { rendered.html_safe }
31
+ inject_values(fragment, resolved)
32
+ ActionText::Content.new(fragment, canonicalize: false)
40
33
  end
41
34
  end
42
35
 
@@ -74,6 +67,19 @@ module LexxyVariables
74
67
  substitute(inner, depth + 1)
75
68
  end
76
69
 
70
+ # Swaps each nonce-guarded token for its value, staying at the text-node
71
+ # level so values serialize as escaped text and read back raw in plain-text
72
+ # and markdown conversions. #substitute returned a fresh fragment, so
73
+ # mutating it in place is safe.
74
+ def inject_values(fragment, assigns)
75
+ pattern = Placeholder.pattern(@nonce)
76
+ fragment.source.traverse do |node|
77
+ next unless node.text? && node.content.match?(pattern)
78
+
79
+ node.content = node.content.gsub(pattern) { @config.renderer.resolve_value($1, assigns) }
80
+ end
81
+ end
82
+
77
83
  # Accepts whatever a :html resolver returns (ActionText content, rich
78
84
  # text, a Nokogiri node, or an HTML string) and coerces it to the
79
85
  # ActionText::Fragment that #substitute needs, or nil to drop the chip.
@@ -1,3 +1,3 @@
1
1
  module LexxyVariables
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,31 @@
1
+ module LexxyVariables
2
+ # Mixed into ActionText::Content via the :action_text_content load hook.
3
+ module WithVariables
4
+ # Returns a new ActionText::Content with every variable chip resolved, so
5
+ # Action Text's own conversions chain from the result:
6
+ #
7
+ # @post.body.with_variables(first_name: "Ada").to_plain_text
8
+ # @post.body.with_variables(context: tenant).to_s
9
+ # @post.body.with_variables.to_markdown # on Rails versions that ship it
10
+ #
11
+ # Takes `context:`, `locale:`, and per-render values as keyword args or an
12
+ # `assigns:` hash.
13
+ def with_variables(context: nil, locale: nil, assigns: {}, **inline_assigns)
14
+ LexxyVariables::Resolver.new.call(
15
+ self, context: context, locale: locale, assigns: assigns.merge(inline_assigns)
16
+ )
17
+ end
18
+ end
19
+
20
+ # Mixed into ActionText::RichText via the :action_text_rich_text load hook,
21
+ # so `@post.body.with_variables` works straight off the association.
22
+ module RichTextWithVariables
23
+ def with_variables(context: nil, locale: nil, assigns: {}, **inline_assigns)
24
+ (body || ActionText::Content.new(nil, canonicalize: false))
25
+ .with_variables(context: context, locale: locale, assigns: assigns.merge(inline_assigns))
26
+ end
27
+ end
28
+ end
29
+
30
+ ActiveSupport.on_load(:action_text_content) { include LexxyVariables::WithVariables }
31
+ ActiveSupport.on_load(:action_text_rich_text) { include LexxyVariables::RichTextWithVariables }
@@ -1,5 +1,4 @@
1
1
  require "active_support"
2
- require "erb"
3
2
  require "securerandom"
4
3
  require "nokogiri"
5
4
 
@@ -10,15 +9,16 @@ require "lexxy_variables/registry"
10
9
  require "lexxy_variables/renderers/substitution"
11
10
  require "lexxy_variables/renderers/liquid"
12
11
  require "lexxy_variables/configuration"
13
- require "lexxy_variables/pipeline"
12
+ require "lexxy_variables/resolver"
13
+ require "lexxy_variables/with_variables"
14
14
  require "lexxy_variables/attachable"
15
15
  require "lexxy_variables/helper"
16
16
  require "lexxy_variables/engine" if defined?(Rails::Engine)
17
17
 
18
18
  # Insert and safely resolve variable/attachment tokens in Lexxy rich text.
19
19
  #
20
- # The gem owns the mechanism: the editor extension, the nonce-safe render
21
- # pipeline, the attachment-type registry, and the renderers. The host app owns
20
+ # The gem owns the mechanism: the editor extension, the nonce-safe resolver,
21
+ # the attachment-type registry, and the renderers. The host app owns
22
22
  # the policy: what variables exist (catalog), what a key resolves to (assigns),
23
23
  # and any extra attachment types (register_attachment, e.g. snippets).
24
24
  module LexxyVariables
@@ -0,0 +1,19 @@
1
+ current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/ext/erb/escape
2
+ /opt/hostedtoolcache/Ruby/3.4.10/x64/bin/ruby extconf.rb
3
+ checking for rb_ext_ractor_safe() in ruby.h... yes
4
+ creating Makefile
5
+
6
+ current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/ext/erb/escape
7
+ make DESTDIR\= sitearchdir\=./.gem.20260719-2315-wnl2jv sitelibdir\=./.gem.20260719-2315-wnl2jv clean
8
+
9
+ current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/ext/erb/escape
10
+ make DESTDIR\= sitearchdir\=./.gem.20260719-2315-wnl2jv sitelibdir\=./.gem.20260719-2315-wnl2jv
11
+ compiling escape.c
12
+ linking shared-object erb/escape.so
13
+
14
+ current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/ext/erb/escape
15
+ make DESTDIR\= sitearchdir\=./.gem.20260719-2315-wnl2jv sitelibdir\=./.gem.20260719-2315-wnl2jv install
16
+ /usr/bin/install -c -m 0755 escape.so ./.gem.20260719-2315-wnl2jv/erb
17
+
18
+ current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/ext/erb/escape
19
+ make DESTDIR\= sitearchdir\=./.gem.20260719-2315-wnl2jv sitelibdir\=./.gem.20260719-2315-wnl2jv clean
@@ -1,2 +1,2 @@
1
- current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/ext
2
- /opt/hostedtoolcache/Ruby/3.4.10/x64/bin/ruby -rrubygems /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake RUBYARCHDIR\=/home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/lexxy-0.9.24 RUBYLIBDIR\=/home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/lexxy-0.9.24
1
+ current directory: /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/ext
2
+ /opt/hostedtoolcache/Ruby/3.4.10/x64/bin/ruby -rrubygems /home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake RUBYARCHDIR\=/home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/lexxy-0.9.25 RUBYLIBDIR\=/home/runner/work/lexxy-variables/lexxy-variables/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/lexxy-0.9.25
@@ -1,5 +1,11 @@
1
1
  ## Current
2
2
 
3
+ ## Release v1.3.8 (19 July 2026)
4
+
5
+ concurrent-ruby:
6
+
7
+ * See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.8).
8
+
3
9
  ## Release v1.3.7 (16 June 2026)
4
10
 
5
11
  concurrent-ruby:
@@ -3,6 +3,6 @@ module Concurrent
3
3
  # Various classes within allows for +nil+ values to be stored,
4
4
  # so a special +NULL+ token is required to indicate the "nil-ness".
5
5
  # @!visibility private
6
- NULL = ::Object.new
6
+ NULL = ::Object.new.freeze
7
7
 
8
8
  end
@@ -915,6 +915,7 @@ module Concurrent
915
915
  # Represents a value which will become available in future. May reject with a reason instead,
916
916
  # e.g. when the tasks raises an exception.
917
917
  class Future < AbstractEventFuture
918
+ SET_BACKTRACE_LOCATIONS_SUPPORTED = RUBY_VERSION >= '3.4'
918
919
 
919
920
  # Is it in fulfilled state?
920
921
  # @return [Boolean]
@@ -1014,9 +1015,10 @@ module Concurrent
1014
1015
  raise Concurrent::Error, 'it is not rejected' unless rejected?
1015
1016
  raise ArgumentError unless args.size <= 1
1016
1017
  reason = Array(internal_state.reason).flatten.compact
1018
+ callsites = SET_BACKTRACE_LOCATIONS_SUPPORTED ? caller_locations : caller
1017
1019
  if reason.size > 1
1018
1020
  ex = Concurrent::MultipleErrors.new reason
1019
- ex.set_backtrace(caller)
1021
+ ex.set_backtrace(callsites)
1020
1022
  ex
1021
1023
  else
1022
1024
  ex = if reason[0].respond_to? :exception
@@ -1024,7 +1026,11 @@ module Concurrent
1024
1026
  else
1025
1027
  RuntimeError.new(reason[0]).exception(*args)
1026
1028
  end
1027
- ex.set_backtrace Array(ex.backtrace) + caller
1029
+ if SET_BACKTRACE_LOCATIONS_SUPPORTED && (locations = ex.backtrace_locations)
1030
+ ex.set_backtrace locations + callsites
1031
+ else
1032
+ ex.set_backtrace Array(ex.backtrace) + callsites.map(&:to_s)
1033
+ end
1028
1034
  ex
1029
1035
  end
1030
1036
  end