absmartly-sdk 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +180 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +92 -0
- data/LICENSE.txt +21 -0
- data/README +180 -0
- data/Rakefile +12 -0
- data/example/example.rb +48 -0
- data/lib/a_b_smartly.rb +92 -0
- data/lib/a_b_smartly_config.rb +49 -0
- data/lib/absmartly/md5.rb +178 -0
- data/lib/absmartly/variant_assigner.rb +36 -0
- data/lib/absmartly/version.rb +5 -0
- data/lib/absmartly.rb +57 -0
- data/lib/audience_deserializer.rb +8 -0
- data/lib/audience_matcher.rb +38 -0
- data/lib/client.rb +80 -0
- data/lib/client_config.rb +43 -0
- data/lib/context.rb +528 -0
- data/lib/context_config.rb +70 -0
- data/lib/context_data_deserializer.rb +8 -0
- data/lib/context_data_provider.rb +8 -0
- data/lib/context_event_handler.rb +8 -0
- data/lib/context_event_logger.rb +9 -0
- data/lib/context_event_serializer.rb +8 -0
- data/lib/default_audience_deserializer.rb +13 -0
- data/lib/default_context_data_deserializer.rb +16 -0
- data/lib/default_context_data_provider.rb +15 -0
- data/lib/default_context_event_handler.rb +15 -0
- data/lib/default_context_event_serializer.rb +58 -0
- data/lib/default_http_client.rb +61 -0
- data/lib/default_http_client_config.rb +19 -0
- data/lib/default_variable_parser.rb +13 -0
- data/lib/hashing.rb +9 -0
- data/lib/http_client.rb +20 -0
- data/lib/json/attribute.rb +30 -0
- data/lib/json/context_data.rb +31 -0
- data/lib/json/experiment.rb +83 -0
- data/lib/json/experiment_application.rb +27 -0
- data/lib/json/experiment_variant.rb +29 -0
- data/lib/json/exposure.rb +60 -0
- data/lib/json/goal_achievement.rb +32 -0
- data/lib/json/publish_event.rb +42 -0
- data/lib/json/unit.rb +30 -0
- data/lib/json_expr/evaluator.rb +27 -0
- data/lib/json_expr/expr_evaluator.rb +122 -0
- data/lib/json_expr/json_expr.rb +37 -0
- data/lib/json_expr/operator.rb +8 -0
- data/lib/json_expr/operators/and_combinator.rb +14 -0
- data/lib/json_expr/operators/binary_operator.rb +22 -0
- data/lib/json_expr/operators/boolean_combinator.rb +15 -0
- data/lib/json_expr/operators/equals_operator.rb +12 -0
- data/lib/json_expr/operators/greater_than_operator.rb +12 -0
- data/lib/json_expr/operators/greater_than_or_equal_operator.rb +12 -0
- data/lib/json_expr/operators/in_operator.rb +23 -0
- data/lib/json_expr/operators/less_than_operator.rb +12 -0
- data/lib/json_expr/operators/less_than_or_equal_operator.rb +12 -0
- data/lib/json_expr/operators/match_operator.rb +17 -0
- data/lib/json_expr/operators/nil_operator.rb +11 -0
- data/lib/json_expr/operators/not_operator.rb +11 -0
- data/lib/json_expr/operators/or_combinator.rb +14 -0
- data/lib/json_expr/operators/unary_operator.rb +13 -0
- data/lib/json_expr/operators/value_operator.rb +11 -0
- data/lib/json_expr/operators/var_operator.rb +21 -0
- data/lib/scheduled_executor_service.rb +8 -0
- data/lib/scheduled_thread_pool_executor.rb +14 -0
- data/lib/string.rb +30 -0
- data/lib/variable_parser.rb +8 -0
- data/lib/variant_assigner.rb +47 -0
- data/sig/absmartly.rbs +4 -0
- metadata +120 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bigdecimal"
|
4
|
+
require_relative "../string"
|
5
|
+
require_relative "./evaluator"
|
6
|
+
EMPTY_MAP = {}
|
7
|
+
EMPTY_LIST = []
|
8
|
+
|
9
|
+
class ExprEvaluator < Evaluator
|
10
|
+
attr_accessor :operators
|
11
|
+
attr_accessor :vars
|
12
|
+
NUMERIC_REGEX = /\A[-+]?[0-9]*\.?[0-9]+\Z/
|
13
|
+
|
14
|
+
def initialize(operators, vars)
|
15
|
+
@operators = operators
|
16
|
+
@vars = vars
|
17
|
+
end
|
18
|
+
|
19
|
+
def evaluate(expr)
|
20
|
+
if expr.is_a? Array
|
21
|
+
return @operators[:and].evaluate(self, expr)
|
22
|
+
elsif expr.is_a? Hash
|
23
|
+
expr.transform_keys(&:to_sym).each do |key, value|
|
24
|
+
if @operators[key]
|
25
|
+
return @operators[key].evaluate(self, value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def boolean_convert(x)
|
33
|
+
if x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
34
|
+
return x
|
35
|
+
elsif x.is_a?(Numeric) || !(x =~ NUMERIC_REGEX).nil?
|
36
|
+
return !x.to_f.zero?
|
37
|
+
elsif x.is_a?(String)
|
38
|
+
return x != "false" && x != "0" && x != ""
|
39
|
+
end
|
40
|
+
|
41
|
+
!x.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def number_convert(x)
|
45
|
+
return if x.nil? || x.to_s.empty?
|
46
|
+
|
47
|
+
if x.is_a?(Numeric) || !(x =~ NUMERIC_REGEX).nil?
|
48
|
+
return x.to_f
|
49
|
+
elsif x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
50
|
+
return x ? 1.0 : 0.0
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def string_convert(x)
|
56
|
+
if x.is_a?(String)
|
57
|
+
return x
|
58
|
+
elsif x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
59
|
+
return x.to_s
|
60
|
+
elsif x.is_a?(Numeric) || !(x =~ NUMERIC_REGEX).nil?
|
61
|
+
return x == x.to_i ? x.to_i.to_s : x.to_s
|
62
|
+
end
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def extract_var(path)
|
67
|
+
frags = path.split("/")
|
68
|
+
target = !vars.nil? ? vars : {}
|
69
|
+
|
70
|
+
frags.each do |frag|
|
71
|
+
list = target
|
72
|
+
value = nil
|
73
|
+
if target.is_a?(Array)
|
74
|
+
value = list[frag.to_i]
|
75
|
+
elsif target.is_a?(Hash)
|
76
|
+
value = list[frag].nil? ? list[frag.to_sym] : list[frag]
|
77
|
+
end
|
78
|
+
|
79
|
+
unless value.nil?
|
80
|
+
target = value
|
81
|
+
next
|
82
|
+
end
|
83
|
+
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
target
|
87
|
+
end
|
88
|
+
|
89
|
+
def compare(lhs, rhs)
|
90
|
+
if lhs.nil?
|
91
|
+
return rhs.nil? ? 0 : nil
|
92
|
+
elsif rhs.nil?
|
93
|
+
return nil
|
94
|
+
end
|
95
|
+
|
96
|
+
if lhs.is_a?(Numeric)
|
97
|
+
rvalue = number_convert(rhs)
|
98
|
+
return lhs.to_f.to_s.casecmp(rvalue.to_s) unless rvalue.nil?
|
99
|
+
elsif lhs.is_a?(String)
|
100
|
+
rvalue = string_convert(rhs)
|
101
|
+
return lhs.compare_to(rvalue) unless rvalue.nil?
|
102
|
+
elsif lhs.is_a?(TrueClass) || lhs.is_a?(FalseClass)
|
103
|
+
rvalue = boolean_convert(rhs)
|
104
|
+
return lhs.to_s.casecmp(rvalue.to_s) unless rvalue.nil?
|
105
|
+
elsif lhs.class == rhs.class && lhs === rhs
|
106
|
+
return 0
|
107
|
+
end
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class Array
|
113
|
+
def self.wrap(object)
|
114
|
+
if object.nil?
|
115
|
+
[]
|
116
|
+
elsif object.respond_to?(:to_ary)
|
117
|
+
object.to_ary || [object]
|
118
|
+
else
|
119
|
+
[object]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./expr_evaluator"
|
4
|
+
Dir["lib/json_expr/operators/*.rb"].each { |file| require "./#{file}" }
|
5
|
+
|
6
|
+
class JsonExpr
|
7
|
+
attr_accessor :operators
|
8
|
+
attr_accessor :vars
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@operators = {
|
12
|
+
"and": AndCombinator.new,
|
13
|
+
"or": OrCombinator.new,
|
14
|
+
"value": ValueOperator.new,
|
15
|
+
"var": VarOperator.new,
|
16
|
+
"null": NilOperator.new,
|
17
|
+
"not": NotOperator.new,
|
18
|
+
"in": InOperator.new,
|
19
|
+
"match": MatchOperator.new,
|
20
|
+
"eq": EqualsOperator.new,
|
21
|
+
"gt": GreaterThanOperator.new,
|
22
|
+
"gte": GreaterThanOrEqualOperator.new,
|
23
|
+
"lt": LessThanOperator.new,
|
24
|
+
"lte": LessThanOrEqualOperator.new
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def evaluate_boolean_expr(expr, vars)
|
29
|
+
evaluator = ExprEvaluator.new(operators, vars)
|
30
|
+
evaluator.boolean_convert(evaluator.evaluate(expr))
|
31
|
+
end
|
32
|
+
|
33
|
+
def evaluate_expr(expr, vars)
|
34
|
+
evaluator = ExprEvaluator.new(operators, vars)
|
35
|
+
evaluator.evaluate(expr)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "boolean_combinator"
|
4
|
+
|
5
|
+
class AndCombinator
|
6
|
+
include BooleanCombinator
|
7
|
+
|
8
|
+
def combine(evaluator, exprs)
|
9
|
+
Array.wrap(exprs).each do |expr|
|
10
|
+
return false unless evaluator.boolean_convert(evaluator.evaluate(expr))
|
11
|
+
end
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BinaryOperator
|
4
|
+
def evaluate(evaluator, args)
|
5
|
+
if args.is_a? Array
|
6
|
+
args_list = args
|
7
|
+
lhs = args_list.size > 0 ? evaluator.evaluate(args_list[0]) : nil
|
8
|
+
unless lhs.nil?
|
9
|
+
rhs = args_list.size > 1 ? evaluator.evaluate(args_list[1]) : nil
|
10
|
+
unless rhs.nil?
|
11
|
+
return binary(evaluator, lhs, rhs)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
# @abstract method
|
19
|
+
def binary(evaluator, lhs, rhs)
|
20
|
+
raise NotImplementedError.new("You must implement binary method.")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BooleanCombinator
|
4
|
+
def evaluate(evaluator, args)
|
5
|
+
if args.is_a? Array
|
6
|
+
return combine(evaluator, args)
|
7
|
+
end
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
# @abstract method
|
12
|
+
def combine(evaluator, args)
|
13
|
+
raise NotImplementedError.new("You must implement combine method.")
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "binary_operator"
|
4
|
+
|
5
|
+
class GreaterThanOrEqualOperator
|
6
|
+
include BinaryOperator
|
7
|
+
|
8
|
+
def binary(evaluator, lhs, rhs)
|
9
|
+
result = evaluator.compare(lhs, rhs)
|
10
|
+
!result.nil? ? (result >= 0) : nil
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "binary_operator"
|
4
|
+
|
5
|
+
class InOperator
|
6
|
+
include BinaryOperator
|
7
|
+
|
8
|
+
def binary(evaluator, haystack, needle)
|
9
|
+
if haystack.is_a? Array
|
10
|
+
haystack.each do |item|
|
11
|
+
return true if evaluator.compare(item, needle) == 0
|
12
|
+
end
|
13
|
+
return false
|
14
|
+
elsif haystack.is_a? String
|
15
|
+
needle_string = evaluator.string_convert(needle)
|
16
|
+
return !needle_string.nil? && haystack.include?(needle_string)
|
17
|
+
elsif haystack.is_a?(Hash)
|
18
|
+
needle_string = evaluator.string_convert(needle)
|
19
|
+
return !needle_string.nil? && haystack.key?(needle_string)
|
20
|
+
end
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "binary_operator"
|
4
|
+
|
5
|
+
class MatchOperator
|
6
|
+
include BinaryOperator
|
7
|
+
|
8
|
+
def binary(evaluator, lhs, rhs)
|
9
|
+
text = evaluator.string_convert(lhs)
|
10
|
+
unless text.nil?
|
11
|
+
pattern = evaluator.string_convert(rhs)
|
12
|
+
unless pattern.nil?
|
13
|
+
text.match(pattern)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "boolean_combinator"
|
4
|
+
|
5
|
+
class OrCombinator
|
6
|
+
include BooleanCombinator
|
7
|
+
|
8
|
+
def combine(evaluator, exprs)
|
9
|
+
Array.wrap(exprs).each do |expr|
|
10
|
+
return true if evaluator.boolean_convert(evaluator.evaluate(expr))
|
11
|
+
end
|
12
|
+
Array.wrap(exprs).empty?
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UnaryOperator
|
4
|
+
def evaluate(evaluator, args)
|
5
|
+
arg = evaluator.evaluate(args)
|
6
|
+
unary(evaluator, arg)
|
7
|
+
end
|
8
|
+
|
9
|
+
# @abstract method
|
10
|
+
def unary(evaluator, arg)
|
11
|
+
raise NotImplementedError.new("You must implement unnnary method.")
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "binary_operator"
|
4
|
+
|
5
|
+
class VarOperator
|
6
|
+
include BinaryOperator
|
7
|
+
|
8
|
+
def evaluate(evaluator, path)
|
9
|
+
if path.is_a?(Hash)
|
10
|
+
path = to_sym(path)
|
11
|
+
path = path[:path]
|
12
|
+
end
|
13
|
+
|
14
|
+
path.is_a?(String) ? evaluator.extract_var(path) : nil
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def to_sym(path)
|
19
|
+
path.transform_keys(&:to_sym)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "audience_deserializer"
|
4
|
+
|
5
|
+
class ScheduledThreadPoolExecutor < AudienceDeserializer
|
6
|
+
attr_accessor :log, :reader
|
7
|
+
|
8
|
+
def initialize(timer = 1)
|
9
|
+
end
|
10
|
+
|
11
|
+
def deserialize(bytes, offset, length)
|
12
|
+
@reader.read_value(bytes, offset, length)
|
13
|
+
end
|
14
|
+
end
|
data/lib/string.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class String
|
4
|
+
def compare_to(another_string)
|
5
|
+
value = self.bytes
|
6
|
+
other = another_string.bytes
|
7
|
+
len1 = value.size
|
8
|
+
len2 = other.size
|
9
|
+
lim = [len1, len2].min
|
10
|
+
|
11
|
+
0.upto(lim - 1) do |k|
|
12
|
+
if value[k] != other[k]
|
13
|
+
return get_char(value, k) - get_char(other, k)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
len1 - len2
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_char(val, index)
|
20
|
+
val[index] & 0xff
|
21
|
+
end
|
22
|
+
|
23
|
+
def underscore
|
24
|
+
self.gsub(/::/, "/").
|
25
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
26
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
27
|
+
tr("-", "_").
|
28
|
+
downcase
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "murmurhash3"
|
4
|
+
require_relative "./hashing"
|
5
|
+
|
6
|
+
class VariantAssigner
|
7
|
+
attr_reader :key
|
8
|
+
|
9
|
+
def initialize(key)
|
10
|
+
md5 = Hashing.hash_unit(key.to_s)
|
11
|
+
@key = MurmurHash3::V32.str_hash(md5)
|
12
|
+
@normalizer = 1.0 / 0xffffffff
|
13
|
+
end
|
14
|
+
|
15
|
+
def probability(seed_hi, seed_lo)
|
16
|
+
buffer = Array.new
|
17
|
+
put_uint32(buffer, seed_lo)
|
18
|
+
put_uint32(buffer, seed_hi)
|
19
|
+
put_uint32(buffer, key)
|
20
|
+
hash = MurmurHash3::V32.str_hash(buffer.pack("C*"))
|
21
|
+
|
22
|
+
prob = (hash & 0xffffffff) * @normalizer
|
23
|
+
prob
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.choose_variant(split, prob)
|
27
|
+
sum = 0
|
28
|
+
split.each_with_index do |s, i|
|
29
|
+
sum += s
|
30
|
+
return i if prob < sum
|
31
|
+
end
|
32
|
+
|
33
|
+
split.count - 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def assign(split, seed_hi, seed_lo)
|
37
|
+
prob = probability(seed_hi, seed_lo)
|
38
|
+
self.class.choose_variant(split, prob)
|
39
|
+
end
|
40
|
+
|
41
|
+
def put_uint32(buffer, x)
|
42
|
+
buffer << (x & 0xff)
|
43
|
+
buffer << ((x >> 8) & 0xff)
|
44
|
+
buffer << ((x >> 16) & 0xff)
|
45
|
+
buffer << ((x >> 24) & 0xff)
|
46
|
+
end
|
47
|
+
end
|
data/sig/absmartly.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: absmartly-sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- absmartly
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-12-04 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Absmartly gem
|
14
|
+
email:
|
15
|
+
- sdks@absmartly.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files:
|
19
|
+
- README
|
20
|
+
files:
|
21
|
+
- ".rspec"
|
22
|
+
- ".rubocop.yml"
|
23
|
+
- ".ruby-version"
|
24
|
+
- CHANGELOG.md
|
25
|
+
- CODE_OF_CONDUCT.md
|
26
|
+
- Gemfile
|
27
|
+
- Gemfile.lock
|
28
|
+
- LICENSE.txt
|
29
|
+
- README
|
30
|
+
- Rakefile
|
31
|
+
- example/example.rb
|
32
|
+
- lib/a_b_smartly.rb
|
33
|
+
- lib/a_b_smartly_config.rb
|
34
|
+
- lib/absmartly.rb
|
35
|
+
- lib/absmartly/md5.rb
|
36
|
+
- lib/absmartly/variant_assigner.rb
|
37
|
+
- lib/absmartly/version.rb
|
38
|
+
- lib/audience_deserializer.rb
|
39
|
+
- lib/audience_matcher.rb
|
40
|
+
- lib/client.rb
|
41
|
+
- lib/client_config.rb
|
42
|
+
- lib/context.rb
|
43
|
+
- lib/context_config.rb
|
44
|
+
- lib/context_data_deserializer.rb
|
45
|
+
- lib/context_data_provider.rb
|
46
|
+
- lib/context_event_handler.rb
|
47
|
+
- lib/context_event_logger.rb
|
48
|
+
- lib/context_event_serializer.rb
|
49
|
+
- lib/default_audience_deserializer.rb
|
50
|
+
- lib/default_context_data_deserializer.rb
|
51
|
+
- lib/default_context_data_provider.rb
|
52
|
+
- lib/default_context_event_handler.rb
|
53
|
+
- lib/default_context_event_serializer.rb
|
54
|
+
- lib/default_http_client.rb
|
55
|
+
- lib/default_http_client_config.rb
|
56
|
+
- lib/default_variable_parser.rb
|
57
|
+
- lib/hashing.rb
|
58
|
+
- lib/http_client.rb
|
59
|
+
- lib/json/attribute.rb
|
60
|
+
- lib/json/context_data.rb
|
61
|
+
- lib/json/experiment.rb
|
62
|
+
- lib/json/experiment_application.rb
|
63
|
+
- lib/json/experiment_variant.rb
|
64
|
+
- lib/json/exposure.rb
|
65
|
+
- lib/json/goal_achievement.rb
|
66
|
+
- lib/json/publish_event.rb
|
67
|
+
- lib/json/unit.rb
|
68
|
+
- lib/json_expr/evaluator.rb
|
69
|
+
- lib/json_expr/expr_evaluator.rb
|
70
|
+
- lib/json_expr/json_expr.rb
|
71
|
+
- lib/json_expr/operator.rb
|
72
|
+
- lib/json_expr/operators/and_combinator.rb
|
73
|
+
- lib/json_expr/operators/binary_operator.rb
|
74
|
+
- lib/json_expr/operators/boolean_combinator.rb
|
75
|
+
- lib/json_expr/operators/equals_operator.rb
|
76
|
+
- lib/json_expr/operators/greater_than_operator.rb
|
77
|
+
- lib/json_expr/operators/greater_than_or_equal_operator.rb
|
78
|
+
- lib/json_expr/operators/in_operator.rb
|
79
|
+
- lib/json_expr/operators/less_than_operator.rb
|
80
|
+
- lib/json_expr/operators/less_than_or_equal_operator.rb
|
81
|
+
- lib/json_expr/operators/match_operator.rb
|
82
|
+
- lib/json_expr/operators/nil_operator.rb
|
83
|
+
- lib/json_expr/operators/not_operator.rb
|
84
|
+
- lib/json_expr/operators/or_combinator.rb
|
85
|
+
- lib/json_expr/operators/unary_operator.rb
|
86
|
+
- lib/json_expr/operators/value_operator.rb
|
87
|
+
- lib/json_expr/operators/var_operator.rb
|
88
|
+
- lib/scheduled_executor_service.rb
|
89
|
+
- lib/scheduled_thread_pool_executor.rb
|
90
|
+
- lib/string.rb
|
91
|
+
- lib/variable_parser.rb
|
92
|
+
- lib/variant_assigner.rb
|
93
|
+
- sig/absmartly.rbs
|
94
|
+
homepage: https://github.com/absmartly/ruby-sdk
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata:
|
98
|
+
homepage_uri: https://github.com/absmartly/ruby-sdk
|
99
|
+
source_code_uri: https://github.com/absmartly/ruby-sdk
|
100
|
+
changelog_uri: https://github.com/absmartly/ruby-sdk
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.7.0
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubygems_version: 3.1.6
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: Absmartly gem
|
120
|
+
test_files: []
|