qis 3.2.10__tar.gz → 3.2.11__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.
Files changed (147) hide show
  1. {qis-3.2.10 → qis-3.2.11}/PKG-INFO +1 -1
  2. {qis-3.2.10 → qis-3.2.11}/pyproject.toml +1 -1
  3. {qis-3.2.10 → qis-3.2.11}/qis/examples/factsheets/multi_assets.py +1 -1
  4. {qis-3.2.10 → qis-3.2.11}/qis/plots/lineplot.py +31 -4
  5. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/multi_assets_factsheet.py +1 -1
  6. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/multi_strategy_factseet_pybloqs.py +1 -1
  7. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/multi_strategy_factsheet.py +1 -1
  8. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/strategy_benchmark_factsheet.py +1 -1
  9. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/strategy_benchmark_factsheet_pybloqs.py +1 -1
  10. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/strategy_factsheet.py +1 -1
  11. {qis-3.2.10 → qis-3.2.11}/qis/utils/dates.py +5 -2
  12. {qis-3.2.10 → qis-3.2.11}/LICENSE.txt +0 -0
  13. {qis-3.2.10 → qis-3.2.11}/README.md +0 -0
  14. {qis-3.2.10 → qis-3.2.11}/qis/__init__.py +0 -0
  15. {qis-3.2.10 → qis-3.2.11}/qis/examples/best_returns.py +0 -0
  16. {qis-3.2.10 → qis-3.2.11}/qis/examples/bootstrap_analysis.py +0 -0
  17. {qis-3.2.10 → qis-3.2.11}/qis/examples/boxplot_conditional_returns.py +0 -0
  18. {qis-3.2.10 → qis-3.2.11}/qis/examples/btc_asset_corr.py +0 -0
  19. {qis-3.2.10 → qis-3.2.11}/qis/examples/constant_notional.py +0 -0
  20. {qis-3.2.10 → qis-3.2.11}/qis/examples/constant_weight_portfolios.py +0 -0
  21. {qis-3.2.10 → qis-3.2.11}/qis/examples/core/perf_bbg_prices.py +0 -0
  22. {qis-3.2.10 → qis-3.2.11}/qis/examples/core/price_plots.py +0 -0
  23. {qis-3.2.10 → qis-3.2.11}/qis/examples/core/us_election.py +0 -0
  24. {qis-3.2.10 → qis-3.2.11}/qis/examples/credit_spreads.py +0 -0
  25. {qis-3.2.10 → qis-3.2.11}/qis/examples/europe_futures.py +0 -0
  26. {qis-3.2.10 → qis-3.2.11}/qis/examples/factsheets/multi_strategy.py +0 -0
  27. {qis-3.2.10 → qis-3.2.11}/qis/examples/factsheets/pyblogs_reports.py +0 -0
  28. {qis-3.2.10 → qis-3.2.11}/qis/examples/factsheets/strategy.py +0 -0
  29. {qis-3.2.10 → qis-3.2.11}/qis/examples/factsheets/strategy_benchmark.py +0 -0
  30. {qis-3.2.10 → qis-3.2.11}/qis/examples/generate_option_rolls.py +0 -0
  31. {qis-3.2.10 → qis-3.2.11}/qis/examples/interpolation_infrequent_returns.py +0 -0
  32. {qis-3.2.10 → qis-3.2.11}/qis/examples/leveraged_strategies.py +0 -0
  33. {qis-3.2.10 → qis-3.2.11}/qis/examples/long_short.py +0 -0
  34. {qis-3.2.10 → qis-3.2.11}/qis/examples/momentum_indices.py +0 -0
  35. {qis-3.2.10 → qis-3.2.11}/qis/examples/ohlc_vol_analysis.py +0 -0
  36. {qis-3.2.10 → qis-3.2.11}/qis/examples/overnight_returns.py +0 -0
  37. {qis-3.2.10 → qis-3.2.11}/qis/examples/perf_external_assets.py +0 -0
  38. {qis-3.2.10 → qis-3.2.11}/qis/examples/readme_performances.py +0 -0
  39. {qis-3.2.10 → qis-3.2.11}/qis/examples/risk_return_frontier.py +0 -0
  40. {qis-3.2.10 → qis-3.2.11}/qis/examples/rolling_performance.py +0 -0
  41. {qis-3.2.10 → qis-3.2.11}/qis/examples/seasonality.py +0 -0
  42. {qis-3.2.10 → qis-3.2.11}/qis/examples/sharpe_vs_sortino.py +0 -0
  43. {qis-3.2.10 → qis-3.2.11}/qis/examples/simulate_quant_strats.py +0 -0
  44. {qis-3.2.10 → qis-3.2.11}/qis/examples/test_ewm.py +0 -0
  45. {qis-3.2.10 → qis-3.2.11}/qis/examples/test_scatter.py +0 -0
  46. {qis-3.2.10 → qis-3.2.11}/qis/examples/try_pybloqs.py +0 -0
  47. {qis-3.2.10 → qis-3.2.11}/qis/examples/universe_corrs.py +0 -0
  48. {qis-3.2.10 → qis-3.2.11}/qis/examples/vix_beta_to_equities_bonds.py +0 -0
  49. {qis-3.2.10 → qis-3.2.11}/qis/examples/vix_conditional_returns.py +0 -0
  50. {qis-3.2.10 → qis-3.2.11}/qis/examples/vix_spy_by_year.py +0 -0
  51. {qis-3.2.10 → qis-3.2.11}/qis/examples/vix_tenor_analysis.py +0 -0
  52. {qis-3.2.10 → qis-3.2.11}/qis/examples/vol_without_weekends.py +0 -0
  53. {qis-3.2.10 → qis-3.2.11}/qis/file_utils.py +0 -0
  54. {qis-3.2.10 → qis-3.2.11}/qis/local_path.py +0 -0
  55. {qis-3.2.10 → qis-3.2.11}/qis/models/README.md +0 -0
  56. {qis-3.2.10 → qis-3.2.11}/qis/models/__init__.py +0 -0
  57. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/__init__.py +0 -0
  58. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/auto_corr.py +0 -0
  59. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/corr_cov_matrix.py +0 -0
  60. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/ewm.py +0 -0
  61. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/ewm_convolution.py +0 -0
  62. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/ewm_factors.py +0 -0
  63. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/ewm_winsor_outliers.py +0 -0
  64. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/pca.py +0 -0
  65. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/plot_correlations.py +0 -0
  66. {qis-3.2.10 → qis-3.2.11}/qis/models/linear/ra_returns.py +0 -0
  67. {qis-3.2.10 → qis-3.2.11}/qis/models/stats/__init__.py +0 -0
  68. {qis-3.2.10 → qis-3.2.11}/qis/models/stats/bootstrap.py +0 -0
  69. {qis-3.2.10 → qis-3.2.11}/qis/models/stats/ohlc_vol.py +0 -0
  70. {qis-3.2.10 → qis-3.2.11}/qis/models/stats/rolling_stats.py +0 -0
  71. {qis-3.2.10 → qis-3.2.11}/qis/models/stats/test_bootstrap.py +0 -0
  72. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/README.md +0 -0
  73. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/__init__.py +0 -0
  74. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/cond_regression.py +0 -0
  75. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/config.py +0 -0
  76. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/desc_table.py +0 -0
  77. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/fx_ops.py +0 -0
  78. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/perf_stats.py +0 -0
  79. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/regime_classifier.py +0 -0
  80. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/returns.py +0 -0
  81. {qis-3.2.10 → qis-3.2.11}/qis/perfstats/timeseries_bfill.py +0 -0
  82. {qis-3.2.10 → qis-3.2.11}/qis/plots/README.md +0 -0
  83. {qis-3.2.10 → qis-3.2.11}/qis/plots/__init__.py +0 -0
  84. {qis-3.2.10 → qis-3.2.11}/qis/plots/bars.py +0 -0
  85. {qis-3.2.10 → qis-3.2.11}/qis/plots/boxplot.py +0 -0
  86. {qis-3.2.10 → qis-3.2.11}/qis/plots/contour.py +0 -0
  87. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/__init__.py +0 -0
  88. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/data_timeseries.py +0 -0
  89. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/desc_table.py +0 -0
  90. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/drawdowns.py +0 -0
  91. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/perf_table.py +0 -0
  92. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/prices.py +0 -0
  93. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/regime_class_table.py +0 -0
  94. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/regime_data.py +0 -0
  95. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/regime_pdf.py +0 -0
  96. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/regime_scatter.py +0 -0
  97. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/returns_heatmap.py +0 -0
  98. {qis-3.2.10 → qis-3.2.11}/qis/plots/derived/returns_scatter.py +0 -0
  99. {qis-3.2.10 → qis-3.2.11}/qis/plots/errorbar.py +0 -0
  100. {qis-3.2.10 → qis-3.2.11}/qis/plots/heatmap.py +0 -0
  101. {qis-3.2.10 → qis-3.2.11}/qis/plots/histogram.py +0 -0
  102. {qis-3.2.10 → qis-3.2.11}/qis/plots/histplot2d.py +0 -0
  103. {qis-3.2.10 → qis-3.2.11}/qis/plots/pie.py +0 -0
  104. {qis-3.2.10 → qis-3.2.11}/qis/plots/qqplot.py +0 -0
  105. {qis-3.2.10 → qis-3.2.11}/qis/plots/reports/__init__.py +0 -0
  106. {qis-3.2.10 → qis-3.2.11}/qis/plots/reports/econ_data_single.py +0 -0
  107. {qis-3.2.10 → qis-3.2.11}/qis/plots/reports/gantt_data_history.py +0 -0
  108. {qis-3.2.10 → qis-3.2.11}/qis/plots/reports/price_history.py +0 -0
  109. {qis-3.2.10 → qis-3.2.11}/qis/plots/reports/utils.py +0 -0
  110. {qis-3.2.10 → qis-3.2.11}/qis/plots/scatter.py +0 -0
  111. {qis-3.2.10 → qis-3.2.11}/qis/plots/stackplot.py +0 -0
  112. {qis-3.2.10 → qis-3.2.11}/qis/plots/table.py +0 -0
  113. {qis-3.2.10 → qis-3.2.11}/qis/plots/time_series.py +0 -0
  114. {qis-3.2.10 → qis-3.2.11}/qis/plots/utils.py +0 -0
  115. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/README.md +0 -0
  116. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/__init__.py +0 -0
  117. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/backtester.py +0 -0
  118. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/ewm_portfolio_risk.py +0 -0
  119. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/multi_portfolio_data.py +0 -0
  120. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/portfolio_data.py +0 -0
  121. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/__init__.py +0 -0
  122. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/brinson_attribution.py +0 -0
  123. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/config.py +0 -0
  124. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/reports/strategy_signal_factsheet.py +0 -0
  125. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/signal_data.py +0 -0
  126. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/strats/__init__.py +0 -0
  127. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/strats/quant_strats_delta1.py +0 -0
  128. {qis-3.2.10 → qis-3.2.11}/qis/portfolio/strats/seasonal_strats.py +0 -0
  129. {qis-3.2.10 → qis-3.2.11}/qis/settings.yaml +0 -0
  130. {qis-3.2.10 → qis-3.2.11}/qis/sql_engine.py +0 -0
  131. {qis-3.2.10 → qis-3.2.11}/qis/test_data.py +0 -0
  132. {qis-3.2.10 → qis-3.2.11}/qis/utils/README.md +0 -0
  133. {qis-3.2.10 → qis-3.2.11}/qis/utils/__init__.py +0 -0
  134. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_agg.py +0 -0
  135. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_cut.py +0 -0
  136. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_freq.py +0 -0
  137. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_groups.py +0 -0
  138. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_melt.py +0 -0
  139. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_ops.py +0 -0
  140. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_str.py +0 -0
  141. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_to_scores.py +0 -0
  142. {qis-3.2.10 → qis-3.2.11}/qis/utils/df_to_weights.py +0 -0
  143. {qis-3.2.10 → qis-3.2.11}/qis/utils/generic.py +0 -0
  144. {qis-3.2.10 → qis-3.2.11}/qis/utils/np_ops.py +0 -0
  145. {qis-3.2.10 → qis-3.2.11}/qis/utils/ols.py +0 -0
  146. {qis-3.2.10 → qis-3.2.11}/qis/utils/sampling.py +0 -0
  147. {qis-3.2.10 → qis-3.2.11}/qis/utils/struct_ops.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: qis
3
- Version: 3.2.10
3
+ Version: 3.2.11
4
4
  Summary: Implementation of visualisation and reporting analytics for Quantitative Investment Strategies
5
5
  License: LICENSE.txt
6
6
  Keywords: quantitative,investing,portfolio optimization,systematic strategies,volatility
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "qis"
3
- version = "3.2.10"
3
+ version = "3.2.11"
4
4
  description = "Implementation of visualisation and reporting analytics for Quantitative Investment Strategies"
5
5
  license = "LICENSE.txt"
6
6
  authors = ["Artur Sepp <artursepp@gmail.com>"]
@@ -23,7 +23,7 @@ class UnitTests(Enum):
23
23
 
24
24
  def run_unit_test(unit_test: UnitTests):
25
25
 
26
- end_date = '10Jan2025' # performance repoting
26
+ end_date = '17Apr2025' # performance repoting
27
27
 
28
28
  prices = None # if Noe, use yahoo finance data
29
29
 
@@ -15,6 +15,9 @@ import qis.plots.utils as put
15
15
 
16
16
 
17
17
  def plot_line(df: Union[pd.Series, pd.DataFrame],
18
+ x: str = None,
19
+ y: str = None,
20
+ hue: str = None,
18
21
  linestyles: List[str] = None,
19
22
  linestyle: Any = '-',
20
23
  linewidth: float = 1.0,
@@ -37,7 +40,13 @@ def plot_line(df: Union[pd.Series, pd.DataFrame],
37
40
  ax: plt.Subplot = None,
38
41
  **kwargs
39
42
  ) -> Optional[plt.Figure]:
40
-
43
+ """
44
+ line plot wrapper for sns, lineplot
45
+ plot df using index
46
+ x: str = None: x column
47
+ y: str = None: y column
48
+ hue: str = None: hue
49
+ """
41
50
  if isinstance(df, pd.DataFrame):
42
51
  pass
43
52
  elif isinstance(df, pd.Series):
@@ -45,22 +54,40 @@ def plot_line(df: Union[pd.Series, pd.DataFrame],
45
54
  else:
46
55
  raise TypeError(f"unsuported data type {type(df)}")
47
56
 
57
+ if x is not None:
58
+ if y is None:
59
+ raise ValueError(f"y column must be given with x column")
60
+ else:
61
+ if hue is not None:
62
+ df = df[[x, y, hue]]
63
+ else:
64
+ df = df[[x, y]]
65
+
48
66
  if ax is None:
49
67
  fig, ax = plt.subplots()
50
68
  else:
51
69
  fig = None
52
70
 
53
71
  if colors is None:
54
- colors = put.get_n_colors(n=len(df.columns), **kwargs)
72
+ if hue is None:
73
+ colors = put.get_n_colors(n=len(df.columns), **kwargs)
74
+ else:
75
+ colors = put.get_n_colors(n=len(df[hue].unique()), **kwargs)
55
76
 
56
- sns.lineplot(data=df, palette=colors, dashes=False, markers=markers, linestyle=linestyle, linewidth=linewidth, ax=ax)
77
+ sns.lineplot(data=df, x=x, y=y, hue=hue,
78
+ palette=colors, dashes=False, markers=markers, linestyle=linestyle, linewidth=linewidth,
79
+ style=hue,
80
+ ax=ax)
57
81
 
58
82
  if title is not None:
59
83
  put.set_title(ax=ax, title=title, fontsize=fontsize, **kwargs)
60
84
 
61
85
  if legend_loc is not None:
62
86
  if legend_labels is None:
63
- legend_labels = put.get_legend_lines(data=df, legend_stats=legend_stats, var_format=yvar_format)
87
+ if hue is None:
88
+ legend_labels = put.get_legend_lines(data=df, legend_stats=legend_stats, var_format=yvar_format)
89
+ else:
90
+ h, legend_labels = ax.get_legend_handles_labels()
64
91
  put.set_legend(ax=ax,
65
92
  labels=legend_labels,
66
93
  colors=colors,
@@ -420,7 +420,7 @@ def generate_multi_asset_factsheet(prices: pd.DataFrame,
420
420
  heatmap_freq: str = 'YE',
421
421
  time_period: TimePeriod = None, # time period for reporting
422
422
  figsize: Tuple[float, float] = (8.3, 11.7), # A4 for portrait
423
- fontsize: int = 4,
423
+ fontsize: int = 5,
424
424
  factsheet_name: str = None,
425
425
  performance_bars: Tuple[PerfStat, PerfStat] = (PerfStat.SHARPE_RF0, PerfStat.MAX_DD),
426
426
  drop_1y_ra_perf_table: bool = True,
@@ -232,7 +232,7 @@ def generate_multi_portfolio_factsheet(multi_portfolio_data: MultiPortfolioData,
232
232
  heatmap_freq: str = 'YE',
233
233
  figsize: Tuple[float, float] = (8.3, 11.7), # A4 for portrait
234
234
  is_grouped: bool = False,
235
- fontsize: int = 4,
235
+ fontsize: int = 5,
236
236
  **kwargs
237
237
  ) -> plt.Figure:
238
238
  """
@@ -27,7 +27,7 @@ def generate_multi_portfolio_factsheet(multi_portfolio_data: MultiPortfolioData,
27
27
  group_data: pd.Series = None,
28
28
  add_group_exposures_and_pnl: bool = False,
29
29
  add_strategy_factsheets: bool = False,
30
- fontsize: int = 4,
30
+ fontsize: int = 5,
31
31
  **kwargs
32
32
  ) -> List[plt.Figure]:
33
33
  """
@@ -35,7 +35,7 @@ def generate_strategy_benchmark_factsheet_plt(multi_portfolio_data: MultiPortfol
35
35
  add_exposures_comp: bool = False,
36
36
  is_grouped: Optional[bool] = None,
37
37
  figsize: Tuple[float, float] = (8.3, 11.7), # A4 for portrait
38
- fontsize: int = 4,
38
+ fontsize: int = 5,
39
39
  **kwargs
40
40
  ) -> List[plt.Figure]:
41
41
  """
@@ -33,7 +33,7 @@ def generate_strategy_benchmark_factsheet_with_pyblogs(multi_portfolio_data: Mul
33
33
  heatmap_freq: str = 'YE',
34
34
  weight_freq: str = 'ME',
35
35
  is_input_weights: bool = True,
36
- fontsize: int = 4,
36
+ fontsize: int = 5,
37
37
  **kwargs
38
38
  ) -> p.VStack:
39
39
  """
@@ -38,7 +38,7 @@ def generate_strategy_factsheet(portfolio_data: PortfolioData,
38
38
  sharpe_rolling_window: int = 260,
39
39
  add_benchmarks_to_navs: bool = False,
40
40
  figsize: Tuple[float, float] = (8.5, 11.7), # A4 for portrait
41
- fontsize: int = 4,
41
+ fontsize: int = 5,
42
42
  weight_change_sample_size: int = 20,
43
43
  add_current_position_var_risk_sheet: bool = False,
44
44
  add_weights_turnover_sheet: bool = False,
@@ -28,6 +28,9 @@ CALENDAR_DAYS_IN_MONTH = 30
28
28
  CALENDAR_DAYS_PER_YEAR_SHARPE = 365.25 # for total return computations for Sharpe
29
29
 
30
30
 
31
+ DEFAULT_TRADING_YEAR_DAYS = 252 # How mny trading days we assume per year, see get_period_days()
32
+
33
+
31
34
  def get_current_time_with_tz(tz: Optional[str] = 'UTC',
32
35
  days_offset: int = None,
33
36
  normalize: bool = True,
@@ -67,7 +70,7 @@ def get_period_days(freq: str = 'B',
67
70
  an_f will return the number of period in year
68
71
  consistent with using 252 for vol annualization
69
72
  """
70
- an_days = 365 if is_calendar else 252
73
+ an_days = 365 if is_calendar else DEFAULT_TRADING_YEAR_DAYS
71
74
  if freq in ['1M']:
72
75
  days = 1.0 / 24.0 / 60.0
73
76
  an_f = an_days * 24.0 * 60.0
@@ -117,7 +120,7 @@ def get_period_days(freq: str = 'B',
117
120
  days = an_days
118
121
  an_f = 1.0
119
122
  else:
120
- raise TypeError(f'freq={freq} is not impelemnted')
123
+ raise TypeError(f'freq={freq} is not implemented')
121
124
 
122
125
  return days, an_f
123
126
 
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
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