timeboxing, save fix, pref tweaks

This commit is contained in:
Damien Elmes 2009-01-05 13:43:36 +09:00
parent 914fc45666
commit bcfb876664
7 changed files with 494 additions and 38 deletions

View file

@ -69,8 +69,10 @@ class Config(dict):
'qaDivider': True,
'splitQA': True,
'sortIndex': 0,
'addZeroSpace': True,
'addZeroSpace': False,
'alternativeTheme': False,
'showStudyScreen': True,
'showStudyOptions': False,
}
for (k,v) in fields.items():
if not self.has_key(k):

View file

@ -19,6 +19,8 @@ from anki.media import rebuildMediaDir
from anki.db import OperationalError
from anki.stdmodels import BasicModel
from anki.hooks import runHook, addHook, removeHook, _hooks
from anki.deck import newCardOrderLabels, newCardSchedulingLabels
from anki.deck import revCardOrderLabels
import anki.latex
import anki.lang
import anki.deck
@ -50,6 +52,7 @@ class AnkiQt(QMainWindow):
self.restoreGeometry(self.config['mainWindowGeom'])
self.setupViews()
self.setupEditor()
self.setupStudyScreen()
self.setupButtons()
self.setupAnchors()
self.setupToolbar()
@ -195,9 +198,9 @@ Please do not file a bug report with Anki.\n\n""")
self.state = state
self.updateTitleBar()
if 'state' != 'noDeck' and state != 'editCurrentFact':
self.showReviewScreen()
self.switchToReviewScreen()
if state == "noDeck":
self.showWelcomeScreen()
self.switchToWelcomeScreen()
self.help.hide()
self.currentCard = None
self.lastCard = None
@ -218,12 +221,17 @@ Please do not file a bug report with Anki.\n\n""")
# if the same card is being shown and it's not
# due yet, give up
return self.moveToState("deckFinished")
if (self.config['showStudyScreen'] and
not self.deck.sessionStartTime):
return self.moveToState("studyScreen")
if self.deck.sessionLimitReached():
return self.moveToState("studyScreen")
self.enableCardMenuItems()
return self.moveToState("showQuestion")
else:
return self.moveToState("deckFinished")
elif state == "deckEmpty":
self.showWelcomeScreen()
self.switchToWelcomeScreen()
self.disableCardMenuItems()
elif state == "deckFinished":
self.deck.s.flush()
@ -250,6 +258,10 @@ Please do not file a bug report with Anki.\n\n""")
self.deck.s.flush()
self.deck.refresh()
return self.moveToState("auto")
elif state == "studyScreen":
self.currentCard = None
self.disableCardMenuItems()
self.showStudyScreen()
self.updateViews(state)
def keyPressEvent(self, evt):
@ -379,16 +391,19 @@ new:
# Main stack
##########################################################################
def showWelcomeScreen(self):
def switchToWelcomeScreen(self):
self.mainWin.mainStack.setCurrentIndex(1)
self.hideButtons()
def showEditScreen(self):
def switchToEditScreen(self):
self.mainWin.mainStack.setCurrentIndex(2)
def showReviewScreen(self):
def switchToStudyScreen(self):
self.mainWin.mainStack.setCurrentIndex(3)
def switchToReviewScreen(self):
self.mainWin.mainStack.setCurrentIndex(4)
# Buttons
##########################################################################
@ -772,9 +787,10 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
return self.onSaveAs()
return
if not self.deck.modifiedSinceSave():
return
return True
self.deck.save()
self.updateTitleBar()
return True
def onSaveAs(self):
"Prompt for a file name, then save."
@ -892,7 +908,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
def showEditor(self):
self.showSaveEditorButton()
self.showEditScreen()
self.switchToEditScreen()
self.editor.setFact(self.currentCard.fact)
def onFactValid(self, fact):
@ -901,6 +917,108 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
def onFactInvalid(self, fact):
self.mainWin.saveEditorButton.setEnabled(False)
# Study screen
##########################################################################
def setupStudyScreen(self):
self.mainWin.newCardOrder.insertItems(
0, QStringList(newCardOrderLabels().values()))
self.mainWin.newCardScheduling.insertItems(
0, QStringList(newCardSchedulingLabels().values()))
self.mainWin.revCardOrder.insertItems(
0, QStringList(revCardOrderLabels().values()))
self.connect(self.mainWin.optionsHelpButton,
SIGNAL("clicked()"),
lambda: QDesktopServices.openUrl(QUrl(
ankiqt.appWiki + "StudyOptions")))
def showStudyScreen(self):
self.switchToStudyScreen()
self.mainWin.optionsButton.setChecked(self.config['showStudyOptions'])
self.mainWin.optionsBox.setShown(self.config['showStudyOptions'])
initial = self.deck.sessionStartTime == 0
if initial or not self.deck.sessionLimitReached():
# deck just opened, or screen triggered manually
top = _("<h1>Welcome back!</h1>")
else:
top = _("<h1>Well done!</h1>")
# top label
h = {}
s = self.deck.getStats()
h['lapsed'] = '<font color=#990000>%s</font>' % s['failed']
h['ret'] = s['rev']
h['new'] = '<font color=#0000ff>%s</font>' % s['new']
h['repsToday'] = '<font color=#007700>%s</font>' % s['dTotal']
h['repsIn5'] = '<font color=#007700>%s</font>' % self.deck.s.scalar(
"select count(*) from reviewHistory where time > :t",
t = time.time() - 300)
h['timeToday'] = '<font color=#007700>%s</font>' % (
anki.utils.fmtTimeSpan(s['dReviewTime'], short=True))
self.mainWin.optionsLabel.setText(top + _("""\
<p>
<table width=300>
<tr><td>
<table>
<tr><td>Reps done today:</td><td align=right><b>%(repsToday)s</b></td></tr>
<tr><td>Reps in last 5 mins:</td><td align=right><b>%(repsIn5)s</b></td></tr>
<tr><td>Total time today:</td><td align=right><b>%(timeToday)s</b></td></tr>
</table></td>
<td><table>
<tr><td>Lapsed due:</td><td align=right><b>%(lapsed)s</b></td></tr>
<tr><td>Retained due:</td><td align=right><b>%(ret)s</b></td></tr>
<tr><td>New due:</td><td align=right><b>%(new)s</b></td></tr>
</table></td></tr></table>""") % h)
# start reviewing button
self.mainWin.buttonStack.setCurrentIndex(3)
self.mainWin.buttonStack.show()
if initial:
self.mainWin.startReviewingButton.setText(_("Start &Reviewing"))
else:
self.mainWin.startReviewingButton.setText(_("Continue &Reviewing"))
self.mainWin.startReviewingButton.setFocus()
self.connect(self.mainWin.startReviewingButton,
SIGNAL("clicked()"),
self.onStartReview)
self.setupStudyOptions()
def setupStudyOptions(self):
self.mainWin.newPerDay.setText(str(self.deck.newCardsPerDay))
self.mainWin.minuteLimit.setText(str(self.deck.sessionTimeLimit/60.0))
self.mainWin.questionLimit.setText(str(self.deck.sessionRepLimit))
self.mainWin.newCardOrder.setCurrentIndex(self.deck.newCardOrder)
self.mainWin.newCardScheduling.setCurrentIndex(self.deck.newCardSpacing)
self.mainWin.revCardOrder.setCurrentIndex(self.deck.revCardOrder)
self.mainWin.delayLapsedCards.setChecked(not self.deck.delay0)
def onStartReview(self):
self.config['showStudyOptions'] = self.mainWin.optionsButton.isChecked()
try:
self.deck.newCardsPerDay = int(self.mainWin.newPerDay.text())
self.deck.sessionTimeLimit = float(
self.mainWin.minuteLimit.text()) * 60
self.deck.sessionRepLimit = int(self.mainWin.questionLimit.text())
except (ValueError, OverflowError):
pass
self.deck.newCardOrder = self.mainWin.newCardOrder.currentIndex()
self.deck.newCardSpacing = self.mainWin.newCardScheduling.currentIndex()
self.deck.revCardOrder = self.mainWin.revCardOrder.currentIndex()
# avoid clobbering the user's settings if they haven't changed
if self.deck.delay0 and self.mainWin.delayLapsedCards.isChecked():
self.deck.delay0 = 0
elif (not self.deck.delay0 and
not self.mainWin.delayLapsedCards.isChecked()):
self.deck.delay0 = 600
if not self.deck.sessionStartTime or self.deck.sessionLimitReached():
self.deck.startSession()
self.deck.flushMod()
self.moveToState("getQuestion")
def onStudyOptions(self):
if self.state == "studyScreen":
self.onStartReview()
else:
self.moveToState("studyScreen")
# Toolbar
##########################################################################
@ -917,8 +1035,9 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
mw.toolBar.addAction(mw.actionAddcards)
mw.toolBar.addAction(mw.actionEditCurrent)
mw.toolBar.addAction(mw.actionEditdeck)
mw.toolBar.addAction(mw.actionMarkCard)
mw.toolBar.addAction(mw.actionGraphs)
mw.toolBar.addAction(mw.actionStudyOptions)
mw.toolBar.addAction(mw.actionMarkCard)
mw.toolBar.addAction(mw.actionRepeatAudio)
self.addToolBar(Qt.TopToolBarArea, mw.toolBar)
mw.toolBar.setIconSize(QSize(self.config['iconSize'],
@ -1248,7 +1367,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
self.connect(self.syncThread, SIGNAL("updateSyncProgress"), self.updateSyncProgress)
self.connect(self.syncThread, SIGNAL("bulkSyncFailed"), self.bulkSyncFailed)
self.syncThread.start()
self.showWelcomeScreen()
self.switchToWelcomeScreen()
self.setEnabled(False)
while not self.syncThread.isFinished():
self.app.processEvents()
@ -1353,6 +1472,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
"Kstats",
"Cstats",
"ActiveTags",
"StudyOptions",
)
deckRelatedMenus = (
@ -1413,6 +1533,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
self.connect(m.actionGetMoreDecks, s, self.onGetMoreDecks)
self.connect(m.actionCacheLatex, s, self.onCacheLatex)
self.connect(m.actionUncacheLatex, s, self.onUncacheLatex)
self.connect(m.actionStudyOptions, s, self.onStudyOptions)
def enableDeckMenuItems(self, enabled=True):
"setEnabled deck-related items."

View file

@ -165,7 +165,8 @@ class Preferences(QDialog):
self.dialog.showToolbar.setChecked(self.config['showToolbar'])
self.dialog.tallButtons.setChecked(
self.config['easeButtonHeight'] != 'standard')
self.dialog.suppressEstimates.setChecked(self.config['suppressEstimates'])
self.dialog.showEstimates.setChecked(not self.config['suppressEstimates'])
self.dialog.showStudyOptions.setChecked(self.config['showStudyScreen'])
self.dialog.showLastCardInterval.setChecked(self.config['showLastCardInterval'])
self.dialog.showLastCardContent.setChecked(self.config['showLastCardContent'])
self.dialog.showTray.setChecked(self.config['showTrayIcon'])
@ -188,7 +189,8 @@ class Preferences(QDialog):
self.config['showLastCardContent'] = self.dialog.showLastCardContent.isChecked()
self.config['showTrayIcon'] = self.dialog.showTray.isChecked()
self.config['showTimer'] = self.dialog.showTimer.isChecked()
self.config['suppressEstimates'] = self.dialog.suppressEstimates.isChecked()
self.config['suppressEstimates'] = not self.dialog.showEstimates.isChecked()
self.config['showStudyScreen'] = self.dialog.showStudyOptions.isChecked()
self.config['simpleToolbar'] = self.dialog.simpleToolbar.isChecked()
self.config['scrollToAnswer'] = self.dialog.scrollToAnswer.isChecked()
self.config['qaDivider'] = self.dialog.showDivider.isChecked()

View file

@ -5,8 +5,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>655</width>
<height>487</height>
<width>827</width>
<height>648</height>
</rect>
</property>
<property name="sizePolicy" >
@ -27,8 +27,8 @@
<rect>
<x>0</x>
<y>69</y>
<width>655</width>
<height>398</height>
<width>827</width>
<height>559</height>
</rect>
</property>
<property name="sizePolicy" >
@ -154,8 +154,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<height>343</height>
<width>542</width>
<height>504</height>
</rect>
</property>
</widget>
@ -164,8 +164,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>100</width>
<height>30</height>
<width>550</width>
<height>413</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5" >
@ -186,8 +186,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>100</width>
<height>30</height>
<width>550</width>
<height>413</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
@ -202,19 +202,261 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="optionsPage" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>504</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5" >
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4" >
<item>
<layout class="QVBoxLayout" name="verticalLayout_11" >
<item>
<widget class="QLabel" name="optionsLabel" >
<property name="text" >
<string>&lt;h1>Welcome!&lt;/h1></string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_12" >
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" >
<item>
<widget class="QPushButton" name="optionsButton" >
<property name="text" >
<string>Review &amp;Options>></string>
</property>
<property name="checkable" >
<bool>true</bool>
</property>
<property name="checked" >
<bool>false</bool>
</property>
<property name="flat" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="optionsHelpButton" >
<property name="text" >
<string>Help</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="optionsBox" >
<property name="title" >
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8" >
<item>
<layout class="QGridLayout" name="gridLayout_13" >
<property name="leftMargin" >
<number>2</number>
</property>
<property name="spacing" >
<number>0</number>
</property>
<item row="1" column="0" >
<widget class="QLabel" name="label_20" >
<property name="minimumSize" >
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text" >
<string>Time limit (mins):</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="minuteLimit" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_21" >
<property name="text" >
<string>Question limit:</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="questionLimit" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="2" >
<spacer name="horizontalSpacer_3" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="label_22" >
<property name="minimumSize" >
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text" >
<string>New per day</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="newPerDay" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QComboBox" name="newCardOrder" />
</item>
<item>
<widget class="QComboBox" name="newCardScheduling" />
</item>
<item>
<widget class="QComboBox" name="revCardOrder" />
</item>
<item>
<widget class="QCheckBox" name="delayLapsedCards" >
<property name="text" >
<string>Delay lapsed cards until after reviews</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_4" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0" >
<widget class="QStackedWidget" name="buttonStack" >
<property name="currentIndex" >
<number>3</number>
<number>4</number>
</property>
<widget class="QWidget" name="page1" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<width>542</width>
<height>49</height>
</rect>
</property>
@ -249,7 +491,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<width>542</width>
<height>49</height>
</rect>
</property>
@ -399,8 +641,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>100</width>
<height>30</height>
<width>542</width>
<height>49</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4" >
@ -434,7 +676,39 @@
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<width>542</width>
<height>49</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6" >
<item>
<spacer name="verticalSpacer_5" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="startReviewingButton" >
<property name="text" >
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page5" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>49</height>
</rect>
</property>
@ -632,7 +906,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>655</width>
<width>827</width>
<height>23</height>
</rect>
</property>
@ -761,6 +1035,7 @@
</widget>
<addaction name="actionActiveTags" />
<addaction name="separator" />
<addaction name="actionStudyOptions" />
<addaction name="actionDisplayProperties" />
<addaction name="actionModelProperties" />
<addaction name="actionDeckProperties" />
@ -778,8 +1053,8 @@
<property name="geometry" >
<rect>
<x>0</x>
<y>467</y>
<width>655</width>
<y>628</y>
<width>827</width>
<height>20</height>
</rect>
</property>
@ -792,7 +1067,7 @@
<rect>
<x>0</x>
<y>23</y>
<width>655</width>
<width>827</width>
<height>46</height>
</rect>
</property>
@ -827,6 +1102,7 @@
<addaction name="separator" />
<addaction name="actionRepeatAudio" />
<addaction name="actionMarkCard" />
<addaction name="actionStudyOptions" />
</widget>
<action name="actionExit" >
<property name="icon" >
@ -1243,7 +1519,7 @@
<action name="actionCram" >
<property name="icon" >
<iconset resource="../icons.qrc" >
<normaloff>:/icons/chronometer.png</normaloff>:/icons/chronometer.png</iconset>
<normaloff>:/icons/view-pim-calendar.png</normaloff>:/icons/view-pim-calendar.png</iconset>
</property>
<property name="text" >
<string>C&amp;ram...</string>
@ -1351,9 +1627,55 @@
<string>Uncache LaTeX</string>
</property>
</action>
<action name="actionStudyOptions" >
<property name="icon" >
<iconset resource="../icons.qrc" >
<normaloff>:/icons/chronometer.png</normaloff>:/icons/chronometer.png</iconset>
</property>
<property name="text" >
<string>&amp;Study Options</string>
</property>
</action>
</widget>
<tabstops>
<tabstop>optionsButton</tabstop>
<tabstop>optionsHelpButton</tabstop>
<tabstop>newPerDay</tabstop>
<tabstop>minuteLimit</tabstop>
<tabstop>questionLimit</tabstop>
<tabstop>newCardOrder</tabstop>
<tabstop>newCardScheduling</tabstop>
<tabstop>revCardOrder</tabstop>
<tabstop>delayLapsedCards</tabstop>
<tabstop>easeButton2</tabstop>
<tabstop>easeButton3</tabstop>
<tabstop>easeButton1</tabstop>
<tabstop>easeButton4</tabstop>
<tabstop>saveEditorButton</tabstop>
<tabstop>help</tabstop>
<tabstop>welcomeText</tabstop>
<tabstop>startReviewingButton</tabstop>
<tabstop>showAnswerButton</tabstop>
</tabstops>
<resources>
<include location="../icons.qrc" />
</resources>
<connections/>
<connections>
<connection>
<sender>optionsButton</sender>
<signal>toggled(bool)</signal>
<receiver>optionsBox</receiver>
<slot>setShown(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>98</x>
<y>134</y>
</hint>
<hint type="destinationlabel" >
<x>219</x>
<y>190</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -177,9 +177,16 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="suppressEstimates" >
<widget class="QCheckBox" name="showEstimates" >
<property name="text" >
<string>Don't show next time before answer</string>
<string>Show next time before answer</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showStudyOptions" >
<property name="text" >
<string>Show study options on startup</string>
</property>
</widget>
</item>
@ -546,7 +553,8 @@
<tabstop>backgroundColour</tabstop>
<tabstop>showDivider</tabstop>
<tabstop>splitQA</tabstop>
<tabstop>suppressEstimates</tabstop>
<tabstop>showEstimates</tabstop>
<tabstop>showStudyOptions</tabstop>
<tabstop>saveWhenClosing</tabstop>
<tabstop>saveAfterEvery</tabstop>
<tabstop>saveAfterEveryNum</tabstop>

View file

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/" >
<file>icons/view-pim-calendar.png</file>
<file>icons/anki-tag.png</file>
<file>icons/edit-redo.png</file>
<file>icons/text-xml.png</file>

BIN
icons/view-pim-calendar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB