mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge branch 'develop' into info-box-army-management
This commit is contained in:
commit
317183e00d
@ -89,6 +89,8 @@
|
|||||||
"vcmi.adventureOptions.borderScroll.help" : "{Border Scrolling}\n\nScroll adventure map when cursor is adjacent to window edge. Can be disabled by holding down CTRL key.",
|
"vcmi.adventureOptions.borderScroll.help" : "{Border Scrolling}\n\nScroll adventure map when cursor is adjacent to window edge. Can be disabled by holding down CTRL key.",
|
||||||
"vcmi.adventureOptions.infoBarCreatureManagement.hover" : "Info Panel Creature Management",
|
"vcmi.adventureOptions.infoBarCreatureManagement.hover" : "Info Panel Creature Management",
|
||||||
"vcmi.adventureOptions.infoBarCreatureManagement.help" : "{Info Panel Creature Management}\n\nAllows rearranging creatures in info panel instead of cycling between default components",
|
"vcmi.adventureOptions.infoBarCreatureManagement.help" : "{Info Panel Creature Management}\n\nAllows rearranging creatures in info panel instead of cycling between default components",
|
||||||
|
"vcmi.adventureOptions.leftButtonDrag.hover" : "Left Click Drag Map",
|
||||||
|
"vcmi.adventureOptions.leftButtonDrag.help" : "{Left Click Drag Map}\n\nWhen enabled, moving mouse with left button pressed will drag adventure map view",
|
||||||
"vcmi.adventureOptions.mapScrollSpeed1.hover": "",
|
"vcmi.adventureOptions.mapScrollSpeed1.hover": "",
|
||||||
"vcmi.adventureOptions.mapScrollSpeed5.hover": "",
|
"vcmi.adventureOptions.mapScrollSpeed5.hover": "",
|
||||||
"vcmi.adventureOptions.mapScrollSpeed6.hover": "",
|
"vcmi.adventureOptions.mapScrollSpeed6.hover": "",
|
||||||
|
@ -68,6 +68,8 @@
|
|||||||
"vcmi.adventureOptions.showGrid.help" : "{Показувати сітку}\n\n Відображає сітку, що показує межі між клітинками на мапі пригод.",
|
"vcmi.adventureOptions.showGrid.help" : "{Показувати сітку}\n\n Відображає сітку, що показує межі між клітинками на мапі пригод.",
|
||||||
"vcmi.adventureOptions.borderScroll.hover" : "Прокрутка по краю",
|
"vcmi.adventureOptions.borderScroll.hover" : "Прокрутка по краю",
|
||||||
"vcmi.adventureOptions.borderScroll.help" : "{{Прокрутка по краю}\n\nПрокручувати мапу пригод, коли курсор знаходиться біля краю вікна. Цю функцію можна вимкнути, утримуючи клавішу CTRL.",
|
"vcmi.adventureOptions.borderScroll.help" : "{{Прокрутка по краю}\n\nПрокручувати мапу пригод, коли курсор знаходиться біля краю вікна. Цю функцію можна вимкнути, утримуючи клавішу CTRL.",
|
||||||
|
"vcmi.adventureOptions.leftButtonDrag.hover" : "Переміщення мапи лівою кнопкою",
|
||||||
|
"vcmi.adventureOptions.leftButtonDrag.help" : "{Переміщення мапи лівою кнопкою}\n\nЯкщо увімкнено, переміщення миші з натиснутою лівою кнопкою буде перетягувати мапу пригод",
|
||||||
"vcmi.adventureOptions.mapScrollSpeed1.hover": "",
|
"vcmi.adventureOptions.mapScrollSpeed1.hover": "",
|
||||||
"vcmi.adventureOptions.mapScrollSpeed5.hover": "",
|
"vcmi.adventureOptions.mapScrollSpeed5.hover": "",
|
||||||
"vcmi.adventureOptions.mapScrollSpeed6.hover": "",
|
"vcmi.adventureOptions.mapScrollSpeed6.hover": "",
|
||||||
|
@ -15,13 +15,20 @@ public class LanguageSettingDialog extends LauncherSettingDialog<String>
|
|||||||
static
|
static
|
||||||
{
|
{
|
||||||
AVAILABLE_LANGUAGES.add("english");
|
AVAILABLE_LANGUAGES.add("english");
|
||||||
|
AVAILABLE_LANGUAGES.add("czech");
|
||||||
AVAILABLE_LANGUAGES.add("chinese");
|
AVAILABLE_LANGUAGES.add("chinese");
|
||||||
|
AVAILABLE_LANGUAGES.add("finnish");
|
||||||
AVAILABLE_LANGUAGES.add("french");
|
AVAILABLE_LANGUAGES.add("french");
|
||||||
AVAILABLE_LANGUAGES.add("german");
|
AVAILABLE_LANGUAGES.add("german");
|
||||||
|
AVAILABLE_LANGUAGES.add("hungarian");
|
||||||
|
AVAILABLE_LANGUAGES.add("italian");
|
||||||
AVAILABLE_LANGUAGES.add("korean");
|
AVAILABLE_LANGUAGES.add("korean");
|
||||||
AVAILABLE_LANGUAGES.add("polish");
|
AVAILABLE_LANGUAGES.add("polish");
|
||||||
|
AVAILABLE_LANGUAGES.add("portuguese");
|
||||||
AVAILABLE_LANGUAGES.add("russian");
|
AVAILABLE_LANGUAGES.add("russian");
|
||||||
AVAILABLE_LANGUAGES.add("spanish");
|
AVAILABLE_LANGUAGES.add("spanish");
|
||||||
|
AVAILABLE_LANGUAGES.add("swedish");
|
||||||
|
AVAILABLE_LANGUAGES.add("turkish");
|
||||||
AVAILABLE_LANGUAGES.add("ukrainian");
|
AVAILABLE_LANGUAGES.add("ukrainian");
|
||||||
AVAILABLE_LANGUAGES.add("other_cp1250");
|
AVAILABLE_LANGUAGES.add("other_cp1250");
|
||||||
AVAILABLE_LANGUAGES.add("other_cp1251");
|
AVAILABLE_LANGUAGES.add("other_cp1251");
|
||||||
|
@ -86,7 +86,7 @@ BattleWindow::BattleWindow(BattleInterface & owner):
|
|||||||
else
|
else
|
||||||
tacticPhaseEnded();
|
tacticPhaseEnded();
|
||||||
|
|
||||||
addUsedEvents(KEYBOARD);
|
addUsedEvents(LCLICK | KEYBOARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleWindow::createQueue()
|
void BattleWindow::createQueue()
|
||||||
@ -204,6 +204,16 @@ void BattleWindow::keyPressed(EShortcut key)
|
|||||||
InterfaceObjectConfigurable::keyPressed(key);
|
InterfaceObjectConfigurable::keyPressed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleWindow::clickPressed(const Point & cursorPosition)
|
||||||
|
{
|
||||||
|
if (owner.openingPlaying())
|
||||||
|
{
|
||||||
|
owner.openingEnd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InterfaceObjectConfigurable::clickPressed(cursorPosition);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleWindow::tacticPhaseStarted()
|
void BattleWindow::tacticPhaseStarted()
|
||||||
{
|
{
|
||||||
auto menuBattle = widget<CIntObject>("menuBattle");
|
auto menuBattle = widget<CIntObject>("menuBattle");
|
||||||
|
@ -86,6 +86,7 @@ public:
|
|||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
void keyPressed(EShortcut key) override;
|
void keyPressed(EShortcut key) override;
|
||||||
bool captureThisKey(EShortcut key) override;
|
bool captureThisKey(EShortcut key) override;
|
||||||
|
void clickPressed(const Point & cursorPosition) override;
|
||||||
void show(Canvas & to) override;
|
void show(Canvas & to) override;
|
||||||
void showAll(Canvas & to) override;
|
void showAll(Canvas & to) override;
|
||||||
|
|
||||||
|
@ -29,11 +29,12 @@ MapViewActions::MapViewActions(MapView & owner, const std::shared_ptr<MapViewMod
|
|||||||
: model(model)
|
: model(model)
|
||||||
, owner(owner)
|
, owner(owner)
|
||||||
, pinchZoomFactor(1.0)
|
, pinchZoomFactor(1.0)
|
||||||
|
, dragActive(false)
|
||||||
{
|
{
|
||||||
pos.w = model->getPixelsVisibleDimensions().x;
|
pos.w = model->getPixelsVisibleDimensions().x;
|
||||||
pos.h = model->getPixelsVisibleDimensions().y;
|
pos.h = model->getPixelsVisibleDimensions().y;
|
||||||
|
|
||||||
addUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER | MOVE | WHEEL);
|
addUsedEvents(LCLICK | SHOW_POPUP | DRAG | GESTURE | HOVER | MOVE | WHEEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewActions::setContext(const std::shared_ptr<IMapRendererContext> & context)
|
void MapViewActions::setContext(const std::shared_ptr<IMapRendererContext> & context)
|
||||||
@ -43,10 +44,32 @@ void MapViewActions::setContext(const std::shared_ptr<IMapRendererContext> & con
|
|||||||
|
|
||||||
void MapViewActions::clickPressed(const Point & cursorPosition)
|
void MapViewActions::clickPressed(const Point & cursorPosition)
|
||||||
{
|
{
|
||||||
int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
|
if (!settings["adventure"]["leftButtonDrag"].Bool())
|
||||||
|
{
|
||||||
|
int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
|
||||||
|
|
||||||
if(context->isInMap(tile))
|
if(context->isInMap(tile))
|
||||||
adventureInt->onTileLeftClicked(tile);
|
adventureInt->onTileLeftClicked(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewActions::clickReleased(const Point & cursorPosition)
|
||||||
|
{
|
||||||
|
if (!dragActive && settings["adventure"]["leftButtonDrag"].Bool())
|
||||||
|
{
|
||||||
|
int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
|
||||||
|
|
||||||
|
if(context->isInMap(tile))
|
||||||
|
adventureInt->onTileLeftClicked(tile);
|
||||||
|
}
|
||||||
|
dragActive = false;
|
||||||
|
dragDistance = Point(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewActions::clickCancel(const Point & cursorPosition)
|
||||||
|
{
|
||||||
|
dragActive = false;
|
||||||
|
dragDistance = Point(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewActions::showPopupWindow(const Point & cursorPosition)
|
void MapViewActions::showPopupWindow(const Point & cursorPosition)
|
||||||
@ -67,6 +90,17 @@ void MapViewActions::wheelScrolled(int distance)
|
|||||||
adventureInt->hotkeyZoom(distance * 4);
|
adventureInt->hotkeyZoom(distance * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapViewActions::mouseDragged(const Point & cursorPosition, const Point & lastUpdateDistance)
|
||||||
|
{
|
||||||
|
dragDistance += lastUpdateDistance;
|
||||||
|
|
||||||
|
if (dragDistance.length() > 16)
|
||||||
|
dragActive = true;
|
||||||
|
|
||||||
|
if (dragActive && settings["adventure"]["leftButtonDrag"].Bool())
|
||||||
|
owner.onMapSwiped(lastUpdateDistance);
|
||||||
|
}
|
||||||
|
|
||||||
void MapViewActions::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
|
void MapViewActions::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
|
||||||
{
|
{
|
||||||
owner.onMapSwiped(lastUpdateDistance);
|
owner.onMapSwiped(lastUpdateDistance);
|
||||||
|
@ -22,7 +22,9 @@ class MapViewActions : public CIntObject
|
|||||||
std::shared_ptr<MapViewModel> model;
|
std::shared_ptr<MapViewModel> model;
|
||||||
std::shared_ptr<IMapRendererContext> context;
|
std::shared_ptr<IMapRendererContext> context;
|
||||||
|
|
||||||
|
Point dragDistance;
|
||||||
double pinchZoomFactor;
|
double pinchZoomFactor;
|
||||||
|
bool dragActive;
|
||||||
|
|
||||||
void handleHover(const Point & cursorPosition);
|
void handleHover(const Point & cursorPosition);
|
||||||
|
|
||||||
@ -32,11 +34,14 @@ public:
|
|||||||
void setContext(const std::shared_ptr<IMapRendererContext> & context);
|
void setContext(const std::shared_ptr<IMapRendererContext> & context);
|
||||||
|
|
||||||
void clickPressed(const Point & cursorPosition) override;
|
void clickPressed(const Point & cursorPosition) override;
|
||||||
|
void clickReleased(const Point & cursorPosition) override;
|
||||||
|
void clickCancel(const Point & cursorPosition) override;
|
||||||
void showPopupWindow(const Point & cursorPosition) override;
|
void showPopupWindow(const Point & cursorPosition) override;
|
||||||
void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
|
void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
|
||||||
void gesturePinch(const Point & centerPosition, double lastUpdateFactor) override;
|
void gesturePinch(const Point & centerPosition, double lastUpdateFactor) override;
|
||||||
void hover(bool on) override;
|
void hover(bool on) override;
|
||||||
void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
|
void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
|
||||||
void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override;
|
void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override;
|
||||||
|
void mouseDragged(const Point & cursorPosition, const Point & lastUpdateDistance) override;
|
||||||
void wheelScrolled(int distance) override;
|
void wheelScrolled(int distance) override;
|
||||||
};
|
};
|
||||||
|
@ -36,6 +36,14 @@ AdventureOptionsTab::AdventureOptionsTab()
|
|||||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||||
setRedrawParent(true);
|
setRedrawParent(true);
|
||||||
|
|
||||||
|
#ifdef VCMI_MOBILE
|
||||||
|
addConditional("mobile", true);
|
||||||
|
addConditional("desktop", false);
|
||||||
|
#else
|
||||||
|
addConditional("mobile", false);
|
||||||
|
addConditional("desktop", true);
|
||||||
|
#endif
|
||||||
|
|
||||||
const JsonNode config(ResourceID("config/widgets/settings/adventureOptionsTab.json"));
|
const JsonNode config(ResourceID("config/widgets/settings/adventureOptionsTab.json"));
|
||||||
addCallback("playerHeroSpeedChanged", [this](int value)
|
addCallback("playerHeroSpeedChanged", [this](int value)
|
||||||
{
|
{
|
||||||
@ -114,6 +122,10 @@ AdventureOptionsTab::AdventureOptionsTab()
|
|||||||
{
|
{
|
||||||
return setBoolSetting("gameTweaks", "infoBarCreatureManagement", value);
|
return setBoolSetting("gameTweaks", "infoBarCreatureManagement", value);
|
||||||
});
|
});
|
||||||
|
addCallback("leftButtonDragChanged", [](bool value)
|
||||||
|
{
|
||||||
|
return setBoolSetting("adventure", "leftButtonDrag", value);
|
||||||
|
});
|
||||||
build(config);
|
build(config);
|
||||||
|
|
||||||
std::shared_ptr<CToggleGroup> playerHeroSpeedToggle = widget<CToggleGroup>("heroMovementSpeedPicker");
|
std::shared_ptr<CToggleGroup> playerHeroSpeedToggle = widget<CToggleGroup>("heroMovementSpeedPicker");
|
||||||
@ -148,4 +160,8 @@ AdventureOptionsTab::AdventureOptionsTab()
|
|||||||
|
|
||||||
std::shared_ptr<CToggleButton> infoBarCreatureManagementCheckbox = widget<CToggleButton>("infoBarCreatureManagementCheckbox");
|
std::shared_ptr<CToggleButton> infoBarCreatureManagementCheckbox = widget<CToggleButton>("infoBarCreatureManagementCheckbox");
|
||||||
infoBarCreatureManagementCheckbox->setSelected(settings["gameTweaks"]["infoBarCreatureManagement"].Bool());
|
infoBarCreatureManagementCheckbox->setSelected(settings["gameTweaks"]["infoBarCreatureManagement"].Bool());
|
||||||
|
|
||||||
|
std::shared_ptr<CToggleButton> leftButtonDragCheckbox = widget<CToggleButton>("leftButtonDragCheckbox");
|
||||||
|
if (leftButtonDragCheckbox)
|
||||||
|
leftButtonDragCheckbox->setSelected(settings["adventure"]["leftButtonDrag"].Bool());
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@
|
|||||||
"language" : {
|
"language" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "Base language of the mod, before applying localizations. By default vcmi assumes English",
|
"description" : "Base language of the mod, before applying localizations. By default vcmi assumes English",
|
||||||
"enum" : [ "czech", "chinese", "english", "french", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian" ]
|
"enum" : [ "czech", "chinese", "english", "finnish", "french", "german", "hungarian", "italian", "korean", "polish", "portuguese", "russian", "spanish", "swedish", "turkish", "ukrainian" ]
|
||||||
},
|
},
|
||||||
"czech" : {
|
"czech" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
@ -164,6 +164,9 @@
|
|||||||
"english" : {
|
"english" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
},
|
},
|
||||||
|
"finnish" : {
|
||||||
|
"$ref" : "#/definitions/localizable"
|
||||||
|
},
|
||||||
"french" : {
|
"french" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
},
|
},
|
||||||
@ -182,12 +185,21 @@
|
|||||||
"polish" : {
|
"polish" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
},
|
},
|
||||||
|
"portuguese" : {
|
||||||
|
"$ref" : "#/definitions/localizable"
|
||||||
|
},
|
||||||
"russian" : {
|
"russian" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
},
|
},
|
||||||
"spanish" : {
|
"spanish" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
},
|
},
|
||||||
|
"swedish" : {
|
||||||
|
"$ref" : "#/definitions/localizable"
|
||||||
|
},
|
||||||
|
"turkish" : {
|
||||||
|
"$ref" : "#/definitions/localizable"
|
||||||
|
},
|
||||||
"ukrainian" : {
|
"ukrainian" : {
|
||||||
"$ref" : "#/definitions/localizable"
|
"$ref" : "#/definitions/localizable"
|
||||||
},
|
},
|
||||||
|
@ -59,12 +59,12 @@
|
|||||||
},
|
},
|
||||||
"language" : {
|
"language" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"enum" : [ "english", "czech", "chinese", "french", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian" ],
|
"enum" : [ "english", "czech", "chinese", "finnish", "french", "german", "hungarian", "italian", "korean", "polish", "portuguese", "russian", "spanish", "swedish", "turkish", "ukrainian" ],
|
||||||
"default" : "english"
|
"default" : "english"
|
||||||
},
|
},
|
||||||
"gameDataLanguage" : {
|
"gameDataLanguage" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"enum" : [ "auto", "english", "czech", "chinese", "french", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
|
"enum" : [ "auto", "english", "czech", "chinese", "finnish", "french", "german", "hungarian", "italian", "korean", "polish", "portuguese", "russian", "spanish", "swedish", "turkish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
|
||||||
"default" : "auto"
|
"default" : "auto"
|
||||||
},
|
},
|
||||||
"lastSave" : {
|
"lastSave" : {
|
||||||
@ -191,7 +191,7 @@
|
|||||||
"type" : "object",
|
"type" : "object",
|
||||||
"additionalProperties" : false,
|
"additionalProperties" : false,
|
||||||
"default" : {},
|
"default" : {},
|
||||||
"required" : [ "heroMoveTime", "enemyMoveTime", "scrollSpeedPixels", "heroReminder", "quickCombat", "objectAnimation", "terrainAnimation", "alwaysSkipCombat", "borderScroll" ],
|
"required" : [ "heroMoveTime", "enemyMoveTime", "scrollSpeedPixels", "heroReminder", "quickCombat", "objectAnimation", "terrainAnimation", "alwaysSkipCombat", "borderScroll", "leftButtonDrag" ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"heroMoveTime" : {
|
"heroMoveTime" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
@ -231,6 +231,10 @@
|
|||||||
"defaultIOS" : false,
|
"defaultIOS" : false,
|
||||||
"defaultAndroid" : false,
|
"defaultAndroid" : false,
|
||||||
"default" : true
|
"default" : true
|
||||||
|
},
|
||||||
|
"leftButtonDrag" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"default" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -340,6 +340,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "vcmi.adventureOptions.borderScroll.hover"
|
"text": "vcmi.adventureOptions.borderScroll.hover"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "vcmi.adventureOptions.leftButtonDrag.hover",
|
||||||
|
"created" : "desktop"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -378,6 +382,12 @@
|
|||||||
"name": "infoBarCreatureManagementCheckbox",
|
"name": "infoBarCreatureManagementCheckbox",
|
||||||
"help": "vcmi.adventureOptions.infoBarCreatureManagement",
|
"help": "vcmi.adventureOptions.infoBarCreatureManagement",
|
||||||
"callback": "infoBarCreatureManagementChanged"
|
"callback": "infoBarCreatureManagementChanged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "leftButtonDragCheckbox",
|
||||||
|
"help": "vcmi.adventureOptions.leftButtonDrag",
|
||||||
|
"callback": "leftButtonDragChanged",
|
||||||
|
"created" : "desktop"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user