gitarsenal-cli 1.9.112 → 1.9.113
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/.venv_status.json +1 -1
- package/package.json +1 -1
- package/tui-app/index.jsx +163 -20
package/.venv_status.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"created":"2025-10-15T14:
|
|
1
|
+
{"created":"2025-10-15T14:18:56.158Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
|
package/package.json
CHANGED
package/tui-app/index.jsx
CHANGED
|
@@ -380,7 +380,7 @@ const AuthChoice = ({ selectedIndex }) => {
|
|
|
380
380
|
);
|
|
381
381
|
};
|
|
382
382
|
|
|
383
|
-
const LoginForm = ({ values, onInput, onSubmit }) => {
|
|
383
|
+
const LoginForm = ({ values, onInput, onSubmit, onNextField, focusedFieldIndex }) => {
|
|
384
384
|
const fields = ['username', 'email', 'fullName', 'password'];
|
|
385
385
|
const labels = ['Username:', 'Email Address:', 'Full Name:', 'Password:'];
|
|
386
386
|
|
|
@@ -395,21 +395,21 @@ const LoginForm = ({ values, onInput, onSubmit }) => {
|
|
|
395
395
|
<input
|
|
396
396
|
value={values[field] || ''}
|
|
397
397
|
onInput={(value) => onInput(field, value)}
|
|
398
|
-
onSubmit={index === fields.length - 1 ? onSubmit :
|
|
398
|
+
onSubmit={index === fields.length - 1 ? onSubmit : () => onNextField(index)}
|
|
399
399
|
placeholder={field === 'password' ? '••••••••' : ''}
|
|
400
|
-
focused={index ===
|
|
400
|
+
focused={index === focusedFieldIndex}
|
|
401
401
|
width={50}
|
|
402
402
|
/>
|
|
403
403
|
</box>
|
|
404
404
|
))}
|
|
405
405
|
<box marginTop={1}>
|
|
406
|
-
<text dimColor fg="gray">
|
|
406
|
+
<text dimColor fg="gray">Tab or Enter to next field • Esc to go back</text>
|
|
407
407
|
</box>
|
|
408
408
|
</box>
|
|
409
409
|
);
|
|
410
410
|
};
|
|
411
411
|
|
|
412
|
-
const RegisterForm = ({ values, onInput, onSubmit }) => {
|
|
412
|
+
const RegisterForm = ({ values, onInput, onSubmit, onNextField, focusedFieldIndex }) => {
|
|
413
413
|
const fields = ['username', 'email', 'fullName', 'password', 'confirmPassword'];
|
|
414
414
|
const labels = ['Username:', 'Email Address:', 'Full Name:', 'Password (min 8 chars):', 'Confirm Password:'];
|
|
415
415
|
|
|
@@ -424,15 +424,60 @@ const RegisterForm = ({ values, onInput, onSubmit }) => {
|
|
|
424
424
|
<input
|
|
425
425
|
value={values[field] || ''}
|
|
426
426
|
onInput={(value) => onInput(field, value)}
|
|
427
|
-
onSubmit={index === fields.length - 1 ? onSubmit :
|
|
427
|
+
onSubmit={index === fields.length - 1 ? onSubmit : () => onNextField(index)}
|
|
428
428
|
placeholder={field.includes('password') ? '••••••••' : ''}
|
|
429
|
-
focused={index ===
|
|
429
|
+
focused={index === focusedFieldIndex}
|
|
430
430
|
width={50}
|
|
431
431
|
/>
|
|
432
432
|
</box>
|
|
433
433
|
))}
|
|
434
434
|
<box marginTop={1}>
|
|
435
|
-
<text dimColor fg="gray">
|
|
435
|
+
<text dimColor fg="gray">Tab or Enter to next field • Esc to go back</text>
|
|
436
|
+
</box>
|
|
437
|
+
</box>
|
|
438
|
+
);
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
const Settings = ({ userCredentials, selectedIndex }) => {
|
|
442
|
+
const settingsOptions = userCredentials
|
|
443
|
+
? ['Create New Account', 'Logout', 'Back to Menu']
|
|
444
|
+
: ['Create Account', 'Login', 'Back to Menu'];
|
|
445
|
+
|
|
446
|
+
return (
|
|
447
|
+
<box style={{ flexDirection: 'column', alignItems: 'center' }}>
|
|
448
|
+
<box borderStyle="single" padding={1} marginBottom={1}>
|
|
449
|
+
<text bold>Settings</text>
|
|
450
|
+
</box>
|
|
451
|
+
|
|
452
|
+
{userCredentials ? (
|
|
453
|
+
<box marginBottom={2} style={{ flexDirection: 'column', alignItems: 'center' }}>
|
|
454
|
+
<text fg="green">Logged in as: {userCredentials.userName}</text>
|
|
455
|
+
<text dimColor fg="gray">{userCredentials.userEmail}</text>
|
|
456
|
+
</box>
|
|
457
|
+
) : (
|
|
458
|
+
<box marginBottom={2} style={{ flexDirection: 'column', alignItems: 'center' }}>
|
|
459
|
+
<text dimColor fg="gray">No account logged in</text>
|
|
460
|
+
</box>
|
|
461
|
+
)}
|
|
462
|
+
|
|
463
|
+
{settingsOptions.map((option, index) => (
|
|
464
|
+
<box key={index} marginY={0} marginBottom={0}>
|
|
465
|
+
{index === selectedIndex ? (
|
|
466
|
+
<box borderStyle="single" borderColor="cyan" paddingX={2} paddingY={0} width={48} style={{ justifyContent: 'center' }}>
|
|
467
|
+
<text bold fg="cyan">{option}</text>
|
|
468
|
+
</box>
|
|
469
|
+
) : (
|
|
470
|
+
<box borderStyle="single" borderColor="gray" paddingX={2} paddingY={0} width={48} style={{ justifyContent: 'center' }}>
|
|
471
|
+
<text dimColor>{option}</text>
|
|
472
|
+
</box>
|
|
473
|
+
)}
|
|
474
|
+
</box>
|
|
475
|
+
))}
|
|
476
|
+
|
|
477
|
+
<box marginTop={2} style={{ flexDirection: 'column', alignItems: 'center' }}>
|
|
478
|
+
<text bold>Controls:</text>
|
|
479
|
+
<text dimColor fg="gray">↑↓ - Navigate • Enter - Select</text>
|
|
480
|
+
<text dimColor fg="gray">Esc - Back to menu</text>
|
|
436
481
|
</box>
|
|
437
482
|
</box>
|
|
438
483
|
);
|
|
@@ -498,7 +543,7 @@ const ApiKeysManagement = ({ apiKeys, selectedIndex }) => {
|
|
|
498
543
|
);
|
|
499
544
|
};
|
|
500
545
|
|
|
501
|
-
const ApiKeyForm = ({ serviceName, apiKey, onServiceInput, onKeyInput, onSubmit, isEditing }) => {
|
|
546
|
+
const ApiKeyForm = ({ serviceName, apiKey, onServiceInput, onKeyInput, onSubmit, onNextField, isEditing, focusedFieldIndex }) => {
|
|
502
547
|
return (
|
|
503
548
|
<box style={{ flexDirection: 'column', alignItems: 'center' }}>
|
|
504
549
|
<box borderStyle="single" padding={1} marginBottom={1}>
|
|
@@ -524,8 +569,9 @@ const ApiKeyForm = ({ serviceName, apiKey, onServiceInput, onKeyInput, onSubmit,
|
|
|
524
569
|
<input
|
|
525
570
|
value={serviceName || ''}
|
|
526
571
|
onInput={onServiceInput}
|
|
572
|
+
onSubmit={onNextField}
|
|
527
573
|
placeholder="e.g., openai_api_key"
|
|
528
|
-
focused={
|
|
574
|
+
focused={focusedFieldIndex === 0}
|
|
529
575
|
width={70}
|
|
530
576
|
/>
|
|
531
577
|
</box>
|
|
@@ -545,13 +591,13 @@ const ApiKeyForm = ({ serviceName, apiKey, onServiceInput, onKeyInput, onSubmit,
|
|
|
545
591
|
onInput={onKeyInput}
|
|
546
592
|
onSubmit={onSubmit}
|
|
547
593
|
placeholder="Paste your API key here..."
|
|
548
|
-
focused={isEditing}
|
|
594
|
+
focused={isEditing || focusedFieldIndex === 1}
|
|
549
595
|
width={70}
|
|
550
596
|
/>
|
|
551
597
|
</box>
|
|
552
598
|
|
|
553
599
|
<box marginTop={1} style={{ flexDirection: 'column', alignItems: 'center' }}>
|
|
554
|
-
<text dimColor fg="gray">Enter to save • Esc to cancel</text>
|
|
600
|
+
<text dimColor fg="gray">{isEditing ? 'Enter to save' : 'Tab or Enter to next field'} • Esc to cancel</text>
|
|
555
601
|
{isEditing && <text dimColor fg="gray">Clear field to remove the key</text>}
|
|
556
602
|
</box>
|
|
557
603
|
</box>
|
|
@@ -682,11 +728,13 @@ const App = () => {
|
|
|
682
728
|
const [viewingSandboxId, setViewingSandboxId] = useState(null);
|
|
683
729
|
const [userCredentials, setUserCredentials] = useState(null);
|
|
684
730
|
const [authFormValues, setAuthFormValues] = useState({});
|
|
731
|
+
const [authFieldIndex, setAuthFieldIndex] = useState(0);
|
|
685
732
|
const [apiKeys, setApiKeys] = useState({});
|
|
686
733
|
const [editingServiceName, setEditingServiceName] = useState('');
|
|
687
734
|
const [serviceNameInput, setServiceNameInput] = useState('');
|
|
688
735
|
const [apiKeyInput, setApiKeyInput] = useState('');
|
|
689
736
|
const [isEditingExisting, setIsEditingExisting] = useState(false);
|
|
737
|
+
const [apiKeyFieldIndex, setApiKeyFieldIndex] = useState(0);
|
|
690
738
|
|
|
691
739
|
// Load user credentials on mount
|
|
692
740
|
useEffect(() => {
|
|
@@ -819,8 +867,14 @@ const App = () => {
|
|
|
819
867
|
setServiceNameInput('');
|
|
820
868
|
setApiKeyInput('');
|
|
821
869
|
setIsEditingExisting(false);
|
|
870
|
+
setApiKeyFieldIndex(0);
|
|
822
871
|
setScreen('apiKeysManagement');
|
|
823
872
|
setSelectedIndex(0);
|
|
873
|
+
} else if (key.name === 'tab') {
|
|
874
|
+
// Toggle between fields when adding new key
|
|
875
|
+
if (!isEditingExisting) {
|
|
876
|
+
setApiKeyFieldIndex((prev) => (prev === 0 ? 1 : 0));
|
|
877
|
+
}
|
|
824
878
|
}
|
|
825
879
|
// Let the input component handle all other keys
|
|
826
880
|
return;
|
|
@@ -841,6 +895,10 @@ const App = () => {
|
|
|
841
895
|
} else if (selectedIndex === 2) {
|
|
842
896
|
setScreen('apiKeysManagement');
|
|
843
897
|
setSelectedIndex(0);
|
|
898
|
+
} else if (selectedIndex === 3) {
|
|
899
|
+
// Settings
|
|
900
|
+
setScreen('settings');
|
|
901
|
+
setSelectedIndex(0);
|
|
844
902
|
} else if (selectedIndex === 4) {
|
|
845
903
|
// Help & Examples - open docs page
|
|
846
904
|
openUrl('https://gitarsenal.dev/docs');
|
|
@@ -917,25 +975,35 @@ const App = () => {
|
|
|
917
975
|
if (selectedIndex === 0) {
|
|
918
976
|
setScreen('register');
|
|
919
977
|
setAuthFormValues({});
|
|
978
|
+
setAuthFieldIndex(0);
|
|
920
979
|
} else {
|
|
921
980
|
setScreen('login');
|
|
922
981
|
setAuthFormValues({});
|
|
982
|
+
setAuthFieldIndex(0);
|
|
923
983
|
}
|
|
924
984
|
} else if (key.name === 'escape') {
|
|
925
985
|
process.exit(0);
|
|
926
986
|
}
|
|
927
987
|
} else if (screen === 'login') {
|
|
988
|
+
const loginFields = 4;
|
|
928
989
|
if (key.name === 'escape') {
|
|
929
|
-
setScreen('
|
|
990
|
+
setScreen('settings');
|
|
930
991
|
setSelectedIndex(0);
|
|
931
992
|
setAuthFormValues({});
|
|
993
|
+
setAuthFieldIndex(0);
|
|
994
|
+
} else if (key.name === 'tab') {
|
|
995
|
+
setAuthFieldIndex((prev) => (prev < loginFields - 1 ? prev + 1 : 0));
|
|
932
996
|
}
|
|
933
997
|
// Submit is handled by input component's onSubmit
|
|
934
998
|
} else if (screen === 'register') {
|
|
999
|
+
const registerFields = 5;
|
|
935
1000
|
if (key.name === 'escape') {
|
|
936
|
-
setScreen('
|
|
1001
|
+
setScreen('settings');
|
|
937
1002
|
setSelectedIndex(0);
|
|
938
1003
|
setAuthFormValues({});
|
|
1004
|
+
setAuthFieldIndex(0);
|
|
1005
|
+
} else if (key.name === 'tab') {
|
|
1006
|
+
setAuthFieldIndex((prev) => (prev < registerFields - 1 ? prev + 1 : 0));
|
|
939
1007
|
}
|
|
940
1008
|
// Submit is handled by input component's onSubmit
|
|
941
1009
|
} else if (screen === 'sandboxList') {
|
|
@@ -967,6 +1035,59 @@ const App = () => {
|
|
|
967
1035
|
setViewingSandboxId(null);
|
|
968
1036
|
setScreen('sandboxList');
|
|
969
1037
|
}
|
|
1038
|
+
} else if (screen === 'settings') {
|
|
1039
|
+
const settingsOptions = userCredentials ? 3 : 3; // Always 3 options
|
|
1040
|
+
|
|
1041
|
+
if (key.name === 'up') {
|
|
1042
|
+
setSelectedIndex((prev) => (prev > 0 ? prev - 1 : settingsOptions - 1));
|
|
1043
|
+
} else if (key.name === 'down') {
|
|
1044
|
+
setSelectedIndex((prev) => (prev < settingsOptions - 1 ? prev + 1 : 0));
|
|
1045
|
+
} else if (key.name === 'return' || key.name === 'enter') {
|
|
1046
|
+
if (userCredentials) {
|
|
1047
|
+
// Logged in: Create New Account, Logout, Back to Menu
|
|
1048
|
+
if (selectedIndex === 0) {
|
|
1049
|
+
// Create New Account
|
|
1050
|
+
setScreen('register');
|
|
1051
|
+
setAuthFormValues({});
|
|
1052
|
+
setAuthFieldIndex(0);
|
|
1053
|
+
} else if (selectedIndex === 1) {
|
|
1054
|
+
// Logout
|
|
1055
|
+
setUserCredentials(null);
|
|
1056
|
+
const { userConfigPath } = getUserConfigPath();
|
|
1057
|
+
if (fs.existsSync(userConfigPath)) {
|
|
1058
|
+
fs.unlinkSync(userConfigPath);
|
|
1059
|
+
}
|
|
1060
|
+
setStatusMessage('Logged out successfully');
|
|
1061
|
+
setTimeout(() => setStatusMessage(''), 3000);
|
|
1062
|
+
setScreen('menu');
|
|
1063
|
+
setSelectedIndex(0);
|
|
1064
|
+
} else if (selectedIndex === 2) {
|
|
1065
|
+
// Back to Menu
|
|
1066
|
+
setScreen('menu');
|
|
1067
|
+
setSelectedIndex(0);
|
|
1068
|
+
}
|
|
1069
|
+
} else {
|
|
1070
|
+
// Not logged in: Create Account, Login, Back to Menu
|
|
1071
|
+
if (selectedIndex === 0) {
|
|
1072
|
+
// Create Account
|
|
1073
|
+
setScreen('register');
|
|
1074
|
+
setAuthFormValues({});
|
|
1075
|
+
setAuthFieldIndex(0);
|
|
1076
|
+
} else if (selectedIndex === 1) {
|
|
1077
|
+
// Login
|
|
1078
|
+
setScreen('login');
|
|
1079
|
+
setAuthFormValues({});
|
|
1080
|
+
setAuthFieldIndex(0);
|
|
1081
|
+
} else if (selectedIndex === 2) {
|
|
1082
|
+
// Back to Menu
|
|
1083
|
+
setScreen('menu');
|
|
1084
|
+
setSelectedIndex(0);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
} else if (key.name === 'escape') {
|
|
1088
|
+
setScreen('menu');
|
|
1089
|
+
setSelectedIndex(0);
|
|
1090
|
+
}
|
|
970
1091
|
} else if (screen === 'apiKeysManagement') {
|
|
971
1092
|
// Calculate items: 1 "Add New" + all stored keys
|
|
972
1093
|
const storedKeyNames = Object.keys(apiKeys).sort();
|
|
@@ -982,6 +1103,7 @@ const App = () => {
|
|
|
982
1103
|
setServiceNameInput('');
|
|
983
1104
|
setApiKeyInput('');
|
|
984
1105
|
setIsEditingExisting(false);
|
|
1106
|
+
setApiKeyFieldIndex(0);
|
|
985
1107
|
setScreen('apiKeyForm');
|
|
986
1108
|
} else {
|
|
987
1109
|
// One of the stored keys selected - edit it
|
|
@@ -990,6 +1112,7 @@ const App = () => {
|
|
|
990
1112
|
setServiceNameInput(serviceName);
|
|
991
1113
|
setApiKeyInput(apiKeys[serviceName] || '');
|
|
992
1114
|
setIsEditingExisting(true);
|
|
1115
|
+
setApiKeyFieldIndex(0);
|
|
993
1116
|
setScreen('apiKeyForm');
|
|
994
1117
|
}
|
|
995
1118
|
} else if (key.name === 'd') {
|
|
@@ -1030,6 +1153,13 @@ const App = () => {
|
|
|
1030
1153
|
setAuthFormValues(prev => ({ ...prev, [field]: value }));
|
|
1031
1154
|
};
|
|
1032
1155
|
|
|
1156
|
+
const handleAuthNextField = (currentIndex) => {
|
|
1157
|
+
const maxFields = screen === 'register' ? 4 : 3; // register has 5 fields (0-4), login has 4 fields (0-3)
|
|
1158
|
+
if (currentIndex < maxFields) {
|
|
1159
|
+
setAuthFieldIndex(currentIndex + 1);
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1033
1163
|
const handleLoginSubmit = () => {
|
|
1034
1164
|
const { username, email, fullName, password } = authFormValues;
|
|
1035
1165
|
if (username && email && fullName && password) {
|
|
@@ -1037,9 +1167,11 @@ const App = () => {
|
|
|
1037
1167
|
const saved = saveUserCredentials(username, fullName, email);
|
|
1038
1168
|
if (saved) {
|
|
1039
1169
|
setUserCredentials({ userId: username, userName: fullName, userEmail: email });
|
|
1040
|
-
setStatusMessage(`Welcome, ${fullName}!`);
|
|
1170
|
+
setStatusMessage(`Welcome back, ${fullName}!`);
|
|
1041
1171
|
setTimeout(() => setStatusMessage(''), 3000);
|
|
1042
|
-
|
|
1172
|
+
setScreen('settings');
|
|
1173
|
+
setSelectedIndex(0);
|
|
1174
|
+
setAuthFormValues({});
|
|
1043
1175
|
} else {
|
|
1044
1176
|
setStatusMessage('Failed to save credentials');
|
|
1045
1177
|
setTimeout(() => setStatusMessage(''), 3000);
|
|
@@ -1083,7 +1215,9 @@ const App = () => {
|
|
|
1083
1215
|
setUserCredentials({ userId: username, userName: fullName, userEmail: email });
|
|
1084
1216
|
setStatusMessage(`Account created! Welcome, ${fullName}!`);
|
|
1085
1217
|
setTimeout(() => setStatusMessage(''), 3000);
|
|
1086
|
-
|
|
1218
|
+
setScreen('settings');
|
|
1219
|
+
setSelectedIndex(0);
|
|
1220
|
+
setAuthFormValues({});
|
|
1087
1221
|
} else {
|
|
1088
1222
|
setStatusMessage('Failed to save credentials');
|
|
1089
1223
|
setTimeout(() => setStatusMessage(''), 3000);
|
|
@@ -1098,6 +1232,13 @@ const App = () => {
|
|
|
1098
1232
|
setApiKeyInput(value);
|
|
1099
1233
|
};
|
|
1100
1234
|
|
|
1235
|
+
const handleApiKeyNextField = () => {
|
|
1236
|
+
// Move from Service Name (0) to API Key (1)
|
|
1237
|
+
if (apiKeyFieldIndex === 0) {
|
|
1238
|
+
setApiKeyFieldIndex(1);
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1241
|
+
|
|
1101
1242
|
const handleApiKeyFormSubmit = () => {
|
|
1102
1243
|
const serviceName = isEditingExisting ? editingServiceName : serviceNameInput.trim();
|
|
1103
1244
|
const apiKey = apiKeyInput.trim();
|
|
@@ -1136,6 +1277,7 @@ const App = () => {
|
|
|
1136
1277
|
setServiceNameInput('');
|
|
1137
1278
|
setApiKeyInput('');
|
|
1138
1279
|
setIsEditingExisting(false);
|
|
1280
|
+
setApiKeyFieldIndex(0);
|
|
1139
1281
|
setScreen('apiKeysManagement');
|
|
1140
1282
|
setSelectedIndex(0);
|
|
1141
1283
|
} else {
|
|
@@ -1161,12 +1303,13 @@ const App = () => {
|
|
|
1161
1303
|
{screen === 'gpuCountSelection' && <GpuCountSelection selectedIndex={selectedIndex} gpuType={config.gpuType} />}
|
|
1162
1304
|
{screen === 'confirmation' && <Confirmation config={config} />}
|
|
1163
1305
|
{screen === 'authChoice' && <AuthChoice selectedIndex={selectedIndex} />}
|
|
1164
|
-
{screen === 'login' && <LoginForm values={authFormValues} onInput={handleAuthFormInput} onSubmit={handleLoginSubmit} />}
|
|
1165
|
-
{screen === 'register' && <RegisterForm values={authFormValues} onInput={handleAuthFormInput} onSubmit={handleRegisterSubmit} />}
|
|
1306
|
+
{screen === 'login' && <LoginForm values={authFormValues} onInput={handleAuthFormInput} onSubmit={handleLoginSubmit} onNextField={handleAuthNextField} focusedFieldIndex={authFieldIndex} />}
|
|
1307
|
+
{screen === 'register' && <RegisterForm values={authFormValues} onInput={handleAuthFormInput} onSubmit={handleRegisterSubmit} onNextField={handleAuthNextField} focusedFieldIndex={authFieldIndex} />}
|
|
1166
1308
|
{screen === 'sandboxList' && <SandboxList sandboxes={sandboxes} selectedIndex={selectedIndex} />}
|
|
1167
1309
|
{screen === 'sandboxLogs' && viewingSandbox && <SandboxLogs sandbox={viewingSandbox} />}
|
|
1310
|
+
{screen === 'settings' && <Settings userCredentials={userCredentials} selectedIndex={selectedIndex} />}
|
|
1168
1311
|
{screen === 'apiKeysManagement' && <ApiKeysManagement apiKeys={apiKeys} selectedIndex={selectedIndex} />}
|
|
1169
|
-
{screen === 'apiKeyForm' && <ApiKeyForm serviceName={serviceNameInput} apiKey={apiKeyInput} onServiceInput={handleServiceNameInput} onKeyInput={handleApiKeyInput} onSubmit={handleApiKeyFormSubmit} isEditing={isEditingExisting} />}
|
|
1312
|
+
{screen === 'apiKeyForm' && <ApiKeyForm serviceName={serviceNameInput} apiKey={apiKeyInput} onServiceInput={handleServiceNameInput} onKeyInput={handleApiKeyInput} onSubmit={handleApiKeyFormSubmit} onNextField={handleApiKeyNextField} isEditing={isEditingExisting} focusedFieldIndex={apiKeyFieldIndex} />}
|
|
1170
1313
|
</box>
|
|
1171
1314
|
);
|
|
1172
1315
|
};
|