richvalues 4.0.5__tar.gz → 4.0.6__tar.gz
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.
- {richvalues-4.0.5 → richvalues-4.0.6}/PKG-INFO +2 -2
- {richvalues-4.0.5 → richvalues-4.0.6}/README.md +1 -1
- {richvalues-4.0.5 → richvalues-4.0.6}/pyproject.toml +1 -1
- {richvalues-4.0.5 → richvalues-4.0.6}/richvalues/__init__.py +78 -37
- {richvalues-4.0.5 → richvalues-4.0.6}/richvalues.egg-info/PKG-INFO +2 -2
- {richvalues-4.0.5 → richvalues-4.0.6}/richvalues.egg-info/SOURCES.txt +0 -1
- {richvalues-4.0.5 → richvalues-4.0.6}/setup.py +1 -1
- richvalues-4.0.5/richvalues.egg-info/.DS_Store +0 -0
- {richvalues-4.0.5 → richvalues-4.0.6}/LICENSE +0 -0
- {richvalues-4.0.5 → richvalues-4.0.6}/richvalues.egg-info/dependency_links.txt +0 -0
- {richvalues-4.0.5 → richvalues-4.0.6}/richvalues.egg-info/requires.txt +0 -0
- {richvalues-4.0.5 → richvalues-4.0.6}/richvalues.egg-info/top_level.txt +0 -0
- {richvalues-4.0.5 → richvalues-4.0.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: richvalues
|
3
|
-
Version: 4.0.
|
3
|
+
Version: 4.0.6
|
4
4
|
Summary: Python library for working with uncertainties and upper/lower limits
|
5
5
|
Home-page: https://github.com/andresmegias/richvalues/
|
6
6
|
Author: Andrés Megías Toledano
|
@@ -15,7 +15,7 @@ License-File: LICENSE
|
|
15
15
|
|
16
16
|
RichValues is a Python 3 library for working with numeric values with uncertainties, upper/lower limits and finite intervals, which may be called _rich values_.
|
17
17
|
|
18
|
-
With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
|
18
|
+
With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/lower limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
|
19
19
|
|
20
20
|
The libraries NumPy, Pandas, SciPy and Matplotlib are required by RichValues. A user guide and a quick tutorial are available on GitHub: https://github.com/andresmegias/richvalues/.
|
21
21
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
RichValues is a Python 3 library for working with numeric values with uncertainties, upper/lower limits and finite intervals, which may be called _rich values_.
|
2
2
|
|
3
|
-
With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
|
3
|
+
With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/lower limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
|
4
4
|
|
5
5
|
The libraries NumPy, Pandas, SciPy and Matplotlib are required by RichValues. A user guide and a quick tutorial are available on GitHub: https://github.com/andresmegias/richvalues/.
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "richvalues"
|
7
|
-
version = "4.0.
|
7
|
+
version = "4.0.6"
|
8
8
|
description = "Python library for working with uncertainties and upper/lower limits"
|
9
9
|
license = {file="LICENSE"}
|
10
10
|
authors = [{name="Andrés Megías Toledano"}]
|
@@ -37,7 +37,7 @@ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
37
37
|
POSSIBILITY OF SUCH DAMAGE.
|
38
38
|
"""
|
39
39
|
|
40
|
-
__version__ = '4.0.
|
40
|
+
__version__ = '4.0.6'
|
41
41
|
__author__ = 'Andrés Megías Toledano'
|
42
42
|
|
43
43
|
import copy
|
@@ -238,7 +238,8 @@ def round_sf_unc(x, dx, n=None, min_exp=None, extra_sf_lim=None):
|
|
238
238
|
num_digits_x = len(str(x).split('.')[0])
|
239
239
|
if num_digits_y > num_digits_x:
|
240
240
|
m -= 1
|
241
|
-
|
241
|
+
base_dy = '{:e}'.format(float(dy)).split('e')[0]
|
242
|
+
if float(base_dy) <= extra_sf_lim:
|
242
243
|
m += 1
|
243
244
|
y = round_sf(x, m, min_exp, extra_sf_lim=1-1e-8)
|
244
245
|
else:
|
@@ -339,8 +340,10 @@ def round_sf_uncs(x, dx, n=None, min_exp=None, extra_sf_lim=None):
|
|
339
340
|
diff = num_dec_1 - num_dec_2
|
340
341
|
off1, off2 = 0, 0
|
341
342
|
if num_dec_1 == 0 == num_dec_2:
|
342
|
-
|
343
|
-
|
343
|
+
base_dy1 = '{:e}'.format(dx1).split('e')[0]
|
344
|
+
base_dy2 = '{:e}'.format(dx2).split('e')[0]
|
345
|
+
b1 = float(base_dy1) if np.isfinite(dx1) else 10.
|
346
|
+
b2 = float(base_dy2) if np.isfinite(dx2) else 10.
|
344
347
|
if dx2 > dx1 and b1 <= extra_sf_lim and b2 > extra_sf_lim:
|
345
348
|
off2 = 1
|
346
349
|
if dx1 > dx2 and b2 <= extra_sf_lim and b1 > extra_sf_lim:
|
@@ -945,13 +948,13 @@ class RichValue():
|
|
945
948
|
elif is_uplim:
|
946
949
|
symbol = '<'
|
947
950
|
y = int(np.ceil(x)) if is_int else x
|
948
|
-
min_exp = 0
|
949
951
|
y = round_sf(y, n, min_exp, extra_sf_lim)
|
950
|
-
|
951
|
-
|
952
|
+
if 'e' in y:
|
953
|
+
y, a = y.split('e')
|
954
|
+
else:
|
955
|
+
a = '0'
|
952
956
|
text = ('${} {} {}'.format(symbol, y, mult_symbol)
|
953
957
|
+ ' 10^{'+a+'}$')
|
954
|
-
text = text.replace('e-0', 'e-').replace('e+','e')
|
955
958
|
a = int(text.split('10^{')[1].split('}')[0])
|
956
959
|
if abs(a) < min_exp:
|
957
960
|
y = RichValue(x, dx, is_lolim, is_uplim,
|
@@ -962,7 +965,8 @@ class RichValue():
|
|
962
965
|
text = y.latex(*kwargs)
|
963
966
|
if (not use_extra_sf_in_exacts and omit_ones_in_sci_notation
|
964
967
|
and dx[0] == dx[1] and dx[0] == 0 or np.isnan(dx[0])):
|
965
|
-
|
968
|
+
if '.' not in text:
|
969
|
+
text = text.replace('1 {} '.format(mult_symbol), '')
|
966
970
|
else:
|
967
971
|
x1 = RichValue(main - unc[0], domain=domain)
|
968
972
|
x2 = RichValue(main + unc[1], domain=domain)
|
@@ -2663,7 +2667,7 @@ def add_rich_values(x, y):
|
|
2663
2667
|
is_int = x.is_int and y.is_int
|
2664
2668
|
domain = [x.domain[0] + y.domain[0], x.domain[1] + y.domain[1]]
|
2665
2669
|
sigmas = defaultparams['sigmas to use approximate uncertainty propagation']
|
2666
|
-
if x.is_exact or y.is_exact:
|
2670
|
+
if (x.is_exact or y.is_exact) and (x.is_interv or y.is_interv):
|
2667
2671
|
z = list(np.array(x.interval()) + np.array(y.interval()))
|
2668
2672
|
z = RichValue(z, domain=domain, is_int=is_int)
|
2669
2673
|
elif (not (x.is_interv or y.is_interv)
|
@@ -2687,7 +2691,7 @@ def multiply_rich_values(x, y):
|
|
2687
2691
|
is_int = x.is_int and y.is_int
|
2688
2692
|
domain = propagate_domain(x.domain, y.domain, lambda a,b: a*b)
|
2689
2693
|
sigmas = defaultparams['sigmas to use approximate uncertainty propagation']
|
2690
|
-
if x.is_exact or y.is_exact:
|
2694
|
+
if (x.is_exact or y.is_exact) and (x.is_interv or y.is_interv):
|
2691
2695
|
z = list(np.array(x.interval()) * np.array(y.interval()))
|
2692
2696
|
z = RichValue(z, domain=domain, is_int=is_int)
|
2693
2697
|
elif (not (x.is_interv or y.is_interv)
|
@@ -3070,7 +3074,7 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
|
|
3070
3074
|
unc = 0
|
3071
3075
|
is_lolim, is_uplim, is_range = False, False, True
|
3072
3076
|
min_exp = round(np.mean([me1, me2]))
|
3073
|
-
extra_sf_lim =
|
3077
|
+
extra_sf_lim = max(el1, el2)
|
3074
3078
|
return (main, unc, is_lolim, is_uplim, is_range, domain,
|
3075
3079
|
min_exp, extra_sf_lim)
|
3076
3080
|
|
@@ -3203,7 +3207,7 @@ def rich_array(array, domain=None, is_int=None,
|
|
3203
3207
|
rarray = RichArray(mains, uncs, are_lolims, are_uplims, are_ranges,
|
3204
3208
|
domains, are_ints, variables, expressions)
|
3205
3209
|
min_exp = round(np.mean(min_exps))
|
3206
|
-
extra_sf_lim =
|
3210
|
+
extra_sf_lim = max(extra_sf_lims)
|
3207
3211
|
rarray.set_params({'min_exp': min_exp, 'extra_sf_lim': extra_sf_lim})
|
3208
3212
|
return rarray
|
3209
3213
|
|
@@ -3582,7 +3586,7 @@ def loguniform_distribution(low=-1, high=1, size=1,
|
|
3582
3586
|
return distr
|
3583
3587
|
|
3584
3588
|
def distr_with_rich_values(function, args, len_samples=None,
|
3585
|
-
is_vectorizable=False):
|
3589
|
+
is_vectorizable=False, **kwargs):
|
3586
3590
|
"""
|
3587
3591
|
Same as function_with_rich_values, but just returns the final distribution.
|
3588
3592
|
"""
|
@@ -3688,7 +3692,7 @@ def remove_zero_infs(interval, zero_log, inf_log):
|
|
3688
3692
|
return new_interval
|
3689
3693
|
|
3690
3694
|
def evaluate_distr(distr, domain=None, function=None, args=None,
|
3691
|
-
len_samples=None, is_vectorizable=False, consider_intervs=
|
3695
|
+
len_samples=None, is_vectorizable=False, consider_intervs=None,
|
3692
3696
|
is_domain_cyclic=False, lims_fraction=None, num_reps_lims=None,
|
3693
3697
|
save_pdf=None, **kwargs):
|
3694
3698
|
"""
|
@@ -3776,8 +3780,13 @@ def evaluate_distr(distr, domain=None, function=None, args=None,
|
|
3776
3780
|
if args is not None:
|
3777
3781
|
if type(args) not in (tuple, list):
|
3778
3782
|
args = [args]
|
3779
|
-
|
3780
|
-
|
3783
|
+
if type(args[0]) is not RichArray:
|
3784
|
+
args = [rich_value(arg) if type(arg) not in
|
3785
|
+
(RichValue, ComplexRichValue) else arg for arg in args]
|
3786
|
+
if consider_intervs is None:
|
3787
|
+
consider_intervs = True
|
3788
|
+
if args is not None and all([arg.is_centr for arg in args]):
|
3789
|
+
consider_intervs = False
|
3781
3790
|
|
3782
3791
|
distr = np.array(distr)
|
3783
3792
|
|
@@ -4076,6 +4085,7 @@ def function_with_rich_values(function, args, unc_function=None,
|
|
4076
4085
|
args = [args]
|
4077
4086
|
args = [rich_value(arg) if type(arg) not in (RichValue, ComplexRichValue)
|
4078
4087
|
else arg for arg in args]
|
4088
|
+
args_copy = copy.copy(args)
|
4079
4089
|
|
4080
4090
|
input_function = copy.copy(function)
|
4081
4091
|
if type(function) is str:
|
@@ -4119,7 +4129,7 @@ def function_with_rich_values(function, args, unc_function=None,
|
|
4119
4129
|
|
4120
4130
|
if len_samples is None:
|
4121
4131
|
len_samples = int(len(args)**0.5 * defaultparams['size of samples'])
|
4122
|
-
num_sf =
|
4132
|
+
num_sf = int(np.median([arg.num_sf for arg in args]))
|
4123
4133
|
min_exp = round(np.mean([arg.min_exp for arg in args]))
|
4124
4134
|
extra_sf_lim = max([arg.extra_sf_lim for arg in args])
|
4125
4135
|
|
@@ -4136,9 +4146,6 @@ def function_with_rich_values(function, args, unc_function=None,
|
|
4136
4146
|
use_analytic_propagation = False
|
4137
4147
|
|
4138
4148
|
args_main = np.array([arg.main for arg in args])
|
4139
|
-
# print()
|
4140
|
-
# print(args)
|
4141
|
-
# print(args[0].expression)
|
4142
4149
|
with np.errstate(divide='ignore', invalid='ignore'):
|
4143
4150
|
main = function(*args_main)
|
4144
4151
|
output_size = np.array(main).size
|
@@ -4224,16 +4231,14 @@ def function_with_rich_values(function, args, unc_function=None,
|
|
4224
4231
|
|
4225
4232
|
mains = [main] if output_size == 1 else main
|
4226
4233
|
if unc_function is not None:
|
4227
|
-
|
4228
|
-
|
4234
|
+
uncs = []
|
4235
|
+
args_main = np.array([arg.main for arg in args_copy])
|
4236
|
+
for i in (0,1):
|
4237
|
+
args_unc = [arg.unc[i] for arg in args_copy]
|
4238
|
+
uncs += [unc_function(*args_main, *args_unc)]
|
4229
4239
|
uncs = [uncs] if output_size == 1 else uncs
|
4230
|
-
|
4231
|
-
|
4232
|
-
if not hasattr(uncs[k], '__iter__'):
|
4233
|
-
uncs[k] = [uncs[k]]*2
|
4234
|
-
uncs[k][1] = abs(uncs[k][1])
|
4235
|
-
if not hasattr(uncs,'__iter__'):
|
4236
|
-
uncs = [uncs]*output_size
|
4240
|
+
for k in range(output_size):
|
4241
|
+
uncs[k][1] = abs(uncs[k][1])
|
4237
4242
|
else:
|
4238
4243
|
inds_combs = list(itertools.product(*[[0,1,2]]*len(args)))
|
4239
4244
|
comb_main = tuple([1]*len(args))
|
@@ -4261,6 +4266,9 @@ def function_with_rich_values(function, args, unc_function=None,
|
|
4261
4266
|
real_k = RichValue(main_k.real, unc_k.real, domain=domain_k)
|
4262
4267
|
imag_k = RichValue(main_k.imag, unc_k.imag, domain=domain_k)
|
4263
4268
|
rval_k = ComplexRichValue(real_k, imag_k)
|
4269
|
+
rval_k.num_sf = num_sf
|
4270
|
+
rval_k.min_exp = min_exp
|
4271
|
+
rval_k.extra_sf_lim = extra_sf_lim
|
4264
4272
|
output += [rval_k]
|
4265
4273
|
|
4266
4274
|
else:
|
@@ -4336,6 +4344,37 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
|
|
4336
4344
|
output : rich array / rich value
|
4337
4345
|
Result of the function.
|
4338
4346
|
"""
|
4347
|
+
if 'domain' in kwargs:
|
4348
|
+
domain = kwargs['domain']
|
4349
|
+
del kwargs['domain']
|
4350
|
+
else:
|
4351
|
+
domain = None
|
4352
|
+
distr = distr_with_rich_arrays(function, args, elementwise, **kwargs)
|
4353
|
+
if len(distr.shape) == 1:
|
4354
|
+
output = evaluate_distr(distr, domain, function, args, **kwargs)
|
4355
|
+
else:
|
4356
|
+
output_size = distr.shape[1]
|
4357
|
+
output = []
|
4358
|
+
for k in range(output_size):
|
4359
|
+
function_k = lambda *args: function(args)[k]
|
4360
|
+
rval_k = evaluate_distr(distr[:,k], domain, function_k, args,
|
4361
|
+
**kwargs)
|
4362
|
+
output += [rval_k]
|
4363
|
+
args_main = np.array([arg.main for arg in args])
|
4364
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
4365
|
+
main = function(*args_main)
|
4366
|
+
output_size = np.array(main).size
|
4367
|
+
output_type = RichArray if type(main) is np.ndarray else type(main)
|
4368
|
+
if output_type is tuple and output_size > 1:
|
4369
|
+
output = tuple(output)
|
4370
|
+
elif output_type is RichArray:
|
4371
|
+
output = np.array(output).view(RichArray)
|
4372
|
+
return output
|
4373
|
+
|
4374
|
+
def distr_with_rich_arrays(function, args, elementwise=False, **kwargs):
|
4375
|
+
"""
|
4376
|
+
Same as function_with_rich_arrays, but just returns the final distribution.
|
4377
|
+
"""
|
4339
4378
|
if type(args) not in (tuple, list):
|
4340
4379
|
args = [args]
|
4341
4380
|
args = [rich_array(arg) if type(arg) != RichArray else arg
|
@@ -4351,6 +4390,8 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
|
|
4351
4390
|
if 'len_samples' not in kwargs:
|
4352
4391
|
kwargs['len_samples'] = int(len(args)**0.5
|
4353
4392
|
* defaultparams['size of samples'])
|
4393
|
+
if 'consider_intervs' in kwargs:
|
4394
|
+
del kwargs['consider_intervs']
|
4354
4395
|
if elementwise:
|
4355
4396
|
same_shapes = True
|
4356
4397
|
for arg in args[1:]:
|
@@ -4359,15 +4400,14 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
|
|
4359
4400
|
break
|
4360
4401
|
if not same_shapes:
|
4361
4402
|
raise Exception('Input arrays have different shapes.')
|
4362
|
-
array = np.empty(0,
|
4403
|
+
array = np.empty(0, float)
|
4363
4404
|
args_flat = np.array([arg.flatten() for arg in args])
|
4364
4405
|
for i in range(args[0].size):
|
4365
4406
|
args_i = np.array(args_flat)[:,i].tolist()
|
4366
|
-
rvalue =
|
4407
|
+
rvalue = distr_with_rich_values(function, args_i, **kwargs)
|
4367
4408
|
array = np.append(array, rvalue)
|
4368
4409
|
if shape == ():
|
4369
4410
|
array = np.array(array[0])
|
4370
|
-
array = array.view(RichArray)
|
4371
4411
|
output = array
|
4372
4412
|
else:
|
4373
4413
|
if type(function) is str:
|
@@ -4410,7 +4450,7 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
|
|
4410
4450
|
alt_args = []
|
4411
4451
|
for arg in args:
|
4412
4452
|
alt_args += list(arg.flat)
|
4413
|
-
output =
|
4453
|
+
output = distr_with_rich_values(alt_function, alt_args, **kwargs)
|
4414
4454
|
return output
|
4415
4455
|
|
4416
4456
|
def fmean(array, function='None', inverse_function='None',
|
@@ -4524,12 +4564,12 @@ def errorbar(x, y, lims_factor=None, **kwargs):
|
|
4524
4564
|
xa, ya = rich_array(x), rich_array(y)
|
4525
4565
|
xc = rich_array([x]) if len(xa.shape) == 0 else xa
|
4526
4566
|
yc = rich_array([y]) if len(ya.shape) == 0 else ya
|
4527
|
-
if lims_factor
|
4528
|
-
lims_factor_x, lims_factor_y = None, None
|
4529
|
-
elif type(lims_factor) in (float, int):
|
4567
|
+
if type(lims_factor) in (float, int):
|
4530
4568
|
lims_factor_x, lims_factor_y = [lims_factor]*2
|
4531
4569
|
elif type(lims_factor) in (list, tuple):
|
4532
4570
|
lims_factor_x, lims_factor_y = lims_factor
|
4571
|
+
else:
|
4572
|
+
lims_factor_x, lims_factor_y = None, None
|
4533
4573
|
if lims_factor_x is None:
|
4534
4574
|
lims_factor_x = lim_factor(xc)
|
4535
4575
|
if lims_factor_y is None:
|
@@ -4979,6 +5019,7 @@ rich_df = rdataframe = rich_dataframe
|
|
4979
5019
|
function = function_with_rich_values
|
4980
5020
|
array_function = function_with_rich_arrays
|
4981
5021
|
distribution = distr_with_rich_values
|
5022
|
+
array_distribution = distr_with_rich_arrays
|
4982
5023
|
evaluate_distribution = evaluate_distr
|
4983
5024
|
center_and_uncertainties = center_and_uncs
|
4984
5025
|
is_not_a_number = is_nan = isnan
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: richvalues
|
3
|
-
Version: 4.0.
|
3
|
+
Version: 4.0.6
|
4
4
|
Summary: Python library for working with uncertainties and upper/lower limits
|
5
5
|
Home-page: https://github.com/andresmegias/richvalues/
|
6
6
|
Author: Andrés Megías Toledano
|
@@ -15,7 +15,7 @@ License-File: LICENSE
|
|
15
15
|
|
16
16
|
RichValues is a Python 3 library for working with numeric values with uncertainties, upper/lower limits and finite intervals, which may be called _rich values_.
|
17
17
|
|
18
|
-
With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
|
18
|
+
With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/lower limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
|
19
19
|
|
20
20
|
The libraries NumPy, Pandas, SciPy and Matplotlib are required by RichValues. A user guide and a quick tutorial are available on GitHub: https://github.com/andresmegias/richvalues/.
|
21
21
|
|
@@ -5,7 +5,7 @@ with open('README.md', 'r') as file:
|
|
5
5
|
|
6
6
|
setuptools.setup(
|
7
7
|
name = 'richvalues',
|
8
|
-
version = '4.0.
|
8
|
+
version = '4.0.6',
|
9
9
|
license = 'BSD-3-Clause',
|
10
10
|
author = 'Andrés Megías Toledano',
|
11
11
|
description = 'Python library for working with uncertainties and upper/lower limits',
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|