diff options
Diffstat (limited to 'externals/qhexedit/qhexedit_p.cpp')
-rw-r--r-- | externals/qhexedit/qhexedit_p.cpp | 857 |
1 files changed, 0 insertions, 857 deletions
diff --git a/externals/qhexedit/qhexedit_p.cpp b/externals/qhexedit/qhexedit_p.cpp deleted file mode 100644 index 2a6885de8..000000000 --- a/externals/qhexedit/qhexedit_p.cpp +++ /dev/null @@ -1,857 +0,0 @@ -#include "qhexedit_p.h" -#include "commands.h" - -const int HEXCHARS_IN_LINE = 47; -const int GAP_ADR_HEX = 10; -const int GAP_HEX_ASCII = 16; -const int BYTES_PER_LINE = 16; - -QHexEditPrivate::QHexEditPrivate(QScrollArea *parent) : QWidget(parent) -{ - _undoStack = new QUndoStack(this); - - _scrollArea = parent; - setAddressWidth(4); - setAddressOffset(0); - setAddressArea(true); - setAsciiArea(true); - setHighlighting(true); - setOverwriteMode(true); - setReadOnly(false); - setAddressAreaColor(QColor(0xd4, 0xd4, 0xd4, 0xff)); - setHighlightingColor(QColor(0xff, 0xff, 0x99, 0xff)); - setSelectionColor(QColor(0x6d, 0x9e, 0xff, 0xff)); - setFont(QFont("Courier", 10)); - - _size = 0; - resetSelection(0); - - setFocusPolicy(Qt::StrongFocus); - - connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); - _cursorTimer.setInterval(500); - _cursorTimer.start(); -} - -void QHexEditPrivate::setAddressOffset(int offset) -{ - _xData.setAddressOffset(offset); - adjust(); -} - -int QHexEditPrivate::addressOffset() -{ - return _xData.addressOffset(); -} - -void QHexEditPrivate::setData(const QByteArray &data) -{ - _xData.setData(data); - _undoStack->clear(); - adjust(); - setCursorPos(0); -} - -QByteArray QHexEditPrivate::data() -{ - return _xData.data(); -} - -void QHexEditPrivate::setAddressAreaColor(const QColor &color) -{ - _addressAreaColor = color; - update(); -} - -QColor QHexEditPrivate::addressAreaColor() -{ - return _addressAreaColor; -} - -void QHexEditPrivate::setHighlightingColor(const QColor &color) -{ - _highlightingColor = color; - update(); -} - -QColor QHexEditPrivate::highlightingColor() -{ - return _highlightingColor; -} - -void QHexEditPrivate::setSelectionColor(const QColor &color) -{ - _selectionColor = color; - update(); -} - -QColor QHexEditPrivate::selectionColor() -{ - return _selectionColor; -} - -void QHexEditPrivate::setReadOnly(bool readOnly) -{ - _readOnly = readOnly; -} - -bool QHexEditPrivate::isReadOnly() -{ - return _readOnly; -} - -XByteArray & QHexEditPrivate::xData() -{ - return _xData; -} - -int QHexEditPrivate::indexOf(const QByteArray & ba, int from) -{ - if (from > (_xData.data().length() - 1)) - from = _xData.data().length() - 1; - int idx = _xData.data().indexOf(ba, from); - if (idx > -1) - { - int curPos = idx*2; - setCursorPos(curPos + ba.length()*2); - resetSelection(curPos); - setSelection(curPos + ba.length()*2); - ensureVisible(); - } - return idx; -} - -void QHexEditPrivate::insert(int index, const QByteArray & ba) -{ - if (ba.length() > 0) - { - if (_overwriteMode) - { - QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length()); - _undoStack->push(arrayCommand); - emit dataChanged(); - } - else - { - QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::insert, index, ba, ba.length()); - _undoStack->push(arrayCommand); - emit dataChanged(); - } - } -} - -void QHexEditPrivate::insert(int index, char ch) -{ - QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::insert, index, ch); - _undoStack->push(charCommand); - emit dataChanged(); -} - -int QHexEditPrivate::lastIndexOf(const QByteArray & ba, int from) -{ - from -= ba.length(); - if (from < 0) - from = 0; - int idx = _xData.data().lastIndexOf(ba, from); - if (idx > -1) - { - int curPos = idx*2; - setCursorPos(curPos); - resetSelection(curPos); - setSelection(curPos + ba.length()*2); - ensureVisible(); - } - return idx; -} - -void QHexEditPrivate::remove(int index, int len) -{ - if (len > 0) - { - if (len == 1) - { - if (_overwriteMode) - { - QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::replace, index, char(0)); - _undoStack->push(charCommand); - emit dataChanged(); - } - else - { - QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::remove, index, char(0)); - _undoStack->push(charCommand); - emit dataChanged(); - } - } - else - { - QByteArray ba = QByteArray(len, char(0)); - if (_overwriteMode) - { - QUndoCommand *arrayCommand = new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length()); - _undoStack->push(arrayCommand); - emit dataChanged(); - } - else - { - QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::remove, index, ba, len); - _undoStack->push(arrayCommand); - emit dataChanged(); - } - } - } -} - -void QHexEditPrivate::replace(int index, char ch) -{ - QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::replace, index, ch); - _undoStack->push(charCommand); - resetSelection(); - emit dataChanged(); -} - -void QHexEditPrivate::replace(int index, const QByteArray & ba) -{ - QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length()); - _undoStack->push(arrayCommand); - resetSelection(); - emit dataChanged(); -} - -void QHexEditPrivate::replace(int pos, int len, const QByteArray &after) -{ - QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::replace, pos, after, len); - _undoStack->push(arrayCommand); - resetSelection(); - emit dataChanged(); -} - -void QHexEditPrivate::setAddressArea(bool addressArea) -{ - _addressArea = addressArea; - adjust(); - - setCursorPos(_cursorPosition); -} - -void QHexEditPrivate::setAddressWidth(int addressWidth) -{ - _xData.setAddressWidth(addressWidth); - - setCursorPos(_cursorPosition); -} - -void QHexEditPrivate::setAsciiArea(bool asciiArea) -{ - _asciiArea = asciiArea; - adjust(); -} - -void QHexEditPrivate::setFont(const QFont &font) -{ - QWidget::setFont(font); - adjust(); -} - -void QHexEditPrivate::setHighlighting(bool mode) -{ - _highlighting = mode; - update(); -} - -void QHexEditPrivate::setOverwriteMode(bool overwriteMode) -{ - _overwriteMode = overwriteMode; -} - -bool QHexEditPrivate::overwriteMode() -{ - return _overwriteMode; -} - -void QHexEditPrivate::redo() -{ - _undoStack->redo(); - emit dataChanged(); - setCursorPos(_cursorPosition); - update(); -} - -void QHexEditPrivate::undo() -{ - _undoStack->undo(); - emit dataChanged(); - setCursorPos(_cursorPosition); - update(); -} - -QString QHexEditPrivate::toRedableString() -{ - return _xData.toRedableString(); -} - - -QString QHexEditPrivate::selectionToReadableString() -{ - return _xData.toRedableString(getSelectionBegin(), getSelectionEnd()); -} - -void QHexEditPrivate::keyPressEvent(QKeyEvent *event) -{ - int charX = (_cursorX - _xPosHex) / _charWidth; - int posX = (charX / 3) * 2 + (charX % 3); - int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2; - - -/*****************************************************************************/ -/* Cursor movements */ -/*****************************************************************************/ - - if (event->matches(QKeySequence::MoveToNextChar)) - { - setCursorPos(_cursorPosition + 1); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToPreviousChar)) - { - setCursorPos(_cursorPosition - 1); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToEndOfLine)) - { - setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToStartOfLine)) - { - setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToPreviousLine)) - { - setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToNextLine)) - { - setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - - if (event->matches(QKeySequence::MoveToNextPage)) - { - setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToPreviousPage)) - { - setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToEndOfDocument)) - { - setCursorPos(_xData.size() * 2); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToStartOfDocument)) - { - setCursorPos(0); - resetSelection(_cursorPosition); - } - -/*****************************************************************************/ -/* Select commands */ -/*****************************************************************************/ - if (event->matches(QKeySequence::SelectAll)) - { - resetSelection(0); - setSelection(2*_xData.size() + 1); - } - if (event->matches(QKeySequence::SelectNextChar)) - { - int pos = _cursorPosition + 1; - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectPreviousChar)) - { - int pos = _cursorPosition - 1; - setSelection(pos); - setCursorPos(pos); - } - if (event->matches(QKeySequence::SelectEndOfLine)) - { - int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectStartOfLine)) - { - int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectPreviousLine)) - { - int pos = _cursorPosition - (2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectNextLine)) - { - int pos = _cursorPosition + (2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - - if (event->matches(QKeySequence::SelectNextPage)) - { - int pos = _cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectPreviousPage)) - { - int pos = _cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectEndOfDocument)) - { - int pos = _xData.size() * 2; - setCursorPos(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectStartOfDocument)) - { - int pos = 0; - setCursorPos(pos); - setSelection(pos); - } - -/*****************************************************************************/ -/* Edit Commands */ -/*****************************************************************************/ -if (!_readOnly) -{ - /* Hex input */ - int key = int(event->text()[0].toLatin1()); - if ((key>='0' && key<='9') || (key>='a' && key <= 'f')) - { - if (getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2*posBa); - resetSelection(2*posBa); - } - - // If insert mode, then insert a byte - if (_overwriteMode == false) - if ((charX % 3) == 0) - { - insert(posBa, char(0)); - } - - // Change content - if (_xData.size() > 0) - { - QByteArray hexValue = _xData.data().mid(posBa, 1).toHex(); - if ((charX % 3) == 0) - hexValue[0] = key; - else - hexValue[1] = key; - - replace(posBa, QByteArray().fromHex(hexValue)[0]); - - setCursorPos(_cursorPosition + 1); - resetSelection(_cursorPosition); - } - } - - /* Cut & Paste */ - if (event->matches(QKeySequence::Cut)) - { - QString result = QString(); - for (int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) - { - result += _xData.data().mid(idx, 1).toHex() + " "; - if ((idx % 16) == 15) - result.append("\n"); - } - remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(result); - setCursorPos(getSelectionBegin()); - resetSelection(getSelectionBegin()); - } - - if (event->matches(QKeySequence::Paste)) - { - QClipboard *clipboard = QApplication::clipboard(); - QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); - insert(_cursorPosition / 2, ba); - setCursorPos(_cursorPosition + 2 * ba.length()); - resetSelection(getSelectionBegin()); - } - - - /* Delete char */ - if (event->matches(QKeySequence::Delete)) - { - if (getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2*posBa); - resetSelection(2*posBa); - } - else - { - if (_overwriteMode) - replace(posBa, char(0)); - else - remove(posBa, 1); - } - } - - /* Backspace */ - if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) - { - if (getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2*posBa); - resetSelection(2*posBa); - } - else - { - if (posBa > 0) - { - if (_overwriteMode) - replace(posBa - 1, char(0)); - else - remove(posBa - 1, 1); - setCursorPos(_cursorPosition - 2); - } - } - } - - /* undo */ - if (event->matches(QKeySequence::Undo)) - { - undo(); - } - - /* redo */ - if (event->matches(QKeySequence::Redo)) - { - redo(); - } - - } - - if (event->matches(QKeySequence::Copy)) - { - QString result = QString(); - for (int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) - { - result += _xData.data().mid(idx, 1).toHex() + " "; - if ((idx % 16) == 15) - result.append('\n'); - } - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(result); - } - - // Switch between insert/overwrite mode - if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) - { - _overwriteMode = !_overwriteMode; - setCursorPos(_cursorPosition); - overwriteModeChanged(_overwriteMode); - } - - ensureVisible(); - update(); -} - -void QHexEditPrivate::mouseMoveEvent(QMouseEvent * event) -{ - _blink = false; - update(); - int actPos = cursorPos(event->pos()); - setCursorPos(actPos); - setSelection(actPos); -} - -void QHexEditPrivate::mousePressEvent(QMouseEvent * event) -{ - _blink = false; - update(); - int cPos = cursorPos(event->pos()); - resetSelection(cPos); - setCursorPos(cPos); -} - -void QHexEditPrivate::paintEvent(QPaintEvent *event) -{ - QPainter painter(this); - - // draw some patterns if needed - painter.fillRect(event->rect(), this->palette().color(QPalette::Base)); - if (_addressArea) - painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor); - if (_asciiArea) - { - int linePos = _xPosAscii - (GAP_HEX_ASCII / 2); - painter.setPen(Qt::gray); - painter.drawLine(linePos, event->rect().top(), linePos, height()); - } - - painter.setPen(this->palette().color(QPalette::WindowText)); - - // calc position - int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE; - if (firstLineIdx < 0) - firstLineIdx = 0; - int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; - if (lastLineIdx > _xData.size()) - lastLineIdx = _xData.size(); - int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; - - // paint address area - if (_addressArea) - { - for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) - { - QString address = QString("%1") - .arg(lineIdx + _xData.addressOffset(), _xData.realAddressNumbers(), 16, QChar('0')); - painter.drawText(_xPosAdr, yPos, address); - } - } - - // paint hex area - QByteArray hexBa(_xData.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); - QBrush highLighted = QBrush(_highlightingColor); - QPen colHighlighted = QPen(this->palette().color(QPalette::WindowText)); - QBrush selected = QBrush(_selectionColor); - QPen colSelected = QPen(Qt::white); - QPen colStandard = QPen(this->palette().color(QPalette::WindowText)); - - painter.setBackgroundMode(Qt::TransparentMode); - - for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) - { - QByteArray hex; - int xPos = _xPosHex; - for (int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++) - { - int posBa = lineIdx + colIdx; - if ((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa)) - { - painter.setBackground(selected); - painter.setBackgroundMode(Qt::OpaqueMode); - painter.setPen(colSelected); - } - else - { - if (_highlighting) - { - // hilight diff bytes - painter.setBackground(highLighted); - if (_xData.dataChanged(posBa)) - { - painter.setPen(colHighlighted); - painter.setBackgroundMode(Qt::OpaqueMode); - } - else - { - painter.setPen(colStandard); - painter.setBackgroundMode(Qt::TransparentMode); - } - } - } - - // render hex value - if (colIdx == 0) - { - hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2); - painter.drawText(xPos, yPos, hex); - xPos += 2 * _charWidth; - } else { - hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" "); - painter.drawText(xPos, yPos, hex); - xPos += 3 * _charWidth; - } - - } - } - painter.setBackgroundMode(Qt::TransparentMode); - painter.setPen(this->palette().color(QPalette::WindowText)); - - // paint ascii area - if (_asciiArea) - { - for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) - { - int xPosAscii = _xPosAscii; - for (int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++) - { - painter.drawText(xPosAscii, yPos, _xData.asciiChar(lineIdx + colIdx)); - xPosAscii += _charWidth; - } - } - } - - // paint cursor - if (_blink && !_readOnly && hasFocus()) - { - if (_overwriteMode) - painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText)); - else - painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText)); - } - - if (_size != _xData.size()) - { - _size = _xData.size(); - emit currentSizeChanged(_size); - } -} - -void QHexEditPrivate::setCursorPos(int position) -{ - // delete cursor - _blink = false; - update(); - - // cursor in range? - if (_overwriteMode) - { - if (position > (_xData.size() * 2 - 1)) - position = _xData.size() * 2 - 1; - } else { - if (position > (_xData.size() * 2)) - position = _xData.size() * 2; - } - - if (position < 0) - position = 0; - - // calc position - _cursorPosition = position; - _cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4; - int x = (position % (2 * BYTES_PER_LINE)); - _cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex; - - // immiadately draw cursor - _blink = true; - update(); - emit currentAddressChanged(_cursorPosition/2); -} - -int QHexEditPrivate::cursorPos(QPoint pos) -{ - int result = -1; - // find char under cursor - if ((pos.x() >= _xPosHex) && (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth))) - { - int x = (pos.x() - _xPosHex) / _charWidth; - if ((x % 3) == 0) - x = (x / 3) * 2; - else - x = ((x / 3) * 2) + 1; - int y = ((pos.y() - 3) / _charHeight) * 2 * BYTES_PER_LINE; - result = x + y; - } - return result; -} - -int QHexEditPrivate::cursorPos() -{ - return _cursorPosition; -} - -void QHexEditPrivate::resetSelection() -{ - _selectionBegin = _selectionInit; - _selectionEnd = _selectionInit; -} - -void QHexEditPrivate::resetSelection(int pos) -{ - if (pos < 0) - pos = 0; - pos = pos / 2; - _selectionInit = pos; - _selectionBegin = pos; - _selectionEnd = pos; -} - -void QHexEditPrivate::setSelection(int pos) -{ - if (pos < 0) - pos = 0; - pos = pos / 2; - if (pos >= _selectionInit) - { - _selectionEnd = pos; - _selectionBegin = _selectionInit; - } - else - { - _selectionBegin = pos; - _selectionEnd = _selectionInit; - } -} - -int QHexEditPrivate::getSelectionBegin() -{ - return _selectionBegin; -} - -int QHexEditPrivate::getSelectionEnd() -{ - return _selectionEnd; -} - - -void QHexEditPrivate::updateCursor() -{ - if (_blink) - _blink = false; - else - _blink = true; - update(_cursorX, _cursorY, _charWidth, _charHeight); -} - -void QHexEditPrivate::adjust() -{ - _charWidth = fontMetrics().width(QLatin1Char('9')); - _charHeight = fontMetrics().height(); - - _xPosAdr = 0; - if (_addressArea) - _xPosHex = _xData.realAddressNumbers()*_charWidth + GAP_ADR_HEX; - else - _xPosHex = 0; - _xPosAscii = _xPosHex + HEXCHARS_IN_LINE * _charWidth + GAP_HEX_ASCII; - - // tell QAbstractScollbar, how big we are - setMinimumHeight(((_xData.size()/16 + 1) * _charHeight) + 5); - if(_asciiArea) - setMinimumWidth(_xPosAscii + (BYTES_PER_LINE * _charWidth)); - else - setMinimumWidth(_xPosHex + HEXCHARS_IN_LINE * _charWidth); - - update(); -} - -void QHexEditPrivate::ensureVisible() -{ - // scrolls to cursorx, cusory (which are set by setCursorPos) - // x-margin is 3 pixels, y-margin is half of charHeight - _scrollArea->ensureVisible(_cursorX, _cursorY + _charHeight/2, 3, _charHeight/2 + 2); -} |