praisonAI 2.2.90__tar.gz → 2.2.93__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.
- {praisonai-2.2.90 → praisonai-2.2.93}/PKG-INFO +2 -2
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/cli.py +56 -15
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/deploy.py +1 -1
- {praisonai-2.2.90 → praisonai-2.2.93}/pyproject.toml +4 -4
- {praisonai-2.2.90 → praisonai-2.2.93}/README.md +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/README.md +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/__init__.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/__main__.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/agents_generator.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/api/call.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/auto.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/chainlit_ui.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/inbuilt_tools/__init__.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/inbuilt_tools/autogen_tools.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/inc/__init__.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/inc/config.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/inc/models.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/android-chrome-192x192.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/android-chrome-512x512.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/apple-touch-icon.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/fantasy.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/favicon-16x16.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/favicon-32x32.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/favicon.ico +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/game.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/logo_dark.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/logo_light.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/movie.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/praison-ai-agents-architecture-dark.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/praison-ai-agents-architecture.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/thriller.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/scheduler.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup/__init__.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup/build.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup/config.yaml +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup/post_install.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup/setup_conda_env.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup/setup_conda_env.sh +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/setup.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/test.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/train.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/train_vision.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/README.md +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/agents.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/callbacks.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/chat.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/code.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/colab.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/colab_chainlit.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/components/aicoder.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/chainlit.md +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/bn.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/en-US.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/gu.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/he-IL.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/hi.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/kn.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/ml.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/mr.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/ta.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/te.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/config/translations/zh-CN.json +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/context.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/database_config.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/db.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/fantasy.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/game.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/logo_dark.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/logo_light.png +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/movie.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/praison.css +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/public/thriller.svg +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/realtime.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/realtimeclient/__init__.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/realtimeclient/tools.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/sql_alchemy.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/ui/tools.md +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/upload_vision.py +0 -0
- {praisonai-2.2.90 → praisonai-2.2.93}/praisonai/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PraisonAI
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.93
|
|
4
4
|
Summary: PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration.
|
|
5
5
|
Author: Mervin Praison
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -70,7 +70,7 @@ Requires-Dist: plotly (>=5.24.0) ; extra == "realtime"
|
|
|
70
70
|
Requires-Dist: praisonai-tools (>=0.0.22) ; extra == "autogen"
|
|
71
71
|
Requires-Dist: praisonai-tools (>=0.0.22) ; extra == "autogen-v4"
|
|
72
72
|
Requires-Dist: praisonai-tools (>=0.0.22) ; extra == "crewai"
|
|
73
|
-
Requires-Dist: praisonaiagents (>=0.0.
|
|
73
|
+
Requires-Dist: praisonaiagents (>=0.0.165)
|
|
74
74
|
Requires-Dist: pyautogen (==0.2.29) ; extra == "autogen"
|
|
75
75
|
Requires-Dist: pydantic (<=2.10.1) ; extra == "chat"
|
|
76
76
|
Requires-Dist: pydantic (<=2.10.1) ; extra == "code"
|
|
@@ -28,6 +28,13 @@ AUTOGEN_AVAILABLE = False
|
|
|
28
28
|
PRAISONAI_AVAILABLE = False
|
|
29
29
|
TRAIN_AVAILABLE = False
|
|
30
30
|
try:
|
|
31
|
+
import importlib.util
|
|
32
|
+
CHAINLIT_AVAILABLE = importlib.util.find_spec("chainlit") is not None
|
|
33
|
+
except ImportError:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
def _get_chainlit_run():
|
|
37
|
+
"""Lazy import chainlit to avoid loading .env at startup"""
|
|
31
38
|
# Create necessary directories and set CHAINLIT_APP_ROOT
|
|
32
39
|
if "CHAINLIT_APP_ROOT" not in os.environ:
|
|
33
40
|
chainlit_root = os.path.join(os.path.expanduser("~"), ".praison")
|
|
@@ -39,9 +46,7 @@ try:
|
|
|
39
46
|
os.makedirs(os.path.join(chainlit_root, ".files"), exist_ok=True)
|
|
40
47
|
|
|
41
48
|
from chainlit.cli import chainlit_run
|
|
42
|
-
|
|
43
|
-
except ImportError:
|
|
44
|
-
pass
|
|
49
|
+
return chainlit_run
|
|
45
50
|
|
|
46
51
|
try:
|
|
47
52
|
import gradio as gr
|
|
@@ -573,6 +578,7 @@ class PraisonAI:
|
|
|
573
578
|
parser.add_argument("--goal", type=str, help="Goal for context engineering")
|
|
574
579
|
parser.add_argument("--auto-analyze", action="store_true", help="Enable automatic analysis in context engineering")
|
|
575
580
|
parser.add_argument("--research", action="store_true", help="Run deep research on a topic")
|
|
581
|
+
parser.add_argument("--save", "-s", action="store_true", help="Save research output to file (output/research/)")
|
|
576
582
|
parser.add_argument("--verbose", "-v", action="store_true", help="Enable verbose output for research")
|
|
577
583
|
|
|
578
584
|
# If we're in a test environment, parse with empty args to avoid pytest interference
|
|
@@ -714,7 +720,8 @@ class PraisonAI:
|
|
|
714
720
|
|
|
715
721
|
research_model = getattr(args, 'model', None)
|
|
716
722
|
verbose = getattr(args, 'verbose', False)
|
|
717
|
-
|
|
723
|
+
save = getattr(args, 'save', False)
|
|
724
|
+
self.handle_research_command(research_query, research_model, verbose, save)
|
|
718
725
|
sys.exit(0)
|
|
719
726
|
|
|
720
727
|
# Only check framework availability for agent-related operations
|
|
@@ -812,7 +819,7 @@ class PraisonAI:
|
|
|
812
819
|
if "CHAINLIT_APP_ROOT" not in os.environ:
|
|
813
820
|
os.environ["CHAINLIT_APP_ROOT"] = root_path
|
|
814
821
|
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'chat.py')
|
|
815
|
-
|
|
822
|
+
_get_chainlit_run()([chat_ui_path])
|
|
816
823
|
else:
|
|
817
824
|
print("ERROR: Chat UI is not installed. Please install it with 'pip install \"praisonai[chat]\"' to use the chat UI.")
|
|
818
825
|
|
|
@@ -836,7 +843,7 @@ class PraisonAI:
|
|
|
836
843
|
else:
|
|
837
844
|
logging.info("Public folder already exists.")
|
|
838
845
|
code_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'code.py')
|
|
839
|
-
|
|
846
|
+
_get_chainlit_run()([code_ui_path])
|
|
840
847
|
else:
|
|
841
848
|
print("ERROR: Code UI is not installed. Please install it with 'pip install \"praisonai[code]\"' to use the code UI.")
|
|
842
849
|
|
|
@@ -882,7 +889,7 @@ class PraisonAI:
|
|
|
882
889
|
else:
|
|
883
890
|
logging.info("Public folder already exists.")
|
|
884
891
|
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'agents.py')
|
|
885
|
-
|
|
892
|
+
_get_chainlit_run()([chainlit_ui_path])
|
|
886
893
|
else:
|
|
887
894
|
print("ERROR: Chainlit is not installed. Please install it with 'pip install \"praisonai[ui]\"' to use the UI.")
|
|
888
895
|
|
|
@@ -906,7 +913,7 @@ class PraisonAI:
|
|
|
906
913
|
else:
|
|
907
914
|
logging.info("Public folder already exists.")
|
|
908
915
|
realtime_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'realtime.py')
|
|
909
|
-
|
|
916
|
+
_get_chainlit_run()([realtime_ui_path])
|
|
910
917
|
else:
|
|
911
918
|
print("ERROR: Realtime UI is not installed. Please install it with 'pip install \"praisonai[realtime]\"' to use the realtime UI.")
|
|
912
919
|
|
|
@@ -954,7 +961,7 @@ class PraisonAI:
|
|
|
954
961
|
print(f"[red]ERROR: Context engineering failed: {e}[/red]")
|
|
955
962
|
sys.exit(1)
|
|
956
963
|
|
|
957
|
-
def handle_research_command(self, query: str, model: str = None, verbose: bool = False) -> str:
|
|
964
|
+
def handle_research_command(self, query: str, model: str = None, verbose: bool = False, save: bool = False) -> str:
|
|
958
965
|
"""
|
|
959
966
|
Handle the research command by creating a DeepResearchAgent and running it.
|
|
960
967
|
|
|
@@ -962,6 +969,7 @@ class PraisonAI:
|
|
|
962
969
|
query: Research query/topic
|
|
963
970
|
model: Model for deep research (optional, defaults to o4-mini-deep-research)
|
|
964
971
|
verbose: Enable verbose output (default: False)
|
|
972
|
+
save: Save output to file (default: False)
|
|
965
973
|
|
|
966
974
|
Returns:
|
|
967
975
|
str: Research report
|
|
@@ -985,13 +993,10 @@ class PraisonAI:
|
|
|
985
993
|
|
|
986
994
|
print(f"Model: {model}")
|
|
987
995
|
|
|
988
|
-
# Create DeepResearchAgent
|
|
989
|
-
agent = DeepResearchAgent(
|
|
990
|
-
model=model,
|
|
991
|
-
verbose=verbose
|
|
992
|
-
)
|
|
996
|
+
# Create DeepResearchAgent (verbose=True is default for streaming output)
|
|
997
|
+
agent = DeepResearchAgent(model=model)
|
|
993
998
|
|
|
994
|
-
# Execute the research
|
|
999
|
+
# Execute the research
|
|
995
1000
|
result = agent.research(query)
|
|
996
1001
|
|
|
997
1002
|
print("\n[bold green]Research Complete![/bold green]")
|
|
@@ -1009,6 +1014,42 @@ class PraisonAI:
|
|
|
1009
1014
|
if url:
|
|
1010
1015
|
print(f" {url}")
|
|
1011
1016
|
|
|
1017
|
+
# Save output to file if --save flag is set
|
|
1018
|
+
if save:
|
|
1019
|
+
import re
|
|
1020
|
+
# Get first 10 words from query for filename
|
|
1021
|
+
words = query.split()[:10]
|
|
1022
|
+
filename_base = ' '.join(words)
|
|
1023
|
+
# Sanitize filename: remove invalid characters
|
|
1024
|
+
filename_base = re.sub(r'[<>:"/\\|?*\x00-\x1f]', '', filename_base)
|
|
1025
|
+
filename_base = filename_base.strip()[:100] # Limit length
|
|
1026
|
+
if not filename_base:
|
|
1027
|
+
filename_base = "research_output"
|
|
1028
|
+
|
|
1029
|
+
# Create output directory
|
|
1030
|
+
output_dir = os.path.join(os.getcwd(), "output", "research")
|
|
1031
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
1032
|
+
|
|
1033
|
+
# Build markdown content
|
|
1034
|
+
md_content = f"# {query}\n\n"
|
|
1035
|
+
md_content += result.report
|
|
1036
|
+
if result.citations:
|
|
1037
|
+
md_content += "\n\n## Citations\n\n"
|
|
1038
|
+
for i, citation in enumerate(result.citations, 1):
|
|
1039
|
+
title = getattr(citation, 'title', 'Untitled')
|
|
1040
|
+
url = getattr(citation, 'url', '')
|
|
1041
|
+
if url:
|
|
1042
|
+
md_content += f"{i}. [{title}]({url})\n"
|
|
1043
|
+
else:
|
|
1044
|
+
md_content += f"{i}. {title}\n"
|
|
1045
|
+
|
|
1046
|
+
# Save to file
|
|
1047
|
+
output_path = os.path.join(output_dir, f"{filename_base}.md")
|
|
1048
|
+
with open(output_path, 'w', encoding='utf-8') as f:
|
|
1049
|
+
f.write(md_content)
|
|
1050
|
+
|
|
1051
|
+
print(f"\n[bold green]Saved to:[/bold green] {output_path}")
|
|
1052
|
+
|
|
1012
1053
|
return result.report
|
|
1013
1054
|
|
|
1014
1055
|
except ImportError as e:
|
|
@@ -57,7 +57,7 @@ class CloudDeployer:
|
|
|
57
57
|
file.write("FROM python:3.11-slim\n")
|
|
58
58
|
file.write("WORKDIR /app\n")
|
|
59
59
|
file.write("COPY . .\n")
|
|
60
|
-
file.write("RUN pip install flask praisonai==2.2.
|
|
60
|
+
file.write("RUN pip install flask praisonai==2.2.93 gunicorn markdown\n")
|
|
61
61
|
file.write("EXPOSE 8080\n")
|
|
62
62
|
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
|
63
63
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "PraisonAI"
|
|
3
|
-
version = "2.2.
|
|
3
|
+
version = "2.2.93"
|
|
4
4
|
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = ""
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
"rich>=13.7",
|
|
13
13
|
"markdown>=3.5",
|
|
14
14
|
"pyparsing>=3.0.0",
|
|
15
|
-
"praisonaiagents>=0.0.
|
|
15
|
+
"praisonaiagents>=0.0.165",
|
|
16
16
|
"python-dotenv>=0.19.0",
|
|
17
17
|
"instructor>=1.3.3",
|
|
18
18
|
"PyYAML>=6.0",
|
|
@@ -102,7 +102,7 @@ autogen-v4 = [
|
|
|
102
102
|
|
|
103
103
|
[tool.poetry]
|
|
104
104
|
name = "PraisonAI"
|
|
105
|
-
version = "2.2.
|
|
105
|
+
version = "2.2.93"
|
|
106
106
|
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration."
|
|
107
107
|
authors = ["Mervin Praison"]
|
|
108
108
|
license = ""
|
|
@@ -120,7 +120,7 @@ python = ">=3.10,<3.13"
|
|
|
120
120
|
rich = ">=13.7"
|
|
121
121
|
markdown = ">=3.5"
|
|
122
122
|
pyparsing = ">=3.0.0"
|
|
123
|
-
praisonaiagents = ">=0.0.
|
|
123
|
+
praisonaiagents = ">=0.0.165"
|
|
124
124
|
python-dotenv = ">=0.19.0"
|
|
125
125
|
instructor = ">=1.3.3"
|
|
126
126
|
PyYAML = ">=6.0"
|
|
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
|
{praisonai-2.2.90 → praisonai-2.2.93}/praisonai/public/praison-ai-agents-architecture-dark.png
RENAMED
|
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
|