@datalayer/agent-runtimes 0.0.11 → 1.0.0
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.
- package/README.md +2 -2
- package/lib/Agent.d.ts +29 -0
- package/lib/Agent.js +131 -0
- package/lib/AgentLexical.d.ts +33 -0
- package/lib/AgentLexical.js +295 -0
- package/lib/AgentNotebook.d.ts +19 -0
- package/lib/AgentNotebook.js +192 -0
- package/lib/agent-lexical-main.d.ts +1 -0
- package/lib/agent-lexical-main.js +11 -0
- package/lib/agent-main.d.ts +1 -0
- package/lib/agent-main.js +11 -0
- package/lib/agent-notebook-main.d.ts +1 -0
- package/lib/agent-notebook-main.js +12 -0
- package/lib/components/AgentConfiguration.d.ts +4 -22
- package/lib/components/AgentConfiguration.js +8 -8
- package/lib/components/chat/components/AgentDetails.d.ts +3 -1
- package/lib/components/chat/components/AgentDetails.js +6 -6
- package/lib/components/chat/components/Chat.d.ts +29 -3
- package/lib/components/chat/components/Chat.js +64 -59
- package/lib/components/chat/components/ChatFloating.d.ts +34 -12
- package/lib/components/chat/components/ChatFloating.js +54 -21
- package/lib/components/chat/components/ChatInline.d.ts +5 -1
- package/lib/components/chat/components/ChatInline.js +8 -1
- package/lib/components/chat/components/ChatSidebar.d.ts +6 -1
- package/lib/components/chat/components/ChatSidebar.js +2 -2
- package/lib/components/chat/components/ChatStandalone.d.ts +6 -1
- package/lib/components/chat/components/ChatStandalone.js +2 -2
- package/lib/components/chat/components/base/ChatBase.d.ts +49 -8
- package/lib/components/chat/components/base/ChatBase.js +544 -149
- package/lib/components/chat/components/base/InputPrompt.d.ts +42 -0
- package/lib/components/chat/components/base/InputPrompt.js +131 -0
- package/lib/components/chat/components/index.d.ts +3 -3
- package/lib/components/chat/components/index.js +1 -1
- package/lib/components/chat/components/parts/ReasoningPart.js +2 -4
- package/lib/components/chat/components/parts/TextPart.js +2 -70
- package/lib/components/chat/components/styles/streamdownStyles.d.ts +23 -0
- package/lib/components/chat/components/styles/streamdownStyles.js +319 -0
- package/lib/components/chat/index.d.ts +1 -1
- package/lib/components/chat/index.js +1 -1
- package/lib/components/chat/inference/DatalayerInferenceProvider.js +16 -12
- package/lib/components/chat/inference/SelfHostedInferenceProvider.js +16 -12
- package/lib/components/chat/protocols/AGUIAdapter.d.ts +10 -3
- package/lib/components/chat/protocols/AGUIAdapter.js +123 -44
- package/lib/components/chat/types/tool.d.ts +5 -2
- package/lib/components/index.d.ts +1 -18
- package/lib/components/index.js +0 -9
- package/lib/config/index.d.ts +0 -4
- package/lib/config/index.js +0 -4
- package/lib/examples/A2UiRestaurantExample.js +1 -1
- package/lib/examples/AgentRuntimeChatExample.d.ts +15 -0
- package/lib/examples/AgentRuntimeChatExample.js +126 -0
- package/lib/examples/{AgentSpaceFormExample.d.ts → AgentRuntimeFormExample.d.ts} +3 -3
- package/lib/examples/{AgentSpaceFormExample.js → AgentRuntimeFormExample.js} +10 -8
- package/lib/examples/AgentRuntimeLexical2Example.d.ts +0 -1
- package/lib/examples/AgentRuntimeLexical2Example.js +0 -1
- package/lib/examples/AgentRuntimeLexicalExample.d.ts +0 -1
- package/lib/examples/AgentRuntimeLexicalExample.js +6 -4
- package/lib/examples/AgentRuntimeLexicalSidebarExample.d.ts +0 -1
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +8 -2
- package/lib/examples/AgentRuntimeNotebookExample.js +6 -5
- package/lib/examples/CopilotKitLexicalExample.d.ts +0 -1
- package/lib/examples/CopilotKitLexicalExample.js +0 -1
- package/lib/examples/CopilotKitNotebookExample.js +2 -2
- package/lib/examples/JupyterNotebookExample.js +2 -2
- package/lib/{components → examples/components}/Header.d.ts +2 -1
- package/lib/{components → examples/components}/HeaderControls.js +1 -1
- package/lib/{components → examples/components}/LexicalEditor.d.ts +6 -1
- package/lib/{components → examples/components}/LexicalEditor.js +4 -4
- package/lib/{components → examples/components}/MainContent.d.ts +1 -1
- package/lib/{components → examples/components}/MainContent.js +7 -5
- package/lib/examples/components/index.d.ts +16 -0
- package/lib/examples/components/index.js +13 -0
- package/lib/examples/example-selector.js +2 -1
- package/lib/examples/index.d.ts +1 -1
- package/lib/examples/index.js +1 -1
- package/lib/examples/main.js +2 -2
- package/lib/examples/stores/examplesStore.d.ts +2 -23
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -0
- package/lib/lexical/ChatInlinePlugin.d.ts +13 -2
- package/lib/lexical/ChatInlinePlugin.js +66 -183
- package/lib/lexical/index.d.ts +1 -0
- package/lib/lexical/index.js +1 -0
- package/lib/lexical/useChatInlineToolbarItems.d.ts +35 -0
- package/lib/lexical/useChatInlineToolbarItems.js +91 -0
- package/lib/runtime/useAgentRuntime.d.ts +1 -1
- package/lib/runtime/useAgentRuntime.js +1 -1
- package/lib/{config/agents/code-ai → specs/agents/codeai}/agents.d.ts +5 -2
- package/lib/specs/agents/codeai/agents.js +151 -0
- package/lib/{config → specs}/agents/codemode-paper/agents.d.ts +4 -2
- package/lib/{config → specs}/agents/codemode-paper/agents.js +39 -19
- package/lib/{config → specs}/agents/datalayer-ai/agents.d.ts +4 -2
- package/lib/{config → specs}/agents/datalayer-ai/agents.js +17 -2
- package/lib/{config → specs}/agents/index.d.ts +3 -1
- package/lib/{config → specs}/agents/index.js +12 -3
- package/lib/{config → specs}/envvars.d.ts +1 -0
- package/lib/{config → specs}/envvars.js +10 -0
- package/lib/specs/index.d.ts +5 -0
- package/lib/specs/index.js +9 -0
- package/lib/{config → specs}/mcpServers.d.ts +2 -1
- package/lib/{config → specs}/mcpServers.js +23 -1
- package/lib/specs/models.d.ts +68 -0
- package/lib/specs/models.js +239 -0
- package/lib/state/substates/AIAgentState.d.ts +0 -1
- package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.d.ts +11 -22
- package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.js +5 -5
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.d.ts +6 -6
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.js +4 -4
- package/lib/tools/adapters/agent-runtimes/notebookHooks.d.ts +6 -6
- package/lib/tools/adapters/agent-runtimes/notebookHooks.js +4 -4
- package/lib/{types.d.ts → types/Types.d.ts} +32 -6
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/package.json +11 -5
- package/scripts/codegen/generate_agents.py +53 -13
- package/scripts/codegen/generate_envvars.py +1 -1
- package/scripts/codegen/generate_mcp_servers.py +5 -5
- package/scripts/codegen/generate_models.py +486 -0
- package/scripts/codegen/generate_skills.py +2 -2
- package/style/primer-primitives.css +22 -0
- package/lib/components/chat/components/elements/ChatInputPrompt.d.ts +0 -37
- package/lib/components/chat/components/elements/ChatInputPrompt.js +0 -150
- package/lib/config/agents/code-ai/agents.js +0 -70
- /package/lib/{components → examples/components}/FooterMetrics.d.ts +0 -0
- /package/lib/{components → examples/components}/FooterMetrics.js +0 -0
- /package/lib/{components → examples/components}/Header.js +0 -0
- /package/lib/{components → examples/components}/HeaderControls.d.ts +0 -0
- /package/lib/{components → examples/components}/MockFileBrowser.d.ts +0 -0
- /package/lib/{components → examples/components}/MockFileBrowser.js +0 -0
- /package/lib/{components → examples/components}/SessionTabs.d.ts +0 -0
- /package/lib/{components → examples/components}/SessionTabs.js +0 -0
- /package/lib/{components → examples/components}/TimeTravel.d.ts +0 -0
- /package/lib/{components → examples/components}/TimeTravel.js +0 -0
- /package/lib/{config/agents/code-ai → specs/agents/codeai}/index.d.ts +0 -0
- /package/lib/{config/agents/code-ai → specs/agents/codeai}/index.js +0 -0
- /package/lib/{config → specs}/agents/codemode-paper/index.d.ts +0 -0
- /package/lib/{config → specs}/agents/codemode-paper/index.js +0 -0
- /package/lib/{config → specs}/agents/datalayer-ai/index.d.ts +0 -0
- /package/lib/{config → specs}/agents/datalayer-ai/index.js +0 -0
- /package/lib/{config → specs}/skills.d.ts +0 -0
- /package/lib/{config → specs}/skills.js +0 -0
- /package/lib/{types.js → types/Types.js} +0 -0
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
-
* Distributed under the terms of the Modified BSD License.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Chat input component.
|
|
8
|
-
* Provides the message input area with send button and optional tool suggestions.
|
|
9
|
-
*
|
|
10
|
-
* @module components/chat/components/elements/ChatInputPrompt
|
|
11
|
-
*/
|
|
12
|
-
import React, { useState, useRef, useCallback, useEffect, } from 'react';
|
|
13
|
-
import { Button, Textarea, IconButton, ActionList } from '@primer/react';
|
|
14
|
-
import { Box } from '@datalayer/primer-addons';
|
|
15
|
-
import { PaperAirplaneIcon, SquareCircleIcon, UploadIcon, MentionIcon, } from '@primer/octicons-react';
|
|
16
|
-
import { useChat } from '../../../../hooks/useChat';
|
|
17
|
-
import { useChatStreaming, useChatTools } from '../../store/chatStore';
|
|
18
|
-
/**
|
|
19
|
-
* Chat Input Prompt component
|
|
20
|
-
*/
|
|
21
|
-
export function ChatInputPrompt({ placeholder = 'Type a message...', disabled = false, showToolSuggestions = true, showFileUpload = false, maxRows = 6, className, leadingIcon, sendButtonText = 'Send', onBeforeSend, onAfterSend, }) {
|
|
22
|
-
const [input, setInput] = useState('');
|
|
23
|
-
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
24
|
-
const textareaRef = useRef(null);
|
|
25
|
-
const { sendMessage, stopGeneration } = useChat();
|
|
26
|
-
const { isStreaming } = useChatStreaming();
|
|
27
|
-
const tools = useChatTools();
|
|
28
|
-
// Auto-resize textarea based on content
|
|
29
|
-
const adjustTextareaHeight = useCallback(() => {
|
|
30
|
-
const textarea = textareaRef.current;
|
|
31
|
-
if (textarea) {
|
|
32
|
-
// Reset height to auto to get proper scrollHeight
|
|
33
|
-
textarea.style.height = 'auto';
|
|
34
|
-
// Set height to scrollHeight, capped at maxHeight
|
|
35
|
-
const maxHeight = maxRows * 24; // Approximate line height
|
|
36
|
-
const newHeight = Math.min(textarea.scrollHeight, maxHeight);
|
|
37
|
-
textarea.style.height = `${newHeight}px`;
|
|
38
|
-
// Add overflow if content exceeds maxHeight
|
|
39
|
-
textarea.style.overflowY =
|
|
40
|
-
textarea.scrollHeight > maxHeight ? 'auto' : 'hidden';
|
|
41
|
-
}
|
|
42
|
-
}, [maxRows]);
|
|
43
|
-
// Adjust textarea height when input changes
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
adjustTextareaHeight();
|
|
46
|
-
}, [input, adjustTextareaHeight]);
|
|
47
|
-
// Auto-focus on mount
|
|
48
|
-
useEffect(() => {
|
|
49
|
-
if (textareaRef.current && !disabled) {
|
|
50
|
-
textareaRef.current.focus();
|
|
51
|
-
}
|
|
52
|
-
}, [disabled]);
|
|
53
|
-
// Handle send
|
|
54
|
-
const handleSend = useCallback(async () => {
|
|
55
|
-
const trimmedInput = input.trim();
|
|
56
|
-
if (!trimmedInput || disabled || isStreaming)
|
|
57
|
-
return;
|
|
58
|
-
// Call onBeforeSend hook
|
|
59
|
-
if (onBeforeSend) {
|
|
60
|
-
const result = onBeforeSend(trimmedInput);
|
|
61
|
-
if (result === false)
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
try {
|
|
65
|
-
await sendMessage(trimmedInput);
|
|
66
|
-
setInput('');
|
|
67
|
-
onAfterSend?.(trimmedInput);
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
console.error('[ChatInputPrompt] Send error:', error);
|
|
71
|
-
}
|
|
72
|
-
}, [input, disabled, isStreaming, sendMessage, onBeforeSend, onAfterSend]);
|
|
73
|
-
// Handle stop
|
|
74
|
-
const handleStop = useCallback(() => {
|
|
75
|
-
stopGeneration();
|
|
76
|
-
}, [stopGeneration]);
|
|
77
|
-
// Handle key press
|
|
78
|
-
const handleKeyDown = useCallback((event) => {
|
|
79
|
-
if (event.key === 'Enter' && !event.shiftKey) {
|
|
80
|
-
event.preventDefault();
|
|
81
|
-
handleSend();
|
|
82
|
-
}
|
|
83
|
-
// Show tool suggestions with @
|
|
84
|
-
if (event.key === '@' && showToolSuggestions) {
|
|
85
|
-
setShowSuggestions(true);
|
|
86
|
-
}
|
|
87
|
-
}, [handleSend, showToolSuggestions]);
|
|
88
|
-
// Handle tool mention
|
|
89
|
-
const handleToolMention = useCallback((toolName) => {
|
|
90
|
-
const cursorPosition = textareaRef.current?.selectionStart || input.length;
|
|
91
|
-
const beforeCursor = input.slice(0, cursorPosition);
|
|
92
|
-
const afterCursor = input.slice(cursorPosition);
|
|
93
|
-
// Replace @... with tool mention
|
|
94
|
-
const lastAtIndex = beforeCursor.lastIndexOf('@');
|
|
95
|
-
const newInput = beforeCursor.slice(0, lastAtIndex) + `@${toolName} ` + afterCursor;
|
|
96
|
-
setInput(newInput);
|
|
97
|
-
setShowSuggestions(false);
|
|
98
|
-
// Focus back on textarea
|
|
99
|
-
textareaRef.current?.focus();
|
|
100
|
-
}, [input]);
|
|
101
|
-
// Filter tools based on input
|
|
102
|
-
const filteredTools = React.useMemo(() => {
|
|
103
|
-
if (!showSuggestions)
|
|
104
|
-
return [];
|
|
105
|
-
const cursorPosition = textareaRef.current?.selectionStart || input.length;
|
|
106
|
-
const beforeCursor = input.slice(0, cursorPosition);
|
|
107
|
-
const lastAtIndex = beforeCursor.lastIndexOf('@');
|
|
108
|
-
if (lastAtIndex === -1)
|
|
109
|
-
return [];
|
|
110
|
-
const query = beforeCursor.slice(lastAtIndex + 1).toLowerCase();
|
|
111
|
-
return Object.values(tools).filter(tool => tool.name.toLowerCase().includes(query) ||
|
|
112
|
-
tool.description?.toLowerCase().includes(query));
|
|
113
|
-
}, [tools, input, showSuggestions]);
|
|
114
|
-
return (_jsxs(Box, { className: className, sx: {
|
|
115
|
-
display: 'flex',
|
|
116
|
-
flexDirection: 'column',
|
|
117
|
-
gap: 2,
|
|
118
|
-
p: 3,
|
|
119
|
-
borderTop: '1px solid',
|
|
120
|
-
borderColor: 'border.default',
|
|
121
|
-
bg: 'canvas.default',
|
|
122
|
-
position: 'relative',
|
|
123
|
-
}, children: [showSuggestions && filteredTools.length > 0 && (_jsx(Box, { sx: {
|
|
124
|
-
position: 'absolute',
|
|
125
|
-
bottom: '100%',
|
|
126
|
-
left: 3,
|
|
127
|
-
right: 3,
|
|
128
|
-
maxHeight: 200,
|
|
129
|
-
overflow: 'auto',
|
|
130
|
-
bg: 'canvas.overlay',
|
|
131
|
-
border: '1px solid',
|
|
132
|
-
borderColor: 'border.default',
|
|
133
|
-
borderRadius: 2,
|
|
134
|
-
boxShadow: 'shadow.large',
|
|
135
|
-
zIndex: 10,
|
|
136
|
-
}, children: _jsx(ActionList, { children: filteredTools.map(tool => (_jsxs(ActionList.Item, { onSelect: () => handleToolMention(tool.name), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(MentionIcon, {}) }), _jsxs(Box, { children: [_jsx(Box, { sx: { fontWeight: 'semibold' }, children: tool.name }), tool.description && (_jsx(Box, { sx: { fontSize: 0, color: 'fg.muted' }, children: tool.description }))] })] }, tool.name))) }) })), _jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'flex-end' }, children: [leadingIcon && (_jsx(Box, { sx: {
|
|
137
|
-
display: 'flex',
|
|
138
|
-
alignItems: 'center',
|
|
139
|
-
color: 'fg.muted',
|
|
140
|
-
pb: 2,
|
|
141
|
-
}, children: leadingIcon })), showFileUpload && (_jsx(IconButton, { icon: UploadIcon, "aria-label": "Upload file", variant: "invisible", disabled: disabled || !!isStreaming })), _jsx(Box, { sx: { flex: 1 }, children: _jsx(Textarea, { ref: textareaRef, value: input, onChange: e => setInput(e.target.value), onKeyDown: handleKeyDown, onBlur: () => setTimeout(() => setShowSuggestions(false), 200), placeholder: placeholder, disabled: disabled || !!isStreaming, rows: 1, sx: {
|
|
142
|
-
width: '100%',
|
|
143
|
-
maxHeight: `${maxRows * 24}px`,
|
|
144
|
-
minHeight: '40px',
|
|
145
|
-
resize: 'none',
|
|
146
|
-
overflow: 'hidden',
|
|
147
|
-
transition: 'height 0.1s ease-out',
|
|
148
|
-
} }) }), isStreaming ? (_jsx(Button, { variant: "danger", onClick: handleStop, leadingVisual: SquareCircleIcon, "aria-label": "Stop generation", children: "Stop" })) : (_jsx(Button, { variant: "primary", onClick: handleSend, disabled: disabled || !input.trim(), leadingVisual: PaperAirplaneIcon, "aria-label": "Send message", children: sendButtonText }))] }), _jsxs(Box, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Press ", _jsx("kbd", { children: "Enter" }), " to send, ", _jsx("kbd", { children: "Shift+Enter" }), " for new line", showToolSuggestions && ', @ to mention tools'] })] }));
|
|
149
|
-
}
|
|
150
|
-
export default ChatInputPrompt;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
// ============================================================================
|
|
6
|
-
// Agent Specs
|
|
7
|
-
// ============================================================================
|
|
8
|
-
// Code Ai Agents
|
|
9
|
-
// ============================================================================
|
|
10
|
-
export const SIMPLE_AGENT_SPEC = {
|
|
11
|
-
id: 'code-ai/simple',
|
|
12
|
-
name: 'A Simple Agent',
|
|
13
|
-
description: `A simple conversational agent. No tools, no MCP servers, no skills — just a helpful AI assistant you can chat with.`,
|
|
14
|
-
tags: ['simple', 'chat', 'assistant'],
|
|
15
|
-
enabled: true,
|
|
16
|
-
mcpServers: [],
|
|
17
|
-
skills: [],
|
|
18
|
-
environmentName: 'ai-agents-env',
|
|
19
|
-
icon: 'share-2',
|
|
20
|
-
emoji: '🤖',
|
|
21
|
-
color: '#6366F1',
|
|
22
|
-
suggestions: [
|
|
23
|
-
'Tell me a joke',
|
|
24
|
-
'Explain quantum computing in simple terms',
|
|
25
|
-
'Help me brainstorm ideas for a weekend project',
|
|
26
|
-
'Summarize the key points of a topic I describe',
|
|
27
|
-
],
|
|
28
|
-
systemPrompt: `You are a helpful, friendly AI assistant. You do not have access to any external tools, MCP servers, or skills. Answer questions using your training knowledge, be concise, and let the user know if a question is outside your knowledge.
|
|
29
|
-
`,
|
|
30
|
-
systemPromptCodemodeAddons: undefined,
|
|
31
|
-
};
|
|
32
|
-
// ============================================================================
|
|
33
|
-
// Agent Specs Registry
|
|
34
|
-
// ============================================================================
|
|
35
|
-
export const AGENT_SPECS = {
|
|
36
|
-
// Code Ai
|
|
37
|
-
'code-ai/simple': SIMPLE_AGENT_SPEC,
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Get an agent specification by ID.
|
|
41
|
-
*/
|
|
42
|
-
export function getAgentSpecs(agentId) {
|
|
43
|
-
return AGENT_SPECS[agentId];
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* List all available agent specifications.
|
|
47
|
-
*/
|
|
48
|
-
export function listAgentSpecs() {
|
|
49
|
-
return Object.values(AGENT_SPECS);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Collect all required environment variables for an agent spec.
|
|
53
|
-
*
|
|
54
|
-
* Iterates over the spec's MCP servers and skills and returns the
|
|
55
|
-
* deduplicated union of their `requiredEnvVars` arrays.
|
|
56
|
-
*/
|
|
57
|
-
export function getAgentSpecRequiredEnvVars(spec) {
|
|
58
|
-
const vars = new Set();
|
|
59
|
-
for (const server of spec.mcpServers) {
|
|
60
|
-
for (const v of server.requiredEnvVars ?? []) {
|
|
61
|
-
vars.add(v);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
for (const skill of spec.skills) {
|
|
65
|
-
for (const v of skill.requiredEnvVars ?? []) {
|
|
66
|
-
vars.add(v);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return Array.from(vars);
|
|
70
|
-
}
|
|
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
|