modelflowib 2.84__tar.gz → 2.86__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.
- {modelflowib-2.84 → modelflowib-2.86}/PKG-INFO +3 -2
- {modelflowib-2.84 → modelflowib-2.86}/modelclass.py +19 -5
- {modelflowib-2.84 → modelflowib-2.86}/modelflowib.egg-info/PKG-INFO +3 -2
- {modelflowib-2.84 → modelflowib-2.86}/modelflowib.egg-info/requires.txt +2 -1
- {modelflowib-2.84 → modelflowib-2.86}/modelreport.py +15 -8
- {modelflowib-2.84 → modelflowib-2.86}/modelwidget.py +50 -13
- {modelflowib-2.84 → modelflowib-2.86}/pyproject.toml +3 -2
- {modelflowib-2.84 → modelflowib-2.86}/README.md +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/license.md +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelBLfunk.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_Excel.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_cvx.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_dynare.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_financial_stability.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_latex.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_latex_class.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/model_parquet_mixin.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelcausality.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelconstruct.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelconstruct_estimation.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeldash.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeldashboot.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeldashsidebar.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeldekom.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeldiff.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeldisplay.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelestimation.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelestimator_new.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelflowib.egg-info/SOURCES.txt +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelflowib.egg-info/dependency_links.txt +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelflowib.egg-info/top_level.txt +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelgrab.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelgrabgdx.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelgrabwf2.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelhelp.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelhtml.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelinput_shiny.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelinvert.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeljupyter.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeljupytermagic.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelmacrograb.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelmanipulation.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelmf.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelnet.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelnewton.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelnormalize.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelpattern.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelsolver_ng.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modeluserfunk.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelvis.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelwidget_core.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/modelwidget_input.py +0 -0
- {modelflowib-2.84 → modelflowib-2.86}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelflowib
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.86
|
|
4
4
|
Summary: A tool to solve and manage dynamic economic and financial models
|
|
5
5
|
Author-email: Ib Hansen <Ib.Hansen.Iv@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -21,7 +21,6 @@ Requires-Dist: networkx
|
|
|
21
21
|
Requires-Dist: tqdm
|
|
22
22
|
Requires-Dist: scipy
|
|
23
23
|
Requires-Dist: XlsxWriter
|
|
24
|
-
Requires-Dist: pyarrow
|
|
25
24
|
Requires-Dist: tabulate
|
|
26
25
|
Requires-Dist: openpyxl
|
|
27
26
|
Requires-Dist: xarray
|
|
@@ -41,7 +40,9 @@ Requires-Dist: dash; sys_platform != "emscripten"
|
|
|
41
40
|
Requires-Dist: dash-bootstrap-components; sys_platform != "emscripten"
|
|
42
41
|
Requires-Dist: dash-interactive-graphviz; sys_platform != "emscripten"
|
|
43
42
|
Requires-Dist: plotly; sys_platform != "emscripten"
|
|
43
|
+
Requires-Dist: pyarrow; sys_platform != "emscripten"
|
|
44
44
|
Requires-Dist: jupyter; sys_platform != "emscripten"
|
|
45
|
+
Requires-Dist: jupyterlab-myst; sys_platform != "emscripten"
|
|
45
46
|
Provides-Extra: shiny
|
|
46
47
|
Requires-Dist: shiny; extra == "shiny"
|
|
47
48
|
Requires-Dist: shinywidgets; extra == "shiny"
|
|
@@ -2390,7 +2390,7 @@ class Model_help_Mixin():
|
|
|
2390
2390
|
f' {blanks} <a href="{githubname}" target="_blank">{name}</a>'))
|
|
2391
2391
|
else:
|
|
2392
2392
|
display(HTML(
|
|
2393
|
-
f' {blanks} <a href="{notebook}" target="_blank">{name}</a>'))
|
|
2393
|
+
f' {blanks} <a href="{notebook.as_posix()}" target="_blank">{name}</a>'))
|
|
2394
2394
|
|
|
2395
2395
|
|
|
2396
2396
|
|
|
@@ -5246,6 +5246,11 @@ class Graph_Draw_Mixin():
|
|
|
5246
5246
|
|
|
5247
5247
|
class Display_Mixin():
|
|
5248
5248
|
|
|
5249
|
+
#: True: the result viewers (mpak['...'] and .rplot()) are shown as plain html tabs and
|
|
5250
|
+
#: collapsible sections instead of ipywidgets. They then also display where ipywidgets
|
|
5251
|
+
#: containers don't, like RISE slides. Set it for all models with model.plain_html = True
|
|
5252
|
+
plain_html = False
|
|
5253
|
+
|
|
5249
5254
|
def vis(self, *args, **kwargs):
|
|
5250
5255
|
''' Visualize the data of this model instance
|
|
5251
5256
|
if the user has another vis class she can place it in _vis, then that will be used'''
|
|
@@ -6454,7 +6459,7 @@ class Display_Mixin():
|
|
|
6454
6459
|
title = Display_Mixin._notebook_title(notebook)
|
|
6455
6460
|
rows.append(
|
|
6456
6461
|
f'<tr><td style="text-align:left;padding:2px 24px 2px {indent+2}em;white-space:nowrap">'
|
|
6457
|
-
f'<a href="{notebook}" target="_blank">{name}</a></td>'
|
|
6462
|
+
f'<a href="{notebook.as_posix()}" target="_blank">{name}</a></td>'
|
|
6458
6463
|
f'<td style="text-align:left;padding:2px 12px">{title}</td></tr>')
|
|
6459
6464
|
|
|
6460
6465
|
# try:
|
|
@@ -6514,7 +6519,7 @@ class Display_Mixin():
|
|
|
6514
6519
|
title = Display_Mixin._notebook_title(fname) if ext == 'ipynb' else ''
|
|
6515
6520
|
rows.append(
|
|
6516
6521
|
f'<tr><td style="text-align:left;padding:2px 24px 2px 12px;white-space:nowrap">'
|
|
6517
|
-
f'<a href="{fname}" target="_blank">{name}</a></td>'
|
|
6522
|
+
f'<a href="{fname.as_posix()}" target="_blank">{name}</a></td>'
|
|
6518
6523
|
f'<td style="text-align:left;padding:2px 12px">{title}</td></tr>')
|
|
6519
6524
|
if rows:
|
|
6520
6525
|
display(HTML(
|
|
@@ -6843,11 +6848,20 @@ class Json_Mixin():
|
|
|
6843
6848
|
base.index = base_dates
|
|
6844
6849
|
return base, current_dates
|
|
6845
6850
|
|
|
6851
|
+
def any_case(p):
|
|
6852
|
+
'''p, or else a file in the same folder whose name only differs in case
|
|
6853
|
+
(Windows ignores case, Linux and the browser (JupyterLite) do not)'''
|
|
6854
|
+
if p.exists() or not p.parent.is_dir():
|
|
6855
|
+
return p
|
|
6856
|
+
return next((f for f in p.parent.iterdir() if f.name.lower() == p.name.lower()), p)
|
|
6857
|
+
|
|
6846
6858
|
pinfile = Path(nname:=infile.replace('\\','/'))
|
|
6847
6859
|
if not pinfile.suffix:
|
|
6848
|
-
pinfile = pinfile.with_suffix(cls.data_suffix)
|
|
6849
|
-
if not pinfile.exists() and (nodata := pinfile.with_suffix(cls.nodata_suffix)).exists():
|
|
6860
|
+
pinfile = any_case(pinfile.with_suffix(cls.data_suffix))
|
|
6861
|
+
if not pinfile.exists() and (nodata := any_case(pinfile.with_suffix(cls.nodata_suffix))).exists():
|
|
6850
6862
|
pinfile = nodata
|
|
6863
|
+
else:
|
|
6864
|
+
pinfile = any_case(pinfile)
|
|
6851
6865
|
|
|
6852
6866
|
def read_file(pinfile):
|
|
6853
6867
|
try:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelflowib
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.86
|
|
4
4
|
Summary: A tool to solve and manage dynamic economic and financial models
|
|
5
5
|
Author-email: Ib Hansen <Ib.Hansen.Iv@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -21,7 +21,6 @@ Requires-Dist: networkx
|
|
|
21
21
|
Requires-Dist: tqdm
|
|
22
22
|
Requires-Dist: scipy
|
|
23
23
|
Requires-Dist: XlsxWriter
|
|
24
|
-
Requires-Dist: pyarrow
|
|
25
24
|
Requires-Dist: tabulate
|
|
26
25
|
Requires-Dist: openpyxl
|
|
27
26
|
Requires-Dist: xarray
|
|
@@ -41,7 +40,9 @@ Requires-Dist: dash; sys_platform != "emscripten"
|
|
|
41
40
|
Requires-Dist: dash-bootstrap-components; sys_platform != "emscripten"
|
|
42
41
|
Requires-Dist: dash-interactive-graphviz; sys_platform != "emscripten"
|
|
43
42
|
Requires-Dist: plotly; sys_platform != "emscripten"
|
|
43
|
+
Requires-Dist: pyarrow; sys_platform != "emscripten"
|
|
44
44
|
Requires-Dist: jupyter; sys_platform != "emscripten"
|
|
45
|
+
Requires-Dist: jupyterlab-myst; sys_platform != "emscripten"
|
|
45
46
|
Provides-Extra: shiny
|
|
46
47
|
Requires-Dist: shiny; extra == "shiny"
|
|
47
48
|
Requires-Dist: shinywidgets; extra == "shiny"
|
|
@@ -1525,15 +1525,22 @@ class DisplayKeepFigDef(DisplayDef):
|
|
|
1525
1525
|
return [self.out_html ]
|
|
1526
1526
|
|
|
1527
1527
|
|
|
1528
|
-
@property
|
|
1529
|
-
def
|
|
1528
|
+
@property
|
|
1529
|
+
def fig_tabwidget(self):
|
|
1530
1530
|
figlist = {t: htmlwidget_fig(f) for t,f in self.figs.items() }
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1531
|
+
return tabwidget(figlist,tab=False,selected_index=0)
|
|
1532
|
+
|
|
1533
|
+
@property
|
|
1534
|
+
def out_html(self):
|
|
1535
|
+
return self.fig_tabwidget.datawidget
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
def _ipython_display_(self):
|
|
1539
|
+
# model.plain_html: the charts in plain html sections, which also display where ipywidgets containers don't (RISE)
|
|
1540
|
+
if getattr(self.mmodel, 'plain_html', False):
|
|
1541
|
+
display(HTML(self.fig_tabwidget.html))
|
|
1542
|
+
else:
|
|
1543
|
+
display(self.out_html)
|
|
1537
1544
|
|
|
1538
1545
|
# display(self.out_html)
|
|
1539
1546
|
|
|
@@ -15,8 +15,9 @@ import ipywidgets as widgets
|
|
|
15
15
|
# except:
|
|
16
16
|
# ...
|
|
17
17
|
# print('No ipysheet ')
|
|
18
|
-
from IPython.display import display, clear_output,Latex, Markdown
|
|
18
|
+
from IPython.display import display, clear_output,Latex, Markdown, HTML
|
|
19
19
|
from dataclasses import dataclass,field
|
|
20
|
+
import uuid
|
|
20
21
|
import matplotlib.pylab as plt
|
|
21
22
|
|
|
22
23
|
try:
|
|
@@ -41,8 +42,34 @@ class basewidget:
|
|
|
41
42
|
''' will update container widgets'''
|
|
42
43
|
for w in self.datachildren:
|
|
43
44
|
w.update_df(df,current_per)
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def html_tabs(parts, tab=True, selected=0):
|
|
48
|
+
'''Plain html (no ipywidgets) version of a Tab or an Accordion, used when model.plain_html is True.
|
|
49
|
+
|
|
50
|
+
parts: {title: html string}. tab=True gives tabs made of hidden radio buttons, labels and css,
|
|
51
|
+
tab=False collapsible <details> sections. selected: the index shown first (None: all closed). '''
|
|
52
|
+
uid = 'mft' + uuid.uuid4().hex[:8] # unique, so tabs in other outputs are not affected
|
|
53
|
+
if not tab:
|
|
54
|
+
# the same name makes the sections exclusive: opening one closes the others
|
|
55
|
+
return ''.join(f'<details name="{uid}"{" open" if i == selected else ""}>'
|
|
56
|
+
f'<summary style="cursor:pointer;font-weight:bold">{title}</summary>{body}</details>'
|
|
57
|
+
for i, (title, body) in enumerate(parts.items()))
|
|
58
|
+
css = [f'#{uid} > input {{display:none}}',
|
|
59
|
+
f'#{uid} > label {{display:inline-block;padding:4px 12px;margin-right:2px;cursor:pointer;'
|
|
60
|
+
f'border:1px solid #bbb;border-bottom:none;border-radius:4px 4px 0 0;background:#eee}}',
|
|
61
|
+
f'#{uid} > div {{display:none;border-top:1px solid #bbb;padding-top:6px}}']
|
|
62
|
+
head, panels = '', ''
|
|
63
|
+
for i, (title, body) in enumerate(parts.items()):
|
|
64
|
+
rid = f'{uid}-{i}'
|
|
65
|
+
head += (f'<input type="radio" name="{uid}" id="{rid}"{" checked" if i == (selected or 0) else ""}>'
|
|
66
|
+
f'<label for="{rid}">{title}</label>')
|
|
67
|
+
panels += f'<div>{body}</div>'
|
|
68
|
+
css.append(f'#{rid}:checked + label {{background:#fff;font-weight:bold}}')
|
|
69
|
+
css.append(f'#{rid}:checked ~ div:nth-of-type({i + 1}) {{display:block}}')
|
|
70
|
+
return f'<style>{" ".join(css)}</style><div id="{uid}">{head}{panels}</div>'
|
|
71
|
+
|
|
72
|
+
|
|
46
73
|
@dataclass
|
|
47
74
|
class tabwidget:
|
|
48
75
|
'''A widget to create tab or acordium contaners'''
|
|
@@ -62,8 +89,13 @@ class tabwidget:
|
|
|
62
89
|
|
|
63
90
|
for i,key in enumerate(self.tabdefdict.keys()):
|
|
64
91
|
self.datawidget.set_title(i,key)
|
|
65
|
-
|
|
66
|
-
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def html(self):
|
|
95
|
+
''' the same container as plain html, see html_tabs '''
|
|
96
|
+
return html_tabs({key: child.html for key, child in zip(self.tabdefdict.keys(), self.datachildren)},
|
|
97
|
+
tab=self.tab, selected=self.selected_index)
|
|
98
|
+
|
|
67
99
|
def update_df(self,df,current_per):
|
|
68
100
|
''' will update container widgets'''
|
|
69
101
|
for w in self.datachildren:
|
|
@@ -514,6 +546,7 @@ table, th, td {
|
|
|
514
546
|
|
|
515
547
|
self.whtml = widgets.HTML(image)
|
|
516
548
|
self.datawidget=widgets.VBox([self.wexp,self.whtml]) if len(self.expname) else self.whtml
|
|
549
|
+
self.html = (f'<div>{self.expname}</div>' if len(self.expname) else '') + image
|
|
517
550
|
|
|
518
551
|
|
|
519
552
|
|
|
@@ -540,6 +573,7 @@ class htmlwidget_fig:
|
|
|
540
573
|
image = fig_to_image(self.figs,format=self.format)
|
|
541
574
|
self.whtml = widgets.HTML(image)
|
|
542
575
|
self.datawidget=widgets.VBox([self.wexp,self.whtml]) if len(self.expname) else self.whtml
|
|
576
|
+
self.html = (f'<div>{self.expname}</div>' if len(self.expname) else '') + image
|
|
543
577
|
|
|
544
578
|
@dataclass
|
|
545
579
|
class htmlwidget_style:
|
|
@@ -561,7 +595,8 @@ table, th, td {
|
|
|
561
595
|
}
|
|
562
596
|
</style>
|
|
563
597
|
"""
|
|
564
|
-
self.
|
|
598
|
+
self.html = f'{style_html}{self.styler.to_html()}'
|
|
599
|
+
self.datawidget = widgets.HTML(self.html)
|
|
565
600
|
|
|
566
601
|
def display(self):
|
|
567
602
|
# Function to display the widget
|
|
@@ -580,9 +615,10 @@ class htmlwidget_label:
|
|
|
580
615
|
...
|
|
581
616
|
|
|
582
617
|
self.wexp = widgets.Label(value = self.expname,layout={'width':'54%'})
|
|
583
|
-
|
|
584
|
-
|
|
618
|
+
|
|
619
|
+
|
|
585
620
|
self.datawidget=self.wexp
|
|
621
|
+
self.html = f'<div>{self.expname}</div>'
|
|
586
622
|
|
|
587
623
|
@dataclass
|
|
588
624
|
class htmlwidget_text:
|
|
@@ -593,8 +629,9 @@ class htmlwidget_text:
|
|
|
593
629
|
|
|
594
630
|
def __post_init__(self):
|
|
595
631
|
# Initialize the label widget with the provided text
|
|
632
|
+
self.html = f"<p style='font-family:sans-serif;'>{self.text}</p>"
|
|
596
633
|
self.datawidget = widgets.HTML(
|
|
597
|
-
value=
|
|
634
|
+
value=self.html,
|
|
598
635
|
layout={'width': '90%'}
|
|
599
636
|
)
|
|
600
637
|
|
|
@@ -684,10 +721,10 @@ class visshow:
|
|
|
684
721
|
# print('exo inf created')
|
|
685
722
|
|
|
686
723
|
this = tabwidget(tabnew,selected_index=0)
|
|
687
|
-
# print('this created ')
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
self.datawidget = this.datawidget
|
|
724
|
+
# print('this created ')
|
|
725
|
+
|
|
726
|
+
# model.plain_html: plain html tabs, which also display where ipywidgets containers don't (RISE)
|
|
727
|
+
self.datawidget = HTML(this.html) if getattr(self.mmodel, 'plain_html', False) else this.datawidget
|
|
691
728
|
if self.show_on:
|
|
692
729
|
...
|
|
693
730
|
display(self.datawidget)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "modelflowib" # PyPI distribution name
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.86" # OVERWRITTEN at build time from MF_VERSION
|
|
8
8
|
# (set_pyproject_version.py / make_pip.py -v)
|
|
9
9
|
description = "A tool to solve and manage dynamic economic and financial models"
|
|
10
10
|
readme = "README.md"
|
|
@@ -36,7 +36,6 @@ dependencies = [
|
|
|
36
36
|
"tqdm",
|
|
37
37
|
"scipy",
|
|
38
38
|
"XlsxWriter",
|
|
39
|
-
"pyarrow",
|
|
40
39
|
"tabulate",
|
|
41
40
|
"openpyxl",
|
|
42
41
|
"xarray",
|
|
@@ -57,7 +56,9 @@ dependencies = [
|
|
|
57
56
|
"dash-bootstrap-components; sys_platform != 'emscripten'",
|
|
58
57
|
"dash-interactive-graphviz; sys_platform != 'emscripten'",
|
|
59
58
|
"plotly; sys_platform != 'emscripten'", # modeldashsidebar
|
|
59
|
+
"pyarrow; sys_platform != 'emscripten'", # only .pcimz (large=True) dump/load; not in every Pyodide (0.27 lacks it)
|
|
60
60
|
"jupyter; sys_platform != 'emscripten'", # JupyterLite is the notebook there
|
|
61
|
+
"jupyterlab-myst; sys_platform != 'emscripten'", # MyST markdown (directives, mermaid) in notebook cells; a front-end extension, in JupyterLite it comes from the site build
|
|
61
62
|
]
|
|
62
63
|
|
|
63
64
|
[project.optional-dependencies]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|