parent
							
								
									e20cd71549
								
							
						
					
					
						commit
						063ce31ec6
					
				| 
						 | 
					@ -280,4 +280,20 @@ bool cbInstrFoldDisassembly(int argc, char* argv[])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    GuiFoldDisassembly(start, length);
 | 
					    GuiFoldDisassembly(start, length);
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cbDebugUpdateTitle(int argc, char* argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    duint addr = 0;
 | 
				
			||||||
 | 
					    if(argc > 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(!valfromstring(argv[1], &addr))
 | 
				
			||||||
 | 
					            addr = GetContextDataEx(hActiveThread, UE_CIP);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        addr = GetContextDataEx(hActiveThread, UE_CIP);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    DebugUpdateTitleAsync(addr, false);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,3 +19,4 @@ bool cbInstrAddFavTool(int argc, char* argv[]);
 | 
				
			||||||
bool cbInstrAddFavCmd(int argc, char* argv[]);
 | 
					bool cbInstrAddFavCmd(int argc, char* argv[]);
 | 
				
			||||||
bool cbInstrSetFavToolShortcut(int argc, char* argv[]);
 | 
					bool cbInstrSetFavToolShortcut(int argc, char* argv[]);
 | 
				
			||||||
bool cbInstrFoldDisassembly(int argc, char* argv[]);
 | 
					bool cbInstrFoldDisassembly(int argc, char* argv[]);
 | 
				
			||||||
 | 
					bool cbDebugUpdateTitle(int argc, char* argv[]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,6 +444,49 @@ void updateSEHChainAsync()
 | 
				
			||||||
    updateSEHChainTask.WakeUp();
 | 
					    updateSEHChainTask.WakeUp();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void DebugUpdateTitle(duint disasm_addr, bool analyzeThreadSwitch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char modname[MAX_MODULE_SIZE] = "";
 | 
				
			||||||
 | 
					    char modtext[MAX_MODULE_SIZE * 2] = "";
 | 
				
			||||||
 | 
					    if(!ModNameFromAddr(disasm_addr, modname, true))
 | 
				
			||||||
 | 
					        *modname = 0;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        sprintf_s(modtext, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Module: %s - ")), modname);
 | 
				
			||||||
 | 
					    char threadswitch[256] = "";
 | 
				
			||||||
 | 
					    DWORD currentThreadId = ThreadGetId(hActiveThread);
 | 
				
			||||||
 | 
					    if(analyzeThreadSwitch)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        static DWORD PrevThreadId = 0;
 | 
				
			||||||
 | 
					        if(PrevThreadId == 0)
 | 
				
			||||||
 | 
					            PrevThreadId = fdProcessInfo->dwThreadId; // Initialize to Main Thread
 | 
				
			||||||
 | 
					        if(currentThreadId != PrevThreadId && PrevThreadId != 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            char threadName2[MAX_THREAD_NAME_SIZE] = "";
 | 
				
			||||||
 | 
					            if(!ThreadGetName(PrevThreadId, threadName2) || threadName2[0] == 0)
 | 
				
			||||||
 | 
					                sprintf_s(threadName2, "%X", PrevThreadId);
 | 
				
			||||||
 | 
					            sprintf_s(threadswitch, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", " (switched from %s)")), threadName2);
 | 
				
			||||||
 | 
					            PrevThreadId = currentThreadId;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    char title[deflen] = "";
 | 
				
			||||||
 | 
					    char threadName[MAX_THREAD_NAME_SIZE + 1] = "";
 | 
				
			||||||
 | 
					    if(ThreadGetName(currentThreadId, threadName) && *threadName)
 | 
				
			||||||
 | 
					        strcat_s(threadName, " ");
 | 
				
			||||||
 | 
					    char PIDnumber[64], TIDnumber[64];
 | 
				
			||||||
 | 
					    if(settingboolget("Gui", "PidInHex"))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sprintf_s(PIDnumber, "%X", fdProcessInfo->dwProcessId);
 | 
				
			||||||
 | 
					        sprintf_s(TIDnumber, "%X", currentThreadId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sprintf_s(PIDnumber, "%u", fdProcessInfo->dwProcessId);
 | 
				
			||||||
 | 
					        sprintf_s(TIDnumber, "%u", currentThreadId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "%s - PID: %s - %sThread: %s%s%s")), szBaseFileName, PIDnumber, modtext, threadName, TIDnumber, threadswitch);
 | 
				
			||||||
 | 
					    GuiUpdateWindowTitle(title);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DebugUpdateGui(duint disasm_addr, bool stack)
 | 
					void DebugUpdateGui(duint disasm_addr, bool stack)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(GuiIsUpdateDisabled())
 | 
					    if(GuiIsUpdateDisabled())
 | 
				
			||||||
| 
						 | 
					@ -479,45 +522,7 @@ void DebugUpdateGui(duint disasm_addr, bool stack)
 | 
				
			||||||
        updateCallStackAsync(csp);
 | 
					        updateCallStackAsync(csp);
 | 
				
			||||||
        updateSEHChainAsync();
 | 
					        updateSEHChainAsync();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    char modname[MAX_MODULE_SIZE] = "";
 | 
					    DebugUpdateTitle(disasm_addr, true);
 | 
				
			||||||
    char modtext[MAX_MODULE_SIZE * 2] = "";
 | 
					 | 
				
			||||||
    if(!ModNameFromAddr(disasm_addr, modname, true))
 | 
					 | 
				
			||||||
        *modname = 0;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        sprintf_s(modtext, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Module: %s - ")), modname);
 | 
					 | 
				
			||||||
    char threadswitch[256] = "";
 | 
					 | 
				
			||||||
    DWORD currentThreadId = ThreadGetId(hActiveThread);
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        static DWORD PrevThreadId = 0;
 | 
					 | 
				
			||||||
        if(PrevThreadId == 0)
 | 
					 | 
				
			||||||
            PrevThreadId = fdProcessInfo->dwThreadId; // Initialize to Main Thread
 | 
					 | 
				
			||||||
        if(currentThreadId != PrevThreadId && PrevThreadId != 0)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            char threadName2[MAX_THREAD_NAME_SIZE] = "";
 | 
					 | 
				
			||||||
            if(!ThreadGetName(PrevThreadId, threadName2) || threadName2[0] == 0)
 | 
					 | 
				
			||||||
                sprintf_s(threadName2, "%X", PrevThreadId);
 | 
					 | 
				
			||||||
            sprintf_s(threadswitch, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", " (switched from %s)")), threadName2);
 | 
					 | 
				
			||||||
            PrevThreadId = currentThreadId;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    char title[deflen] = "";
 | 
					 | 
				
			||||||
    char threadName[MAX_THREAD_NAME_SIZE + 1] = "";
 | 
					 | 
				
			||||||
    if(ThreadGetName(currentThreadId, threadName) && *threadName)
 | 
					 | 
				
			||||||
        strcat_s(threadName, " ");
 | 
					 | 
				
			||||||
    //sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "File: %s - PID: %X - %sThread: %s%X%s")), szBaseFileName, fdProcessInfo->dwProcessId, modtext, threadName, currentThreadId, threadswitch);
 | 
					 | 
				
			||||||
    char PIDnumber[64], TIDnumber[64];
 | 
					 | 
				
			||||||
    if(settingboolget("Gui", "PidInHex"))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        sprintf_s(PIDnumber, "%X", fdProcessInfo->dwProcessId);
 | 
					 | 
				
			||||||
        sprintf_s(TIDnumber, "%X", currentThreadId);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        sprintf_s(PIDnumber, "%u", fdProcessInfo->dwProcessId);
 | 
					 | 
				
			||||||
        sprintf_s(TIDnumber, "%u", currentThreadId);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "%s - PID: %s - %sThread: %s%s%s")), szBaseFileName, PIDnumber, modtext, threadName, TIDnumber, threadswitch);
 | 
					 | 
				
			||||||
    GuiUpdateWindowTitle(title);
 | 
					 | 
				
			||||||
    GuiUpdateRegisterView();
 | 
					    GuiUpdateRegisterView();
 | 
				
			||||||
    GuiUpdateDisassemblyView();
 | 
					    GuiUpdateDisassemblyView();
 | 
				
			||||||
    GuiUpdateThreadView();
 | 
					    GuiUpdateThreadView();
 | 
				
			||||||
| 
						 | 
					@ -537,6 +542,12 @@ void DebugUpdateGuiAsync(duint disasm_addr, bool stack)
 | 
				
			||||||
    DebugUpdateGuiTask.WakeUp(disasm_addr, stack);
 | 
					    DebugUpdateGuiTask.WakeUp(disasm_addr, stack);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DebugUpdateTitleAsync(duint disasm_addr, bool analyzeThreadSwitch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static TaskThread_<decltype(&DebugUpdateTitle), duint, bool> DebugUpdateTitleTask(&DebugUpdateTitle);
 | 
				
			||||||
 | 
					    DebugUpdateTitleTask.WakeUp(disasm_addr, analyzeThreadSwitch);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state)
 | 
					void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // call paused routine to clean up various tracing states.
 | 
					    // call paused routine to clean up various tracing states.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ void dbgsetattachevent(HANDLE handle);
 | 
				
			||||||
void dbgsetresumetid(duint tid);
 | 
					void dbgsetresumetid(duint tid);
 | 
				
			||||||
void DebugUpdateGui(duint disasm_addr, bool stack);
 | 
					void DebugUpdateGui(duint disasm_addr, bool stack);
 | 
				
			||||||
void DebugUpdateGuiAsync(duint disasm_addr, bool stack);
 | 
					void DebugUpdateGuiAsync(duint disasm_addr, bool stack);
 | 
				
			||||||
 | 
					void DebugUpdateTitleAsync(duint disasm_addr, bool analyzeThreadSwitch);
 | 
				
			||||||
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state = paused);
 | 
					void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state = paused);
 | 
				
			||||||
void DebugUpdateBreakpointsViewAsync();
 | 
					void DebugUpdateBreakpointsViewAsync();
 | 
				
			||||||
void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump = false);
 | 
					void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump = false);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,6 +402,7 @@ static void registercommands()
 | 
				
			||||||
    dbgcmdnew("AddFavouriteCommand", cbInstrAddFavCmd, false); //add favourite command
 | 
					    dbgcmdnew("AddFavouriteCommand", cbInstrAddFavCmd, false); //add favourite command
 | 
				
			||||||
    dbgcmdnew("AddFavouriteToolShortcut,SetFavouriteToolShortcut", cbInstrSetFavToolShortcut, false); //set favourite tool shortcut
 | 
					    dbgcmdnew("AddFavouriteToolShortcut,SetFavouriteToolShortcut", cbInstrSetFavToolShortcut, false); //set favourite tool shortcut
 | 
				
			||||||
    dbgcmdnew("FoldDisassembly", cbInstrFoldDisassembly, true); //fold disassembly segment
 | 
					    dbgcmdnew("FoldDisassembly", cbInstrFoldDisassembly, true); //fold disassembly segment
 | 
				
			||||||
 | 
					    dbgcmdnew("guiupdatetitle", cbDebugUpdateTitle, true); // set relevant disassembly title
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //misc
 | 
					    //misc
 | 
				
			||||||
    dbgcmdnew("chd", cbInstrChd, false); //Change directory
 | 
					    dbgcmdnew("chd", cbInstrChd, false); //Change directory
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
#include "CodeFolding.h"
 | 
					#include "CodeFolding.h"
 | 
				
			||||||
#include "EncodeMap.h"
 | 
					#include "EncodeMap.h"
 | 
				
			||||||
#include "Bridge.h"
 | 
					#include "Bridge.h"
 | 
				
			||||||
#include "MainWindow.h"
 | 
					 | 
				
			||||||
#include "CachedFontMetrics.h"
 | 
					#include "CachedFontMetrics.h"
 | 
				
			||||||
#include "QBeaEngine.h"
 | 
					#include "QBeaEngine.h"
 | 
				
			||||||
#include "MemoryPage.h"
 | 
					#include "MemoryPage.h"
 | 
				
			||||||
| 
						 | 
					@ -901,7 +900,7 @@ void Disassembly::keyPressEvent(QKeyEvent* event)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ShowDisassemblyPopup(0, 0, 0);
 | 
					        ShowDisassemblyPopup(0, 0, 0);
 | 
				
			||||||
        duint dest = DbgGetBranchDestination(rvaToVa(getInitialSelection()));
 | 
					        duint dest = DbgGetBranchDestination(rvaToVa(getInitialSelection()));
 | 
				
			||||||
        if(!dest)
 | 
					        if(!DbgMemIsValidReadPtr(dest))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        QString cmd = "disasm " + ToPtrString(dest);
 | 
					        QString cmd = "disasm " + ToPtrString(dest);
 | 
				
			||||||
        DbgCmdExec(cmd.toUtf8().constData());
 | 
					        DbgCmdExec(cmd.toUtf8().constData());
 | 
				
			||||||
| 
						 | 
					@ -1780,7 +1779,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
 | 
				
			||||||
            mCurrentVa++;
 | 
					            mCurrentVa++;
 | 
				
			||||||
            newHistory.va = selectionVA;
 | 
					            newHistory.va = selectionVA;
 | 
				
			||||||
            newHistory.tableOffset = selectionTableOffset;
 | 
					            newHistory.tableOffset = selectionTableOffset;
 | 
				
			||||||
            newHistory.windowTitle = MainWindow::windowTitle;
 | 
					 | 
				
			||||||
            mVaHistory.push_back(newHistory);
 | 
					            mVaHistory.push_back(newHistory);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1842,7 +1840,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
 | 
				
			||||||
            //new disassembled address
 | 
					            //new disassembled address
 | 
				
			||||||
            newHistory.va = parVA;
 | 
					            newHistory.va = parVA;
 | 
				
			||||||
            newHistory.tableOffset = getTableOffset();
 | 
					            newHistory.tableOffset = getTableOffset();
 | 
				
			||||||
            newHistory.windowTitle = MainWindow::windowTitle;
 | 
					 | 
				
			||||||
            if(mVaHistory.size())
 | 
					            if(mVaHistory.size())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if(mVaHistory.last().va != parVA) //not 2x the same va in history
 | 
					                if(mVaHistory.last().va != parVA) //not 2x the same va in history
 | 
				
			||||||
| 
						 | 
					@ -1952,7 +1949,7 @@ void Disassembly::historyPrevious()
 | 
				
			||||||
    disassembleAt(va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
 | 
					    disassembleAt(va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update window title
 | 
					    // Update window title
 | 
				
			||||||
    emit updateWindowTitle(mVaHistory.at(mCurrentVa).windowTitle);
 | 
					    DbgCmdExecDirect(QString("guiupdatetitle %1").arg(ToPtrString(va)));
 | 
				
			||||||
    GuiUpdateAllViews();
 | 
					    GuiUpdateAllViews();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1967,7 +1964,7 @@ void Disassembly::historyNext()
 | 
				
			||||||
    disassembleAt(va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
 | 
					    disassembleAt(va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update window title
 | 
					    // Update window title
 | 
				
			||||||
    emit updateWindowTitle(mVaHistory.at(mCurrentVa).windowTitle);
 | 
					    DbgCmdExecDirect(QString("guiupdatetitle %1").arg(ToPtrString(va)));
 | 
				
			||||||
    GuiUpdateAllViews();
 | 
					    GuiUpdateAllViews();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -165,7 +165,6 @@ private:
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        dsint va;
 | 
					        dsint va;
 | 
				
			||||||
        dsint tableOffset;
 | 
					        dsint tableOffset;
 | 
				
			||||||
        QString windowTitle;
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QList<HistoryData> mVaHistory;
 | 
					    QList<HistoryData> mVaHistory;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,8 +53,6 @@
 | 
				
			||||||
#include "UpdateChecker.h"
 | 
					#include "UpdateChecker.h"
 | 
				
			||||||
#include "Tracer/TraceBrowser.h"
 | 
					#include "Tracer/TraceBrowser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString MainWindow::windowTitle = "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MainWindow::MainWindow(QWidget* parent)
 | 
					MainWindow::MainWindow(QWidget* parent)
 | 
				
			||||||
    : QMainWindow(parent),
 | 
					    : QMainWindow(parent),
 | 
				
			||||||
      ui(new Ui::MainWindow)
 | 
					      ui(new Ui::MainWindow)
 | 
				
			||||||
| 
						 | 
					@ -960,12 +958,10 @@ void MainWindow::updateWindowTitleSlot(QString filename)
 | 
				
			||||||
    if(filename.length())
 | 
					    if(filename.length())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        setWindowTitle(filename + QString(" - ") + mWindowMainTitle);
 | 
					        setWindowTitle(filename + QString(" - ") + mWindowMainTitle);
 | 
				
			||||||
        windowTitle = filename;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        setWindowTitle(mWindowMainTitle);
 | 
					        setWindowTitle(mWindowMainTitle);
 | 
				
			||||||
        windowTitle = mWindowMainTitle;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -269,9 +269,6 @@ protected:
 | 
				
			||||||
    void dropEvent(QDropEvent* pEvent);
 | 
					    void dropEvent(QDropEvent* pEvent);
 | 
				
			||||||
    bool event(QEvent* event);
 | 
					    bool event(QEvent* event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    static QString windowTitle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
    void setupLanguagesMenu2();
 | 
					    void setupLanguagesMenu2();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue