kindle manager

This commit is contained in:
gavin
2020-06-07 10:21:02 +08:00
parent 722757dadd
commit 76cc0d8c6d
15 changed files with 1007 additions and 233 deletions

View File

@@ -72,10 +72,13 @@ b['1']['2'] = {'3':1} # OK
so I need to use resouce file(.qrc) to manage resouce(icons),
and generator rcc binnay file, must kmanapp\_rc.py
command: pyside2-rcc -binary kmanapp.qrc -o kmanapp\_rc.py
- use QTime to check kindle kindle is connected or not
# feature plan
## 20200528
- first abstract from kindle hard / local directory for different OS **done**
- add GUI use QT **done**
- new thread to check kindle connection status
- use thread to check kindle connection status **XXXX**
- export function

BIN
icons/person.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
icons/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

122
kman.py
View File

@@ -9,10 +9,12 @@
import re
import os
import io
import json
import time
import logging
import platform
import subprocess
from collections import defaultdict
# data structure - use dict
@@ -123,7 +125,7 @@ class kMan:
kp = self.get_kindle_path()
if not kp:
s2 = u'Disconnected'
s2 = u'Disconnected ({})'.format(CLIPPATH)
else:
with open(kp+'/system/version.txt' , 'r', encoding='utf8', errors='ignore') as f:
s2 = u'Connected ({}) version {}'.format(kp,f.read().strip())
@@ -189,8 +191,8 @@ class kMan:
# parse #1 line
aus = au.search(authinfo)
bookname = aus.group(1)
author = aus.group(2)
bookname = aus.group(1).strip()
author = aus.group(2).strip()
section[bookname]['author'] = author
section['bookname'] = bookname
@@ -314,6 +316,73 @@ class kMan:
return bks
def get_bookname_num(self,bks):
""" get note number of booknames
Args:
bks: books dict
Return: dict {bookname:num,...}
"""
bksnum = defaultdict(dict)
nu = 0
for kb,vb in bks.items():
bksnum.setdefault(kb, 0)
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: continue
bksnum[kb] += 1
nu += 1
return [nu, bksnum]
def get_author_num(self,bks):
""" get note number of author
Args:
bks: books dict
Return: dict {bookname:num,...}
"""
bksnum = defaultdict(dict)
nu = 0
for kb,vb in bks.items():
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: continue
au = vb['author']
bksnum.setdefault(au, 0)
bksnum[au] += 1
nu += 1
return [nu, bksnum]
def filter_clips(self, bks, info=None, tp=0):
""" filter clips
Args:
bks: books dict
info: filter by bookname or author information
tp: type to be filter
0: top/root item clicked
1: bookname item clicked
2: author item clicked
"""
nbks = defaultdict(dict)
# do not filter
if tp==0: nbks = bks
# do filter
for kb, vb in bks.items():
if [info, tp] in ([kb, 1], [vb['author'], 2]):
nbks[kb] = vb
seclist = []
idx = 0
for kb, vb in nbks.items():
for ks,vs in vb.items():
if ks in ['author', 'lines']: continue
tm = self.format_time(' '.join([vs['day'],vs['week'], \
vs['meridiem'],vs['time']]))
tp = '标注' if vs['type']=='HL' else '笔记'
seclist.append((vs['content'],tp,kb,vb['author'],vs['position'],tm))
idx += 1
return seclist
def add_note_to_highlight(self,bks):
""" append note content to corresponding highlight
and remove NT sections
@@ -349,7 +418,8 @@ class kMan:
'TITLE'
'AUTHOR'
'CONTENT'
Return: search clipping content
Return:
[number of result , result dict]
"""
nbks = defaultdict(dict)
nu = 0
@@ -405,37 +475,58 @@ class kMan:
else ("ls /Volumes/Kindle" if os.name=='posix' else '')
# not test for windows & linux
with os.popen(cmd) as s:
r = s.read()
with subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, \
stderr=subprocess.PIPE, bufsize=-1) as s:
stream_stdout = io.TextIOWrapper(s.stdout, encoding='utf-8')
stream_stderr = io.TextIOWrapper(s.stderr, encoding='utf-8')
sout = str(stream_stdout.read())
#serr = str(stream_stderr.read())
#if sout: print('stdout {}'.format(sout))
#if serr: print('stderr {}'.format(serr))
if os.name == 'nt': # windows
for d in r.split('\n'):
for d in sout.split('\n'):
if 'Kindle' in d: return d.split('\s+')[0]
elif os.name == 'posix': # mac os
if r: return('/Volumes/Kindle')
if sout: return('/Volumes/Kindle')
else:
pass
"""
# will print error information on stdout
with os.popen(cmd) as s:
sout = s.read()
if os.name == 'nt': # windows
for d in sout.split('\n'):
if 'Kindle' in d: return d.split('\s+')[0]
elif os.name == 'posix': # mac os
if sout: return('/Volumes/Kindle')
else:
pass
"""
return False
def import_clips(self, tp='local'):
def import_clips(self, fp=CLIPPATH):
"""import clips from local file or kindle
4 lines for each section seperated with '======='
so read 4 lines before '======='
Args: tp: 'local' local clipping file
'kindle' kindle clipping file
Args: fp - file path
Return: 0 - want to import kindle but kindle is not connected
books dict
"""
# check kindle by user just call get_kindle_path()
"""
if tp=='kindle':
kp = get_kindle_path()
if not kp: return 0
else: path = kp
else:
path = CLIPPATH
path = fn
"""
# loop to fill books dict
with open(path, 'r', encoding='utf8', errors='ignore') as f:
with open(fp, 'r', encoding='utf8', errors='ignore') as f:
bks = defaultdict(dict)
secd = defaultdict(dict)
sidx = 0
@@ -490,7 +581,7 @@ class kMan:
if __name__=='__main__':
#books = defaultdict(dict)
km = kMan()
books = km.import_clips('local')
books = km.import_clips()
# remove duplication
km.drop_duplicate(books)
@@ -503,6 +594,9 @@ if __name__=='__main__':
searchnote = km.search_clip(books, '巴曙松', 'ALL', 'AUTHOR')
if searchnote[0] > 0: km.format_out(searchnote[1], 'searchauthor', ft='MD')
print(km.get_bookname_num(books))
print(km.get_author_num(books))
# add note content to hightlight, then delete note
km.add_note_to_highlight(books)

View File

@@ -1,19 +1,20 @@
import sys
from time import sleep
from threading import Thread
import _thread
import threading
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWidgets import QLabel
from PySide2.QtWidgets import QMessageBox
from PySide2.QtWidgets import QFileDialog
from PySide2.QtCore import (QCoreApplication, QDate, QDateTime, QMetaObject,
QObject, QPoint, QRect, QSize, QTime, QUrl, Qt)
QAbstractTableModel, QObject, QPoint, QRect, QSize, QTime,
QUrl, Qt, QThread, Signal, QTimer)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter,
QPixmap, QRadialGradient, QStandardItem, QStandardItemModel)
from PySide2.QtWidgets import *
#from PySide2.QtWidgets import *
from mainwindow import Ui_MainWindow
from kman import *
@@ -21,38 +22,34 @@ from kman import *
# import binary resource file(kmanapp_rc.py)
import kmanapp_rc
ONLY_TEST = 0
ONLY_TEST = 1
class kmanWindow(QMainWindow):
"""
def __init__(self, *args, **kwargs):
super(kmanWindow, self).__init__(*args, **kwargs)
"""
flag = True
def __init__(self, parent=None):
super(kmanWindow, self).__init__(parent)
self.stat_str = 'status information'
self.search_str = ''
self.local_fn = CLIPPATH
# create ui and initial it
ui = Ui_MainWindow()
ui.setupUi(self)
self.ui = ui
self.km = kMan()
self.books = self.km.import_clips('local')
self.books = self.km.import_clips()
# loop check kindle is connected or not
# to be implement
"""
try:
#_thread.start_new_thread(self.check_kindle_status)
t1 = threading.Thread(target=check_kindle_status)
t1.start()
except:
print ("Error: can not start thread")
"""
self.add_ui_component()
self.show_status_info()
self.fill_treeview()
# timer to check status of kindle
self.timer = QTimer(self)
self.timer.timeout.connect(self.show_status_info)
self.timer.start(1000)
# connect action/toolbutton to slot functions
ui.actionimportkindle.triggered.connect(lambda: self.import_kindle(self.books))
@@ -62,18 +59,34 @@ class kmanWindow(QMainWindow):
ui.actionstatistic.triggered.connect(lambda: self.statistic())
ui.actionhomepage.triggered.connect(lambda: self.homepage())
ui.actionabout.triggered.connect(lambda: self.about())
ui.actionflush.triggered.connect(lambda: self.flush())
ui.actionflush.triggered.connect(lambda: self.refresh())
ui.searchComboBox.currentIndexChanged.connect(self.search_scope_change)
ui.searchToolButton.clicked.connect(self.search_button_clicked)
ui.treeView.clicked.connect(self.clicked_items)
self.add_ui_component()
#add_ui_component() ###! can not found this function
ui.treeView.clicked.connect(self.tree_item_clicked)
ui.tableView.clicked.connect(self.table_item_clicked)
def add_ui_component(self):
self.ui.searchComboBox.addItems(['ALL','bookname','content','author'])
# status bar
self.ui.status_label = QLabel()
self.ui.pe = QPalette()
# table
#self.ui.tablemodel=QStandardItemModel(100,5)
self.ui.tablemodel= nTableModel(100,5)
self.ui.tablemodel.setHorizontalHeaderLabels(
[u'Content',u'Type',u'Bookname',u'Author',u'Position',u'Date'])
self.ui.tablemodel.update(self.km.filter_clips(self.books))
self.ui.tableView.verticalHeader().hide()
for row in range(5):
for column in range(5):
i=QStandardItem("row %s,column %s"%(row,column))
self.ui.tablemodel.setItem(row,column,i)
self.ui.tableView.setModel(self.ui.tablemodel)
"""
if not ONLY_TEST: # XXXXXXXXXXXXX
model = QStandardItemModel()
rootItem = model.invisibleRootItem()
@@ -113,11 +126,25 @@ class kmanWindow(QMainWindow):
icon.addFile(u":/icons/book_open.png", QSize(), QIcon.Normal, QIcon.Off)
item.setIcon(icon)
parentItem.appendRow(item)
self.ui.treeView.setModel(model)
"""
self.ui.treeView.setModel(model)
def tree_item_clicked(self, modelidx):
model_index_list = self.ui.treeView.selectedIndexes() # QModelIndexList
model_index = model_index_list[0] # QModelIndex
itemmodel = model_index.model() #QAbstractItemModel/QStandardItemModel
item = itemmodel.itemFromIndex(modelidx) #QStandardItem
def clicked_items(self):
print( 'call clicked_items()' )
print(item.text())
# filter clips
#item = self.ui.treeView.selectedIndexes()[0]
#print(item.model().itemFromIndex(modelidx).text())
def table_item_clicked(self, item):
content = item.data()
#print('call table_item_clicked() {}'.format(content))
def search_button_clicked(self):
print( 'call search_button_clicked()' )
@@ -129,10 +156,11 @@ class kmanWindow(QMainWindow):
#print(search_clip(self.books,s,'ALL',p[t]))
print('call search_scope_change()')
## XXXX
def check_kindle_status(self):
while True:
while self.flag:
self.show_status_info()
sleep(1)
sleep(2)
def show_status_info(self):
""" show status information on statusbar
@@ -143,33 +171,92 @@ class kmanWindow(QMainWindow):
"""
status = self.km.status_info()
self.ui.statusbar.showMessage(status[0],0)
clabel = QLabel(status[1])
self.ui.status_label.setText(status[1])
if not self.km.status:
pe = QPalette()
pe.setColor(QPalette.WindowText,Qt.red)
#clabel.setAutoFillBackground(True)
clabel.setPalette(pe)
self.ui.statusbar.addPermanentWidget(clabel, stretch=0)
self.ui.pe.setColor(QPalette.WindowText,Qt.red)
#self.ui.status_label.setAutoFillBackground(True)
self.ui.status_label.setPalette(pe)
self.ui.statusbar.addPermanentWidget(self.ui.status_label, stretch=0)
# define slot functions
def import_kindle(self,bks):
fp = self.km.get_kindle_path()
if not fp:
self.messagebox(ico=2, info='\n\n kindle is not connected')
return 0
self.books = self.km.import_clips(self.km.get_kindle_path())
status = self.km.status_info()
self.show_status_info()
print(bks)
pass
def import_local(self):
fn, ft = QFileDialog.getOpenFileName(self,
"choose file to import",
'./', # 起始路径
"All Files (*);;Text Files (*.txt)") # 设置文件扩展名过滤,用双分号间隔
'./', # start path
"All Files (*);;Text Files (*.txt)") # filter file type
self.fn = fn
self.books = self.km.import_clips(fn)
self.show_status_info()
#print('filename ', fn, 'filetype ', ft)
if fn == "": return False
def fill_treeview(self):
self.ui.model = QStandardItemModel()
rootItem = self.ui.model.invisibleRootItem()
item = QStandardItem('All Notes')
icon = QIcon()
icon.addFile(u":/icons/emblem_library.png", QSize(), QIcon.Normal, QIcon.Off)
item.setIcon(icon)
item.setAccessibleDescription('top')
rootItem.appendRow(item)
parent_item = item
# add bookname tree
[totalnum, booknum] = self.km.get_bookname_num(self.books)
bookname_item = QStandardItem('Bookname ({})'.format(totalnum))
icon = QIcon()
icon.addFile(u":/icons/book_open.png", QSize(), QIcon.Normal, QIcon.Off)
bookname_item.setIcon(icon)
bookname_item.setAccessibleDescription('root')
parent_item.appendRow(bookname_item)
if totalnum > 0:
for k, v in booknum.items():
item = QStandardItem('{} ({})'.format(k, v))
icon = QIcon()
icon.addFile(u":/icons/book_open_bookmark.png", QSize(), QIcon.Normal, QIcon.Off)
item.setIcon(icon)
item.setAccessibleDescription('leaf')
bookname_item.appendRow(item)
# add author tree
[totalnum, authnum] = self.km.get_author_num(self.books)
author_item = QStandardItem('Author ({})'.format(totalnum))
icon = QIcon()
icon.addFile(u":/icons/person.png", QSize(), QIcon.Normal, QIcon.Off)
author_item.setIcon(icon)
author_item.setAccessibleDescription('root')
parent_item.appendRow(author_item)
parent_item = author_item
if totalnum > 0:
for k, v in authnum.items():
item = QStandardItem('{} ({})'.format(k, v))
icon = QIcon()
icon.addFile(u":/icons/user.png", QSize(), QIcon.Normal, QIcon.Off)
item.setIcon(icon)
item.setAccessibleDescription('leaf')
author_item.appendRow(item)
self.ui.treeView.setModel(self.ui.model)
self.ui.treeView.expandAll()
def config(self):
print("call slot config()")
pass
@@ -187,7 +274,7 @@ class kmanWindow(QMainWindow):
pass
def about(self):
self.messagebox('\n'+ \
self.messagebox(ico=1, info='\n'+ \
' kindle management tool \n\n' + \
' v1.0.4\n\n' + \
' Author: chengan\n\n' + \
@@ -196,28 +283,87 @@ class kmanWindow(QMainWindow):
print("call slot about()")
pass
def flush(self):
print("call slot flush()")
def refresh(self):
print("call slot refresh()")
pass
# unify messagebox
def messagebox(self, showinfo):
def messagebox(self, ico=1, info=''):
""" unify messagebox
Args: ico - QMessageBox.NoIcon 0
QMessageBox.Information 1
QMessageBox.Warning 2
QMessageBox.Critical 3
QMessageBox.Question 4
"""
icons = {0:QMessageBox.NoIcon, \
1:QMessageBox.Information, \
2:QMessageBox.Warning, \
3:QMessageBox.Critical, \
4:QMessageBox.Question }
msgBox = QMessageBox()
msgBox.setText(showinfo)
msgBox.setText(info)
msgBox.setInformativeText("")
msgBox.setIcon(QMessageBox.Information)
msgBox.setIcon(icons[ico])
msgBox.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok)
msgBox.setBaseSize(QSize(600, 300))
r = msgBox.exec()
## XXXX
def closeEvent(self, e):
# stop check thread
self.flag = False
## thanks 勤奋的小青蛙 ^_^ - http://www.jyguagua.com/?p=2615
#class nTableModel(QAbstractTableModel):
class nTableModel(QStandardItemModel):
def __init__(self, parent=None, seclist=None, *args):
super(nTableModel, self).__init__()
self.seclist = None
def update(self, seclist):
self.seclist = seclist
def rowCount(self, parent):
if not self.seclist: return 0
return len(self.seclist)
def columnCount(self, parent):
if not self.seclist: return 0
return len(self.seclist[0])
def data(self, index, role):
if not index.isValid():
return None
elif role != Qt.DisplayRole:
return None
return self.seclist[index.row()][index.column()]
def sort(self, col, order):
"""sort table by given column number col"""
self.emit(SIGNAL("layoutAboutToBeChanged()"))
self.seclist = sorted(self.seclist, key=operator.itemgetter(col))
if order == Qt.DescendingOrder:
self.seclist.reverse()
self.emit(SIGNAL("layoutChanged()"))
if __name__ == "__main__":
import sys
from PySide2.QtWidgets import QApplication, QLabel
app = QApplication(sys.argv)
kmw = kmanWindow()
kmw.resize(900, 600)
kmw.show()
# loop check kindle is connected or not
# BUG to be implement XXXX
"""
try:
t = threading.Thread(target=kmw.check_kindle_status)
t.start()
except:
print ("Error: can not start thread")
"""
app.exec_()

175
kmanapp.pyproject.user Normal file
View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.11.2, 2020-06-06T20:00:44. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{fae58cf6-d2fe-464b-83cf-b657b7f31038}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop (x86-darwin-generic-mach_o-32bit)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop (x86-darwin-generic-mach_o-32bit)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{47431a9c-e34f-4b94-83d9-f5f98149f5e9}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">-1</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
<value type="QString">-e</value>
<value type="QString">cpu-cycles</value>
<value type="QString">--call-graph</value>
<value type="QString">dwarf,4096</value>
<value type="QString">-F</value>
<value type="QString">250</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">kmanapp</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">PythonEditor.RunConfiguration./Users/mark/kman/kmanapp.py</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/Users/mark/kman/kmanapp.py</value>
<value type="QString" key="PythonEditor.RunConfiguation.Interpreter">{8add66da-db0d-4573-865d-9852c93e0d0e}</value>
<value type="QString" key="PythonEditor.RunConfiguation.Script">/Users/mark/kman/kmanapp.py</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/Users/mark/kman</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@@ -46,5 +46,7 @@
<file>icons/emblem_library.png</file>
<file>icons/book3.png</file>
<file>icons/register.png</file>
<file>icons/person.png</file>
<file>icons/user.png</file>
</qresource>
</RCC>

View File

@@ -6,94 +6,96 @@
from PySide2 import QtCore
qt_resource_data = b"\
\x00\x00\x05^\
\x00\x00\x05w\
\x00\
\x00\x1c\xaax\x9c\xb5Y\xbd\x8e\xdc6\x10\xee\xef)\x84\
\xed\xb3\xda=\x5cr\x81\xc1\x93\x91\x0b\x9c\x18\x88\x0f8\
\xe36v\x19p%\xee\x8a9I\xd4Q\x94o\xd7\x95\
]8@\x80\x04q\x91\xd2U\x8aT\x81\x93\x22\x8d\x8b\
<M|\xb6\x1f##\x92\x92\xa8\xdf\xddX\xa7N\xf3\
\xc3\xe1\xcc\xc7\x99\xe1p\x17\xdd\xdd\x84\x81\xf5\x84\xf0\x84\
\xb2\xe8d2\x9f\xce&\x16\x89\x5c\xe6\xd1h}2\xf9\
v\xf1\xd5'\x9fO\xee:\x07(\xa5\xa5\xd2\x11(9\
\x07\x16r\x03\x9c$\xce\x19\xa6\xd1c\x1ay\xec\x1a\xd9\
\x8a\x03\xa2k\xea\xad\x89\xb0$}2yX\xeaL\xac\
\x08\x87\xe4dbp@\xdfB1g1\xe1b\xab\xc5\
k\xc2B\x22\xf8V\x0a-\xc4\x89+\xe4\x97\x856\xce\
\x0c\xd9\x1bMl3b\xab\x09\xd8S\xf8\xce\xf1\xf1\x11\
\xb2\xd5\xa7b\xfb\x84\xae}\xe1\x1c\xcdAU\x7fK\x9b\
vn\x14\xd9\xf9\xe6m\x9e\x5cK'\x17T\x04D;\
\x93\x08\x0e\xe08\xdf\x80 \xd6\x19\x8e\xf0\x9a\x84$\
\x12\xc8\xd6\x92\xa6\xcd\x1a\x1c\x8f%\x99C\xe1\xc2Z\x8e\
\x03\xa5\xa3\xf7\x08\xf0\x96\xa5\xe5\x82\xaf9\xf5\x1eHV\
\xbeh]rt\x9cT\x90\xd0\xe2\xec\xfad\x02G\xe8\
\xb2 \x0d\xa3\xecSI\x1b\x16\xef\x9f\xb2M\xd5\xa2\xcf\
8}\xca\x22\x81\x83\x8a]m9'\x1a\xb1<\xc0K\
\x12\xe46\x12\x82\xb9\xeb+V\xb1\xa2\x01\xa9 \x1ba\
\x88\x0bD/\xe4j\x13F-\xaf\x80\xa9Y\xca\x8d\xc2\
G\xdbtr\x87\xc74\x22\xf7<*jN\xe7\xdcn\
\xbf\xe3\x00\xbb\xc4g\x81G\xf8\xa2#\x84\x9b_\xfe|\
\xf7\xd3\x8fo\xdf\xfc~\xf3\xf2\xe7\x7f\x9f=\x7f\xfb\xcf\
\xab\x0f\xcf^\xc0\xc7\xcd\x0f/n^\xbfy\xf7\xf2\xd5\
\xfb\xbf\x7f{\xff\xc7\xaf\x1f^\xff5z\x98_\xb2p\
\xc9\xe0\x94\xaba\x16\xdc\xee0\xdd\x94sH\xc9\x8e\x10\
\xed\xd1\x1c^0\x16\x9c\xa6B\xb0\xa8\xea\xb2\xc1\xff\xff\
95\x9dN\xf7B\xbaa\x90\xba\x95\xfd\xc0w`$\
\xe0.'\x09K\xb9\x0b*\x97!\xd4~\x1cO\xaf\xb8\
kjZ(b<\xc4\x01[\xad\x9c;\xb6\x5cf\xab\
H\xa6\xdf\xc7d\x8d\xec\x1db\xbd\xd1\xc7\xe3\x8clU\
\xec\xba1\x18\x22\xa3I\xcc\xdb\x9aD\xedD.\xe2\x80\
\x0aAxq\x1e\x9a\xfe\xee\xb0l\x0e5\xd8\xa0\x89@\
\xee`AM\xf4\x10\x89\xd2\xd0y(\xee\xdc\xb9_4\
\x19dK\xe6AW\x88\x8d\xec\xe0\x84<\xa2\xa4\xb8@\
DN\x97\xbb\xd4\x5cI\xe8Sr\xce\x02\xean\xcd\xbc\
\xc9\xb8\xb1\xe4Z~\xf6-\xb61\xe8\x9es\xb2\x22\x90\
\xf6\xde\xc4zRr\xefmb\x1ce7a%\x11\xa0\
QBB\x11\xe1\xfa\xd9\xedcP\x86NvW\x96:\
\x06e\x1cj\xe9\x89q\xac\xcd\x93\xaeE\x15\xe2\x0d\x0d\
\xd3\xf0\x02\x16\xd7\xc32\x1dP7\xe0\xd1lV\xb9\x0c\
u\x00\xea\x16\x9c\x7fv|||8\xff\xb4r-\x1a\
\xbe\xf5x\xd5H\xbf=\x13\xa7\xfb\xb0Z\xf3\xc6H\x9c\
G\xa0K\xddz\xda\xb4\x02VO\x1c\xbc\x0c\xaa\x99S\
0\xba\xab\xbf5w\xba\x92\xe7L\x1d\xc9\xee\xd4\xd9+\
w\xf6I\x9e\xf6\xec\xd9\xa7Q4\xe1\x81\xc6i\xde\x86\
\x22\xa7G\x04\xa7\xac\xb6A\xe0\xcc\x87\x82\xb3gq5\
\xaa+/\xaf\xb2\x82\xea5V\x8e\x9d\xb3Y\xb3\xbe\xea\
\x05\xb6_\x87\xaf\xd0U\xd2\xe8\xf1f\xf37\x95\x1a%\
\x0a\xc5\x96&\xa7\xb8\xacQ\xc9X\x02\xc3n\xd3?\x83\
\xba3\xb4CM\xaa={\xa7ws|\xaf\xce\xef\xd5\
\x01\xbek\x82/\xb0<<\xacBY\x8e\xf0\xf5y\xbb\
'n9M\x94q\x08M\xb6\xc6\xd1\x98\xfd\x8b\xb1B\
/\xab\x8c\x16\xb5CDX\x80l\x99\x0aR\xdd\xea\x0b\
NpnM\xf6\xb2\x05\x8b\x17\xa5\xc8hp\xc8.L\
\xf4Z<\x85e\x97\xb9\xc9%\xf0\x9c\x15\x0e\x12\x82l\
\xf9\xddn\xc9\xf3\xb0\x9b5[mI\x114\x8c\x19\x17\
\x97\xf2a\xa3\xb2\xa0_3`\xd0\x91\xbb\x14\x13\x12c\
\x8e\x05\xe3\xfd\x96\xae\x19\xf7\x92~\x95,3i\x02\xed\
\x7f\xe0V0W\xad\xe8z\xa0\x11\x1fR;\x86\x17_\
\xbf\x16^f/\xa8a;\xad\x824\xf1u1\x9a\x09\
\xbd\xe38Z3\xd9\x98f\xf7\x1bd[fX(\x85\
\x88O\xe3\xa8u\x825\x84\xe6\xfcZ\xaf\x89\xee\xa9=\
\xaf,#\x94\xde\xea\xaa[\x82T_\xd0\xb8\xd5\x18\xd4\
>\x8dc\xa0\xad\x15\x85\x17\xfb\x8a\xb3\xd0\x92\x1bT\x05\
=\xdbA\xfdH\x9c\xfb\xf1\xd7\x853\xea\x01\xf4\xe1\x7f\
{\xf0\xabH\xc6\xc4\x7f\xe7\x0e\xbb \xd7\xc5<\x1a\xd8\
\xca~\x17\xdc\xa6t\x18\xe0\xca\xd2p\xa8\x95\x9d\x94\xcb\
\x11z\x00\xae\xaa\xeb\x8c\x06+L~\xb0\xc4\xef\xc2\xb5\
\x22\x1e\x06\xac65\x1cYm\xc8\xd2\xc9\x9c\xe5\xb0}\
\x95R\xf7\xb2\xe0\xdcJB\xab\x8bp4\xe0a\x16\xb8\
L\xba`7\x84\xc3@\x97A\x0c\x87|\x97\x99]X\
\x96\x13\xc3hx\x16[t\x82Z\xd7\x18\x86lam\
8\xba\xa5c\x105\xce\x1e\xa9\x96\x8f\x97K*\x06 \
^\x8cE\xa3\x01\x9e\xed\xd0\x05u)\x1b\x06r\x1e\xc5\
m4\x0d\x8ff\xaf\x13K0+\x84\x07\xf1n\xc3\xbb\
\x10V#\xe5h\xf0^\xa5$\xc9\xb6\xe9\x82\xb8*\x1f\
\x06\xb3\x0ce8\xc6\xa0\x12Y\xd2\x96\xe5Q\xf0\xb6\xef\
\x16\xdd\xd91\xe4/\xb0\xe3\xc1{N7\xd8#\x9b.\
t+\xe2\x81\x8d\xa2\xf9/\xca\xc7u\x09i\xc7\x8a\x98\
\xd83k\x8dG\x0a\xca\xe1I\xa4\x0e\x8d\xdc \xf5\x88\
\x1c\xba\x85\xfc\x0b\xd1\x04\xcd\x96k\xcd\x15\x08\x00\x88\x88\
:\x17\x90\x22;\xa5\xce\xc1\x7f\xdc\x00'-\
\x00\x1d\x01x\x9c\xb5Y\xcd\x8e\xdb6\x10\xbe\xefS\x10\
\xbe\xd7\xb2\x17\xdbn\xb1\x90\x1dt\x8b\xb4\x01\x9a\x056\
Xws,h\x89\xb6\xd8\x95D-Ee\xed\x9c\x92\
C\x0a\x14h\xd1\x1cz\xcc\xa9\x87\x9e\x8a\xb4\x87^r\
\xe8\xd34\x9b\xe41:\x22)\x89\xfa\xb5\x1b\xadn\x9a\
\x1f\x0eg>\xce\x0c\x87\xb6}o\x13\xf8\xe8\x09\xe11\
e\xe1l4\x1dOF\x88\x84\x0esi\xb8\x9e\x8d\xbe\
]|\xf5\xc9\xe7\xa3{\xf3\x03;\xa1\x85\xd2\x11(\xcd\
\x0f\x90\xed\xf88\x8e\xe7g\x98\x86\x8fi\xe8\xb2\x1b\xdb\
R\x1c\x10\xddPwM\x04\x92\xf4l\xf4\xa8\xd0\x19\xa1\
\x10\x07d628\xa0\x8f\xec\x88\xb3\x88p\xb1\xd5\xe2\
5a\x01\x11|+\x85\xc8\xe6\xc4\x11\xf2\x0b\xd9\x9b\xf9\
\xc4\xb66\x9a\xd8\xa6\xc4V\x13\xb0\xa7\xf0\xe6\xc7\xc7G\
\xb6\xa5>\x15\xdb#t\xed\x89\xf9\xd1\x14T\xf5\xb7\xb4\
ieFm+\xdb\xbc\xc9\x93\x1b\xe9\xe4\x82\x0a\x9fh\
gb\xc1\x01\x9c\xf97 \xf0\x09:\xc3!^\x93\x80\
\x84\xc2\xb6\xb4\xa4n\xb3\x02\xc7cIfP8\xb0\x96\
c_\xe9\xe8=|\xbceI\xb1\xe0kN\xdd\x87\x92\
\x95-Z\x17\x1c\x1d'\x15$@\x9c\xdd\xccFp\x84\
\x0e\xf3\x93 L?\x95\xb4f\xf1\xc1)\xdb\x94-z\
\x8c\xd3\xa7,\x14\xd8/\xd9\xd5\x963\xa2\x16\xcbC\xbc\
$~f#&\x98;\x9eb\xe5+j\x90\x0a\xb2\x11\
\x868G\xf4B\xae6a\xd4\xf2\x12\x98\x9a\xa5\xdc\xc8\
}\xb4L'wxLCr\xdf\xa5\xa2\xe2t\xc6m\
\xf7;\xf2\xb1C<\xe6\xbb\x84/ZB\xb8\xfd\xe5\xcf\
w?\xfd\xf8\xf6\xcd\xef\xb7/\x7f\xfe\xf7\xd9\xf3\xb7\xff\
\xbc\xfa\xf0\xec\x05|\xdc\xfe\xf0\xe2\xf6\xf5\x9bw/_\
\xbd\xff\xfb\xb7\xf7\x7f\xfc\xfa\xe1\xf5_\x83\x87\xf9%\x0b\
\x96\x0cN\xb9\x1cf\xcem\x0f\xd3I8\x87\x94l\x09\
\xd1\x1a\xcc\xe1\x05c\xfei\x22\x04\x0b\xcb.\x1b\xfc\xff\
\x9fS\xe3\xf1x/\xa4k\x06\xa9S\xda\x0f|\x07F\
\x0c\xeer\x12\xb3\x84;\xa0r\x15@\xedG\xd1\xf8\x9a\
;\xa6&\xb2C\xc6\x03\xec\xb3\xd5j~b\xc9e\x96\
\x8ad\xfc}D\xd6\xb6\xb5C\xac7\xfax\x9cmK\
\x15\xbbn\x0c\x86\xc8h\x12\xd3\xa6&Q9\x91\x8b\xc8\
\xa7B\x10\x9e\x9f\x87\xa6\xbf;,\x9aC\x056h\x22\
\x90;XP\x13=\x9b\x84I0\x7f$NN\x1e\xe4\
M\xc6\xb6$\xf3\xa0-\xc4ZvpB.)\xc9/\
\x10\x91\xd1\xc5.\x15Wb\xfa\x94\x9c3\x9f:[3\
oRn$\xb9\xc8K\xbf\xc56\x02\xddsNV\x04\
\xd2\xde\x1d\xa1'\x05\xf7\xfe&\xc2az\x13\x96\x12\x01\
\x1a%$\x14\x11\x8e\x97\xde>\x06e\xe8\xa4we\xa1\
cP\xc6\xa1\x16\x9e\x18\xc7Z?\xe9JT\x01\xde\xd0\
\x09.`q5,\xd3\x01u\x03\x1eM&\xa5\xcb\
P\x07\xa0n\xc1\xe9g\xc7\xc7\xc7\x87\xd3OK\xd7\xa2\
\xe1[\xa7WX@M-\x13A\xb2\xdb\x83`h\x8b\
\x974\xa6K\xbf\xe4\xd8\x12\xaaw\xbe\xc2~LlK\
~\x17Vs\x1bE\x16T\xb2z\xcf|l\xcf\x81\xc6\
t4\xf2\xf1\x12t\xa9S\xcd\xc6\xc6\x88\xab\xf9\x88!\
\xd0RB\xe6\x8c\xf6\xa6\xd2\x98\x92m9y\xa6Nz\
wF\xee\x95\x92\xfb\xe4dsR\xee\xd3\x7f\xea\xf0@\
?6/Y\x91\xd1\x03\x82S\x14q/p\xa6}\xc1\
\xd9\xb3fkE\x9bUmQ\x98\xd5\xd2-\xa6\xd9\xc9\
\xa4^\xb6\xd5\xba\xdd\xef\xe2(\xd1e\xd2\xb8:\xcc;\
\xc5T\xaa\x95(\x14[\x12\x9f\xe2\xa2F%c\x09\x0c\
\xabI\xff\x0c\xea\xce\xd0\x0e4\xa9\xf6\xec|\x14\x98\xaf\
\x82\xf2\xb3\xa0\xfc.h{\x18\xe4X\x1e\x1e\x96\xa1,\
^\x06\xd51\xbe#n9\xa4\x14q\x08M6\xc6Q\
{R\xe4\xd3\x8a^V\x9aX*\x87X\xeb\xbcz\xcd\
\x17\x9c\xe0\xcc\x9a\xece\x0b\x16-\x0a\x91\xd1\xe0\xaa\x8d\
\xb7\xcd\xe2),\xbb\xcaL6\xb6\xf1\xba%\xd7\xc5N\
\xdal\xb5%E\xd0 b\x5c\x5c\xc9\xf7\x92\xca\x82n\
M\x9fAGnS\x8cI\x849\x16\x8cw[\xbaa\
\xdc\x8d\xbbU\xd2\xcc\xa41\xb4\xff\x9e[\xc1\xb8\xb6\xa2\
\xeb\x9eF<H\xed\x08\x1e\x92\xddZx\x99>\xcc\xfa\
\xed\xb4\xf2\x93\xd8\xd3\xc5h&\xf4\x8e\xe3h\xccdc\
H\xdeo>n\x18\x8d\xa1\x14B>\x8e\xc2\xc6\xc1\xd8\
\x10\x9acq\xb5&\xda\x1f\x03Ye\x19\xa1tVW\
\xd5\x12\xa4\xfa\x82F\x8d\xc6\xa0\xf6i\x14\x01\x8dV\xd4\
'h\xc5Y\x80\xe4\x06eA\xc7vP?\x12\xe7n\
\xfcu\xe1\x0cz\x00]\xf8\xdf\x1d\xfc*\x92!\xf1\xdf\
\xb9\xc3.\xc8u1\x0f\x06\xb6\xb2\xdf\x06\xb7)\xed\x07\
\xb8\xb2\xd4\x1fje'\xe1r\x84\xee\x81\xab\xea:\x83\
\xc1\x0a\x93\x1f,\xf1\xdap-\x89\xfb\x01\xabM\xf5G\
V\x1bB:\x99\xd3\x1c\xb6\xae\x13\xea\x5c\xe5\x9c;I\
hu\x11\x0e\x06<\xcc\x02Wq\x1b\xec\x86\xb0\x1f\xe8\
2\x88\xfe\x90\xef2\xb3\x0b\xcbbb\x18\x0c\xcf|\x8b\
VP\xab\x1a\xfd\x90\xcd\xad\xf5G\xb7p\x0c\xa2\xc6\xe9\
#\x15yx\xb9\xa4\xa2\x07\xe2\xf9X4\x18\xe0\xe9\x0e\
mP\x17\xb2~ gQ\xdcE\xd3pi\xfa:A\
\x82\xa1\x00\x1e\xc4\xbb\x0d\xefBX\x8d\x94\x83\xc1{\x9d\
\x908\xdd\xa6\x0d\xe2\xb2\xbc\x1f\xcc2\x94\xfe\x18\x83J\
\x88\xa4-\xe4R\xf0\xb6\xeb\x16\xdd\xd91\xe4\x0f\xbb\xc3\
\xc1{N7\xd8%\x9b6tK\xe2\x9e\x8d\xa2\xfe\xe7\
\xcc\xc7u\x09i\x07\x85L\xec\x99\xb5\xc6#\xc5\xce\xe0\
\x89\xa5\x0e\x0d\x1d?q\x89\x1c\xba\x85\xfcg\xd2\x04\xcd\
\x92k\xcd\x156\x00\x10\x12u. \xb5\xad\x84\xce\x0f\
\xfe\x03Ie@\xd5\
\x00\x00\x0f\xf6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@@ -29968,6 +29970,84 @@ w\x0b\xbe\x86\xd8\xb8\xeb\x81L\x83\xc8\x9cP\x80\xe9<\
\x02\xbf&;^~3\xb09K\xae\xa5$\xcaR\xec\
\xec1\xfc\x7f\x89E]\xa3\xc9\xb4-\xf9\x00\x00\x00\x00\
IEND\xaeB`\x82\
\x00\x00\x04\xbb\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\
\x00\x00\x04\x82IDATx\xda\xedV}L\x95e\
\x14?\xcf\xfbu\xe1~\xc4\xbdH\x08\x04\x13\xe7\x1d\x5c\
\xb4\x11e\x94\xa3\xa4\xcd\xa6\x92\xc9\xac\xd5\x1fmQ\xab\
\xa5l\xc6\xc8\xd6\xea\x16E\xa9\xfdS\xd9\x96\xc3\xd9\xd6\
\x07F\x06\xd4T6\x1c\x023\xa5@7L\x92\x85+\
q0@\x91\xb05\x09\x10\x02\xee\xbd\xef\xc7\xf3t\x1e\
>op\xa1^Z\xab?8\xdb\xd9{\xde\xf3\x9c\xe7\
\x9c\xdf{\x9es\xce\xf3\x12\xf8\x8f\x89,\x01X\x02\xb0\
\x04\xe0\xaf\x0cX#$\x80\x08\x1bQ\x94\xc0\x80Zr\
\x1f\xf4.d\xff\xd9\x95$\x22\x10\xb2^\x16\x94T\x9d\
\xea\xd7)\xd0\x13\xcf\xael\xd7\x17\x05\x80\x9e\x83\xd7\xd1\
`\x0fh \x03C\x85\x02\xa3\xaa\x11\x96mY\xef\xaf\
\xdfu\xb2[@M$\xf2@QV\x22\xe5\xf6\xc5]\
\xeehYT*\x0d\xaae\xf8\x0d? \x08d\xf9\xbc\
F\xf5\x0d;Vu\xfaL\x010\xce\xc06\xc2\xe08\
\xcc\xc2>*;\xdb\x8b\xd4\x9a\x13\xfd,\xfe9`\xcc\
E\x08\xe9\xd3)\xf5\x1e\xc8Z\xf9yqWr\xad\xcf\
\x18y\x8816m/\x10\x11\x14\xc1\xf2R\xae\xbbs\
\xbf)\x00\xda7P\x85\xc1\xb3\xfft\x1c\x8c\xc0\xc7P\
\x06-\xbet\xd0\xe8L\x10\x9b\x22RWD\xf5\x13\xf1\
1EGt\xaa\xce\xf1)\x09\xca\xe9\xbc\xa4\xab\x9bL\
\x01\x08\xd4\xc2O\x98\xf6\xdb\x83u?\xd2\x07\xe1\xa0z\
\x104\x9d\xce\xb1\x8fv]\xecLL(p36w\
\x0d\xb3pyW\xca\xb55\xa6\x00\xf8\x8e\xc3\xf7\xb8\x9a\
\x1e\xac;fx\xa1\xc6\x9f\x13\xd2\xdea\xfb\x99y\xdc\
;\xe7\xf3w\xf9\xe55=\xe6\x00\x8cT\xc0a\x5c}\
:XW\xa2\xbd\x05\x0d\xda#!\xed\x15yd\xf0\xce\
\xd5O\xd9Q\x94C,\x9f\xf2\xa6^\xdbl\x0a\xc0\xf0\
\x91\xf1\xf3\xaf\x0a\xd6\x1d\xd5\xf2\xa0Z\x7f&\xa4\xbd \
\xf8\xdb\xef\xf0\xbc\xd8\xa1(\x03[\xe7\xae\xb2\xd7\x0a\xd2\
\xba\xdf3\x05\xe0\xe6\x97@\xb0\x98\xebP\xdc0\xa5k\
6\x1e\x80\x03\xda\xbb\xa1\x01\x10\xb5jU\xe2\x87\x85\x91\
\x11\xcdM\xf8\x1a\x1e\xb4\xd4\x87\x00R\x0a\xd7^\xed7\
\x05\x80S\xff\x17\xe0\xc4BlE1n\xdc\x13\x8b9\
\xe9U\xcb\xd3p,\xc4\x84p\xb4\xa367\xb3x\xef\
\x85\xa4\x1c,\xc4\xd2i=!\xd9\xbb\xd3;\xaa\xe7\x8b\
\xb1 \x80\xbeRH\xc5Y\xd0@5p\xf1w\xbfl\
=V\xaa\xe6W\x9cQ\xb3\xbe\xe2\x1f=\x13\xc4\xb8\x14\
\xe5j\xbb;yE%U\xe4\xa1\x821}d/\xef\
\x06\x81H|\x18m.\xbc\xe7\xe2\xa9\xbf\x0d\xe0\xd7\xc3\
\xb8G\x80Gq~<\x8f>2\xe9\xe8\x8c\x0d\xc1\xf2\
\xd2-JG\x89/?\xac\xde\x97\x950\xa5\x8f\xbd\xb5\
y\x8bg\xc5\xd9u\x924\xb4=\xa0\xfb\xe3\xfc\xfa\xcc\
\xd0\xb3+\x0e]\x16-\xdf\xe2\xee\xea\x80\xaeU\xbe\xb9\
\xee\xbb\xde\x90\x00~9\x04\x0eA\x86<T\xe4S\x15\
\xe2h 4\xe2\x01\x16\x05\xa5\xca\x1b\xd04\xe6\x19\x7f\
W$\x11\xee\xf2\x94\xebDn\x91\x0cf\xcc\x9bM\x09\
\x9d[e\x1b\x15\x05\xa9N3\xf4\xf7wg4\xd6M\
\x03\xb8\xfe\x09l\xc5l\x15\xd31X\xceB\x5c\x1b|\
\xe6\xb5\x09i\xd0d}\x0c~`\xf7\xc2\xe0\xa8\x0e\xba\
13p\x9cv\x0bD8\xba\xc1jm\x05Yi\x01\
\xec\x84\x85N\x96g\x05\xbbF\xfa\xe8\xed\xfb\xcf\xee$\
\xdd\xfb!JT\xa0\xd7\xf0\x81e\xb6\xa1\x8e\xd7\xe0\x05\
e\x13\xd4+\x8fC\x8fq\x1b\x0c\x8d\xfa\x17t,c\
6\x1cV\x0b\xd8m=`\xb55\x80\xcdzi~[\
\x0cJ)M!W\xf6A2\xff\xc0\xd9\x13\xb4K\x5c\
\x0d\xe5\xd6W\xa0;\xb0\x0c\xc6\x02*\x98%G\xb8\x05\
\x5c\xce\x1epE\x96\x82(\xcc\xbb?\x8dt\xbd\x03\x12\
\x03\xb2\x9d\x81`a\x84_\xf9\x12\xb4\xb2\x94\xb8O\xc3\
^\xf5\xf6\x8dP31\xe7\x90(\x12X\xbe\xac\xad.\
6\xaa\xb1Z\x16\xfd@\xd1;#t\xe2\x09Xi\x84\
\x1e\x9a.\xc2\x8a\x92}\x02C\xac\xd8<\xc2\xf9\xdf\x1d\
\x99\x0d7m\xa71E\xff\x08\x00\xa7\xf8p\xfa\xc1\xc6\
\x18\xdf\x1e\xbbdhXMx\x87r6h\xee\x93/\
\x8c;'eeeN|f \xbb\x91\xa38\x0fk\
,\xf6\xeb\x1b\xb0\x05-\xa7z]Xd|\xba\xd6\x09\
mn;\xe9By\x10\x99\xf7\xe7o\x93\xdc\x89|\x8e\
\x03\xe0A\x1fF\xe6\xb5\x10\x0d\x13\x7f9V\xe4[`\
\xa2K\xb8\x1c\xb6H\x00\xbcj\xc7`\xa2\x91\x86'e\
\xde\x227\x90\xdb\x91k\xc6\x8f\x00A\xf0/\x14'\x99\
\xdff\x12\xf0\x1f\xb0\x09\x0a\x0b\x92\xcd\x92:\x09bJ\
\xe6M\x8eG\x01|`\x18999\xf4\xff\xffW\xbc\
\x04\xe0\xdf\xa6?\x00rj\xad{\x92\x06\x13\xe9\x00\x00\
\x00\x00IEND\xaeB`\x82\
\x00\x00r\x8b\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@@ -37526,6 +37606,88 @@ W\x22\xf9z\xc2Q\xafD\x96\xf5\xbcVnK\xe3x\
\x83(\xf25\x01G\xac\x0a*,ucW:\xd8\xa2\
n\xaa\xfd\xc2\xff\x0f\xa9U{(\xf7\x16\xc1\xc8\x00\x00\
\x00\x00IEND\xaeB`\x82\
\x00\x00\x04\xfa\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\
\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\
\x00\x00\x00\x09pHYs\x00\x00\x00\xec\x00\x00\x00\xec\
\x01y(q\xbd\x00\x00\x00\x19tEXtSof\
tware\x00www.inksca\
pe.org\x9b\xee<\x1a\x00\x00\x04wID\
ATX\x85\xad\x97\xedoSu\x14\xc7?\xe7\xd7\xee\
vm\xf7\xc0\x96V6(2&t\xe1!\x13XP\
\xe2\x0b\x0c\xc4\xf8\x82%\x9a\xc0\xb2\xe8\x1b\x12\xdf\xf9\xc2\
\xc4\x17\xbc\xc0\x98H4\xfaB\x125\xfc\x11*\xc6g\
\x12\x07!F\x88\x04dA\xa4\x93eA\x180\x0cc\
\xc2x\xd8d\xeb\xd6\xdb\xdb{\x8f/\x5cG\xb7\xf6\xb6\
\xcd\xf4\xfb\xaa=\xe7\xdcs>\xf7\xdes\xcf\xb9W\xa8\
R\xcd\xfd\xda`,\xba\x11v\x01O\x03m(\xcd\xb1\
\xeb\x8e\x07L\xa2\xdcD\x18\x10\xf4\xa4gY}W^\
\x96\xa9j\xf2J\xa5\x80\xd8\x80&\xd5\xe3\x80\x08\xaf\x00\
\x91\x22\xff5\xa7\xd4a3*\x1c1x\x87.\xf7\xd4\
\x0e/\x09 \xf1\x8b\x863\x11\xdeGy\x13\x08\xfa\x02\
\x96\x06\xc8\xcb\x11\xd1\xc3\xb3S\xd6\xc1\x9b\xafI\xa6j\
\x80xJ\xd7\x01\xdf*l\xf2\xcbl\xcd(\xd1q\x07\
kl\x02\xaf\xb1\x0e\x0dY\xfe\x18J\xbf\x04j\xf6\x5c\
\xde+\x7fU\x04\x88\x0f\xe8\x16UN\x00\xf1R\xb9\x9a\
\xfftH\x1e\x9f!>\x9cE\x14\x86\xdc>T\x047\
\xd1Bf{'nK\xcc\x87BFU\xbc\xee+=\
\xa1K\xbe\x00\xf1\x94\xaeS8\xebW\xbc\xfd\xcc,\x1b\
\xbf\x9bF\xf4\xb1m\xc8\xed{|\xa2\x22dvt\x91\
\xed\xec\xf0\x83\x18\xf3\xd4y\xe6jo\xe4v\xdeb\xf2\
?\xdaNi\xad\xc2W~\xc5[\x07m6-*^\
\x94^\x95\xf0\xe9\x0b\xd4\xdc\x18\xf5\x89\xd0\x15F\x82G\
\x13_j\xb8\x08`\xba\x89\x0f\xf8\xf7\xf1*\x92qa\
\xe3\xf7i(S\xfcq\x0d\xa8=}\x01\x5c\xcf/\xa2\
\xab\xced\xdfZ\x00\x10\x1b\xd0\xe4\x5c\xb7\x97Tl8\
Kd\xc2\xad\xa2\xfa\x5c\xd2\xa94\xc1\xdbw\xcb@\xca\
\xfe\xf5\xdfh\xeb<\x80z\x1c\xa0\xcc\xa3\xb6\xecV\xae\
\xea\xe2y\x05\xc6\x1f\x94sGQ\xe7\x1d\x00\xd3\xdc\xaf\
\x0dsC\xc6?Y\xb6\x9ak\xbfP\x92-\x0f\xad\xca\
\xbe\x8e\xa3Zo\x8cE7%&\x5c\xa12\x0d\xa6\x9c\
\xbbt\x81h\xb8RH\xd4\xd8\xd9\xddfn\xb6\x97\xd5\
\xfdd\x99!\xe3\xa3\xdc\x93\xad\x15c\xd4\xc8.\x83O\
\xe7\x17jjy\x80\xbb\x1b\xaa\x87p\xd6\xac\xc4mj\
\xa8\x1c\xe8\xd1i\x805\xd5$\xbd\xd4S_\xd5\xad\xd0\
h\x98\xcc\xceg\xabI\x09B\xbb\x01\xaa@\x85\xd9e\
\x86\xb3o,\xe3\xd1\x0a\xdf\x87\x05/\xd6D\xba\xe7E\
\xbc\xca\xf7?\xafF\x89\xa5\xd4\x06\xaa\xbe\xbe\xa2\xb02\
e\xd3:hS?j3\xe2\x9e\xc5mj\xc0yj\
\x15\xb9u\xabQ\xa9\xb8\xe1\x0beK,\xa5\xf7\x00\xbf\
\x0dRQ\x15\xd6q%\x8d\x07\x81\x91r\x00\xc6\x85\xe8\
}\x97\xd0\x94\x87x\x8b\xe6\x81\xab\x04\xee\x94\x98x\xc6\
\xa0\x910nc\x1d\x982}\xa3\xdc\x08\x02\x03\xc0\xb6\
\xc5>kFI\xfe\x98&\xf1\xab\x8d5\xe3;\xd7\x19\
rO\xfa\xe7\xaf\x0d\x91]\xdfNf\xdb&(\xf5\xbe\
\xfcnP\x8a2\xd4\x8d\xbb\xec\xf8\xe8!\xed?\xcf\
\x96-^I\x92\xb1\x09\xa5.S\x7f\xe4\x18f\xe2Q\
1 \xfa\x93\x91\x10?\x00\xe9BG\xd7\xa7\x8f\x88L\
.\xbd\xf0b\x99\xa94\x91\x13g\x16\x9b\xd3A\xb5\x8e\
\x9b{\x1be\x1a\xe1\x8bB\xcf\xf5\xe7\xcbN\xe6%\xc9\
\xde\xbaa\xb1\xe9\xf3\xa1^\x996\x00\xa2\x1c\x02\xe6\xdb\
y\xb4+\xc4\xd8\xe6\xd0\xffV\xdcI\xb6\xe1$\xdb\x0a\
MY\xcfx\x1f\xc2\xdc:\xbe\xb7E\x86\x81\xc3\x85\x11\
\x17_\xad\xe7A{\xcd\x7f.\x9eK,g\xf6\x85\xed\
\x0b\x8d\xa2\x9f\x5c\xdd[{c\x1e\x00\xa0n\x92\x83\x22\
\xf4\xe7\xff{5\xc2\xb9\xd7\x1b\xb9\xbde\xe9W\x22\xdb\
\xd1\xc6\xccK;\xd1@\xa0\xd0|.\x17\xb1\xde\x9dg\
)\xf4\xc4\xcfk\x8b\x069\x8f\xb0\xaa\xd0\x9e\xb8h\xb3\
\xbeo\x9a\xf0Dqc\x16\xbe\x94\xe6\xa5\xf5\x11f\x9f\
\xdb\x8a\x93\x5c\xbd\xc8S\xfcRZ47\x9f\xf8M;\
=C\x1f\x90(\xb4\x9b\x9c\x92H\xd9\xacH\xd94\x8f\
8\x04m]\x00\xa0V\x0d\xb9\xd68NG\x1b\xce\xda\
\xd5\x10X8\x80T\xb8%\x9ev\xff\xd1\x1b\x1a\x5c\x80\
T\x84\x0f\xb4\x5c\xd4xN\xf8\x1a\xd8Q\xca/\x0a\xe1\
\x87.\xa1\xbfsXc\x0f\xd1p-^C\x14\xfc\xf7\
\xc0\xb9\x80\xd6\xec\x19\xea\x95;E\xb9\xfc\x8eX;\xac\
\xa1\xc94o\xa3\xec\x07\xa2~q\x15vA\x16\xf4\xe3\
\x5c\xd4z\xef\xdan\xb1K\x9eL\xb9\xa3a\xae/j\
8\x08\xec+\x05\xe2\x03\x90F\xf8\xcc\x13\xefP\xbe\xdb\
\xfdT\xf5\xee\x8c\x0fi\x1d\x0e\xdd\xea\xb1\x13a3\xb0\
f\xc1\xe79\x8c\x08\xa4<\xd1SA\xcf:6\xd4+\
\xd3\xd5\xe4\xfd\x07O\xc0\xaf\xb9s\x8fj\x8f\x00\x00\x00\
\x00IEND\xaeB`\x82\
\x00\x00kN\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@@ -46350,6 +46512,10 @@ qt_resource_name = b"\
\x03v\xc2\x07\
\x00q\
\x00u\x00e\x00s\x00t\x00i\x00o\x00n\x00.\x00p\x00n\x00g\
\x00\x0a\
\x0ao\x8eg\
\x00p\
\x00e\x00r\x00s\x00o\x00n\x00.\x00p\x00n\x00g\
\x00\x06\
\x07\x84WG\
\x00q\
@@ -46374,6 +46540,10 @@ qt_resource_name = b"\
\x0c\xcb\xdb\xc7\
\x00m\
\x00o\x00n\x00e\x00y\x002\x00.\x00p\x00n\x00g\
\x00\x08\
\x09\xc5X\xc7\
\x00u\
\x00s\x00e\x00r\x00.\x00p\x00n\x00g\
\x00\x0b\
\x0e|&g\
\x00w\
@@ -46415,99 +46585,103 @@ qt_resource_name = b"\
qt_resource_struct = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00-\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x02\x00\x00\x00/\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x10\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01r\x82\xd3\xbeg\
\x00\x00\x03|\x00\x00\x00\x00\x00\x01\x00\x0838\
\x00\x00\x01r\x8a17\x84\
\x00\x00\x03\x96\x00\x00\x00\x00\x00\x01\x00\x088\x10\
\x00\x00\x01ro \xc0+\
\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x01\x00\x01\x92\x83\
\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x01\x00\x01\x92\x9c\
\x00\x00\x01rybF\xf5\
\x00\x00\x04.\x00\x00\x00\x00\x00\x01\x00\x09\xdbM\
\x00\x00\x04^\x00\x00\x00\x00\x00\x01\x00\x09\xe5#\
\x00\x00\x01ro-O\xd6\
\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x006\xd5\
\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x006\xee\
\x00\x00\x01ryefk\
\x00\x00\x036\x00\x00\x00\x00\x00\x01\x00\x074\x93\
\x00\x00\x036\x00\x00\x00\x00\x00\x01\x00\x074\xac\
\x00\x00\x01ro!\xbci\
\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x04(\xe1\
\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x04(\xfa\
\x00\x00\x01r\x83\x0a\xde,\
\x00\x00\x04d\x00\x00\x00\x00\x00\x01\x00\x0a\x10\xdd\
\x00\x00\x04\x94\x00\x00\x00\x00\x00\x01\x00\x0a\x1a\xb3\
\x00\x00\x01ro \x94\xf5\
\x00\x00\x01j\x00\x00\x00\x00\x00\x01\x00\x03N\xc8\
\x00\x00\x01j\x00\x00\x00\x00\x00\x01\x00\x03N\xe1\
\x00\x00\x01rn\x81\xa0K\
\x00\x00\x00j\x00\x00\x00\x00\x00\x01\x00\x001\xd8\
\x00\x00\x00j\x00\x00\x00\x00\x00\x01\x00\x001\xf1\
\x00\x00\x01r\x83\x17T#\
\x00\x00\x03\x18\x00\x00\x00\x00\x00\x01\x00\x071\xfb\
\x00\x00\x03\x18\x00\x00\x00\x00\x00\x01\x00\x072\x14\
\x00\x00\x01r\x83\x18\xc72\
\x00\x00\x000\x00\x00\x00\x00\x00\x01\x00\x00\x05b\
\x00\x00\x000\x00\x00\x00\x00\x00\x01\x00\x00\x05{\
\x00\x00\x01r\x83\x18J\xbf\
\x00\x00\x01\x9a\x00\x00\x00\x00\x00\x01\x00\x03\xd6&\
\x00\x00\x01\x9a\x00\x00\x00\x00\x00\x01\x00\x03\xd6?\
\x00\x00\x01r\x83\x0b\xa39\
\x00\x00\x01R\x00\x00\x00\x00\x00\x01\x00\x02\xe4\x97\
\x00\x00\x01R\x00\x00\x00\x00\x00\x01\x00\x02\xe4\xb0\
\x00\x00\x01rn\x7f\x9a\xa2\
\x00\x00\x02\xb2\x00\x00\x00\x00\x00\x01\x00\x06'b\
\x00\x00\x02\xb2\x00\x00\x00\x00\x00\x01\x00\x06'{\
\x00\x00\x01rx\xd0\xef\xa4\
\x00\x00\x01\xe6\x00\x00\x00\x00\x00\x01\x00\x04\x0c\xf0\
\x00\x00\x01\xe6\x00\x00\x00\x00\x00\x01\x00\x04\x0d\x09\
\x00\x00\x01ro&U\x86\
\x00\x00\x03\x92\x00\x00\x00\x00\x00\x01\x00\x08\xa35\
\x00\x00\x03\xac\x00\x00\x00\x00\x00\x01\x00\x08\xa8\x0d\
\x00\x00\x01ro'\x5c\xdd\
\x00\x00\x04\xb2\x00\x00\x00\x00\x00\x01\x00\x0b\x0a\xde\
\x00\x00\x04\xe2\x00\x00\x00\x00\x00\x01\x00\x0b\x14\xb4\
\x00\x00\x01rxL\xc3L\
\x00\x00\x02\x84\x00\x00\x00\x00\x00\x01\x00\x05t\xa8\
\x00\x00\x02\x84\x00\x00\x00\x00\x00\x01\x00\x05t\xc1\
\x00\x00\x01rn\x80a\x98\
\x00\x00\x03T\x00\x00\x00\x00\x00\x01\x00\x07L`\
\x00\x00\x03n\x00\x00\x00\x00\x00\x01\x00\x07Q8\
\x00\x00\x01ro!\x10\x8b\
\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x01\x00\x015\xfa\
\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x01\x00\x016\x13\
\x00\x00\x01ro6\xcc\x14\
\x00\x00\x03f\x00\x00\x00\x00\x00\x01\x00\x07\xbe\xef\
\x00\x00\x03\x80\x00\x00\x00\x00\x00\x01\x00\x07\xc3\xc7\
\x00\x00\x01ryf\xd9E\
\x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x06~\xdc\
\x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x06~\xf5\
\x00\x00\x01rn\x83W\xb2\
\x00\x00\x02T\x00\x00\x00\x00\x00\x01\x00\x04\xd7\xa1\
\x00\x00\x02T\x00\x00\x00\x00\x00\x01\x00\x04\xd7\xba\
\x00\x00\x01rn\x80\x8e_\
\x00\x00\x01\xcc\x00\x00\x00\x00\x00\x01\x00\x03\xd8\xa1\
\x00\x00\x01\xcc\x00\x00\x00\x00\x00\x01\x00\x03\xd8\xba\
\x00\x00\x01ro'\xd9\xb1\
\x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x05\xc2\xb6\
\x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x05\xc2\xcf\
\x00\x00\x01ro!\x80\x9f\
\x00\x00\x04B\x00\x00\x00\x00\x00\x01\x00\x09\xf2'\
\x00\x00\x04r\x00\x00\x00\x00\x00\x01\x00\x09\xfb\xfd\
\x00\x00\x01ro*{\xa5\
\x00\x00\x04\x96\x00\x00\x00\x00\x00\x01\x00\x0a\xd1\xcb\
\x00\x00\x04\xc6\x00\x00\x00\x00\x00\x01\x00\x0a\xdb\xa1\
\x00\x00\x01rxA\xa0\xe6\
\x00\x00\x02\xc8\x00\x00\x00\x00\x00\x01\x00\x06[\x1e\
\x00\x00\x03\xfc\x00\x00\x00\x00\x00\x01\x00\x09(\xc5\
\x00\x00\x01r\x8a:\x08\x8f\
\x00\x00\x02\xc8\x00\x00\x00\x00\x00\x01\x00\x06[7\
\x00\x00\x01ro'\xf7\xd9\
\x00\x00\x024\x00\x00\x00\x00\x00\x01\x00\x04xM\
\x00\x00\x03T\x00\x00\x00\x00\x00\x01\x00\x07Ly\
\x00\x00\x01r\x8a6j\xde\
\x00\x00\x024\x00\x00\x00\x00\x00\x01\x00\x04xf\
\x00\x00\x01ro+U:\
\x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x15\x5c\
\x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x15u\
\x00\x00\x01ro\x22L\x9b\
\x00\x00\x01\x1c\x00\x00\x00\x00\x00\x01\x00\x02QY\
\x00\x00\x01\x1c\x00\x00\x00\x00\x00\x01\x00\x02Qr\
\x00\x00\x01rn\x80\xbaA\
\x00\x00\x016\x00\x00\x00\x00\x00\x01\x00\x02\x9d\x07\
\x00\x00\x016\x00\x00\x00\x00\x00\x01\x00\x02\x9d \
\x00\x00\x01ro\x14<\x9f\
\x00\x00\x03\xae\x00\x00\x00\x00\x00\x01\x00\x08\xc3\xe4\
\x00\x00\x03\xc8\x00\x00\x00\x00\x00\x01\x00\x08\xc8\xbc\
\x00\x00\x01ro\x14\xa8\xb6\
\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x01\x00\x00\xb0!\
\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x01\x00\x00\xb0:\
\x00\x00\x01ro\x1e\xc7F\
\x00\x00\x03\xfe\x00\x00\x00\x00\x00\x01\x00\x09\x8f?\
\x00\x00\x04.\x00\x00\x00\x00\x00\x01\x00\x09\x99\x15\
\x00\x00\x01rxK\x8a\x1d\
\x00\x00\x02p\x00\x00\x00\x00\x00\x01\x00\x05\x22\x97\
\x00\x00\x02p\x00\x00\x00\x00\x00\x01\x00\x05\x22\xb0\
\x00\x00\x01ro!G\x15\
\x00\x00\x01\x82\x00\x00\x00\x00\x00\x01\x00\x03\xb6\x09\
\x00\x00\x01\x82\x00\x00\x00\x00\x00\x01\x00\x03\xb6\x22\
\x00\x00\x01ro*\xb4%\
\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x01\x82!\
\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x01\x82:\
\x00\x00\x01r\x82\xb4i\x96\
\x00\x00\x03\xc8\x00\x00\x00\x00\x00\x01\x00\x08\xcd~\
\x00\x00\x03\xe2\x00\x00\x00\x00\x00\x01\x00\x08\xd2V\
\x00\x00\x01ryaf\xee\
\x00\x00\x02\xfe\x00\x00\x00\x00\x00\x01\x00\x06\xcc\xa4\
\x00\x00\x02\xfe\x00\x00\x00\x00\x00\x01\x00\x06\xcc\xbd\
\x00\x00\x01ryg+\xf0\
\x00\x00\x04|\x00\x00\x00\x00\x00\x01\x00\x0an\xf3\
\x00\x00\x04\xac\x00\x00\x00\x00\x00\x01\x00\x0ax\xc9\
\x00\x00\x01rx\xcbU\xa4\
\x00\x00\x04\x1a\x00\x00\x00\x00\x00\x01\x00\x09\xb3\xbc\
\x00\x00\x04J\x00\x00\x00\x00\x00\x01\x00\x09\xbd\x92\
\x00\x00\x01rx\xcc\xdf'\
\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x04-y\
\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x04-\x92\
\x00\x00\x01rn\x80\xf2c\
\x00\x00\x03\xe2\x00\x00\x00\x00\x00\x01\x00\x09#\xed\
\x00\x00\x04\x12\x00\x00\x00\x00\x00\x01\x00\x09-\xc3\
\x00\x00\x01ro!-\x86\
\x00\x00\x01\x08\x00\x00\x00\x00\x00\x01\x00\x01\xe3\xa2\
\x00\x00\x01\x08\x00\x00\x00\x00\x00\x01\x00\x01\xe3\xbb\
\x00\x00\x01rn\x7f\xe8!\
"

View File

@@ -111,6 +111,7 @@ class Ui_MainWindow(object):
self.treeView.setSizePolicy(sizePolicy)
self.treeView.setMaximumSize(QSize(400, 16777215))
self.splitter_2.addWidget(self.treeView)
self.treeView.header().setVisible(False)
self.splitter = QSplitter(self.splitter_2)
self.splitter.setObjectName(u"splitter")
self.splitter.setOrientation(Qt.Vertical)

View File

@@ -69,6 +69,9 @@
<height>16777215</height>
</size>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
<widget class="QSplitter" name="splitter">
<property name="orientation">

View File

@@ -1,6 +1,5 @@
TYPE|BOOKNAME|AUTHOR|MARKTIME|CONTENT
--|--|--|--|--
HL|薛兆丰经济学讲义 |薛兆丰|2020/1/13 8:11:05|么到底什么叫边际?边际就是“新增”带来的“新增”。 例如,边际成本就是每新增一个单位产品所需要付出的新增成本;边际收入是每多卖一个产品能够带来的新增收入;边际产量是每新增一份投入所带来的新增产量;边际效用是每消耗一个单位的商品所能带来的新增享受。
HL|薛兆丰经济学讲义 |薛兆丰|2020/1/30 10:23:58|一个国家很大,贫富有差距,并非每个学校和家长都能负担得起这样标准的校车。标准太高,就会逼着很多学校,尤其是农村的学校放弃提供校车,家长们就只能使用安全性能更低的交通工具,比如自己骑自行车或雇用黑车等,结果是孩子们享受到的安全保障反而降低了。
NT|薛兆丰经济学讲义 |薛兆丰|2020/1/30 10:26:31|山寨 假货 问题
HL|薛兆丰经济学讲义 |薛兆丰|2020/1/30 10:29:41|为了克服信息不对称,建立互信,人类社会构想出了各种各样有趣的解决方案,从重复交易到第三方背书,从质保、延保,再到收益共享。此外,还有三种非常接近的建立信任的办法:付出沉没成本、给出人质或者给出抵押。
HL|薛兆丰经济学讲义|薛兆丰|2020/1/13 8:11:05|么到底什么叫边际?边际就是“新增”带来的“新增”。 例如,边际成本就是每新增一个单位产品所需要付出的新增成本;边际收入是每多卖一个产品能够带来的新增收入;边际产量是每新增一份投入所带来的新增产量;边际效用是每消耗一个单位的商品所能带来的新增享受。
HL|薛兆丰经济学讲义|薛兆丰|2020/1/30 10:23:58|一个国家很大,贫富有差距,并非每个学校和家长都能负担得起这样标准的校车。标准太高,就会逼着很多学校,尤其是农村的学校放弃提供校车,家长们就只能使用安全性能更低的交通工具,比如自己骑自行车或雇用黑车等,结果是孩子们享受到的安全保障反而降低了。
NT|薛兆丰经济学讲义|薛兆丰|2020/1/30 10:26:31|山寨 假货 问题

View File

@@ -18,8 +18,13 @@
==========
薛兆丰经济学讲义 (薛兆丰)
薛兆丰经济学讲义 (薛兆丰)
- 您在位置 #4284-4286的标注 | 添加于 2020年1月30日星期四 上午10:23:58
一个国家很大,贫富有差距,并非每个学校和家长都能负担得起这样标准的校车。标准太高,就会逼着很多学校,尤其是农村的学校放弃提供校车,家长们就只能使用安全性能更低的交通工具,比如自己骑自行车或雇用黑车等,结果是孩子们享受到的安全保障反而降低了。
==========

View File

@@ -1,11 +1,11 @@
import unittest
import unittest2
from collections import defaultdict
from kman import *
class TestKman(unittest.TestCase):
class TestKman(unittest2.TestCase):
# initial
def setUp(self):
CLIPPATH = './test.data'
@@ -13,9 +13,15 @@ class TestKman(unittest.TestCase):
LOG2FILE = 1
DELIMITER= '|'
self.km = kMan()
global t_bm_sec
global t_hl_sec
global t_nt_sec
global t_hl_sec2
global t_hl_sec3
global t_hl_sec4
self.t_num_nt = 0
global t_books
t_bm_sec = ["""另一半中国史 (高洪雷)
""", \
@@ -25,22 +31,55 @@ class TestKman(unittest.TestCase):
""", \
"""- 您在位置 #1408-1410的标注 | 添加于 2020年1月13日星期一 上午8:11:05
""", \
"""边际就是“新增”带来的“新增”。
"""]
t_nt_sec = ["""薛兆丰经济学讲义 (薛兆丰)
""", \
"""- 您在位置 #4286 的笔记 | 添加于 2020年1月30日星期四 下午10:26:31
""", \
"""山寨 假货 问题
"""]
t_hl_sec2 = ["""枪炮、病菌与钢铁 : 人类社会的命运 (世纪人文系列丛书·开放人文) (贾雷德·戴蒙德)
""",\
"""- 您在位置 #4267-4268的标注 | 添加于 2020年1月29日星期三 上午12:42:32
""",\
"""从柏拉图到马克思的所有政治理论家都提出过这个问题xxxx"""]
"""- 您在位置 #4286 的笔记 | 添加于 2020年1月30日星期四 下午10:26:31
t_hl_sec3 = ["""枪炮、病菌与钢铁(贾雷德·戴蒙德)""",\
"""- 您在位置 #4267-4268的标注 | 添加于 2020年1月29日星期三 上午12:42:32""",\
"""从柏拉图到马克思的所有政治理论家都提出过这个问题yyyy"""]
"""山寨 假货 问题
t_hl_sec4 = ["""枪炮、病菌与钢铁 : 人类社会的命运 (世纪人文系列丛书·开放人文) (贾雷德·戴蒙德)""",\
"""- 您在位置 #4267-4268的标注 | 添加于 2020年1月29日星期三 上午12:42:32""",\
"""从柏拉图到马克思的所有政治理论家都提出过这个问题zzzz"""]
t_books = defaultdict(dict)
def cre_tbooks(self):
# parsing section & fill data structure
t_secd = parse_section(t_bm_sec,0)
self.t_num_nt = 0
t_secd = self.km.parse_section(t_bm_sec,0)
self.t_num_nt += 1
bn = t_secd['bookname']
t_secd = self.km.parse_section(t_hl_sec,self.t_num_nt)
bn = t_secd['bookname']
t_books[bn]['author'] = t_secd[bn]['author']
t_books[bn][str(self.t_num_nt)] = t_secd[bn][str(self.t_num_nt)]
t_secd.clear()
self.t_num_nt += 1
t_secd = self.km.parse_section(t_nt_sec,self.t_num_nt)
bn = t_secd['bookname']
t_books[bn]['author'] = t_secd[bn]['author']
t_books[bn][str(self.t_num_nt)] = t_secd[bn][str(self.t_num_nt)]
t_secd.clear()
self.t_num_nt += 1
t_secd = self.km.parse_section(t_hl_sec2,self.t_num_nt)
bn = t_secd['bookname']
t_books[bn]['author'] = t_secd[bn]['author']
t_books[bn][str(self.t_num_nt)] = t_secd[bn][str(self.t_num_nt)]
t_secd.clear()
self.t_num_nt += 1
t_secd = self.km.parse_section(t_hl_sec3,self.t_num_nt)
bn = t_secd['bookname']
t_books[bn]['author'] = t_secd[bn]['author']
t_books[bn][str(self.t_num_nt)] = t_secd[bn][str(self.t_num_nt)]
@@ -48,13 +87,13 @@ class TestKman(unittest.TestCase):
self.t_num_nt += 1
t_secd = self.km.parse_section(t_hl_sec4,self.t_num_nt)
t_books[bn]['2'] = t_secd[bn]['2']
bn = t_secd['bookname']
t_books[bn]['author'] = t_secd[bn]['author']
t_books[bn][str(self.t_num_nt)] = t_secd[bn][str(self.t_num_nt)]
return t_books
t_secd.clear()
return t_books
def test_parse_section(self):
# test function parse_section
def test_parse_section(self):
# parsing section & fill data structure
@@ -67,10 +106,10 @@ class TestKman(unittest.TestCase):
self.assertEqual(bn,'薛兆丰经济学讲义')
self.assertEqual(t_secd[bn]['author'],'薛兆丰')
self.assertEqual(t_secd[bn]['1']['type'],'HL')
self.assertEqual(t_secd[bn]['1']['week'],'星期一')
self.assertEqual(t_secd[bn]['1']['position'],'1408-1410')
self.assertEqual(t_secd[bn]['1']['day'],'2020年1月13日')
self.assertEqual(t_secd[bn]['1']['week'],'星期一')
self.assertEqual(t_secd[bn]['1']['content'],'边际就是“新增”带来的“新增”。\n')
self.assertEqual(t_secd[bn]['1']['meridiem'],'上午')
self.assertEqual(t_secd[bn]['1']['time'],'8:11:05')
self.assertEqual(t_secd[bn]['1']['content'],'边际就是“新增”带来的“新增”。\n')
t_books[bn]['author'] = t_secd[bn]['author']
@@ -86,7 +125,7 @@ class TestKman(unittest.TestCase):
self.assertEqual(t_secd[bn]['2']['position'],'4286')
self.assertEqual(t_secd[bn]['2']['day'],'2020年1月30日')
self.assertEqual(t_secd[bn]['2']['week'],'星期四')
self.assertEqual(t_secd[bn]['2']['content'],'山寨 假货 问题\n')
self.assertEqual(t_secd[bn]['2']['meridiem'],'下午')
self.assertEqual(t_secd[bn]['2']['time'],'10:26:31')
self.assertEqual(t_secd[bn]['2']['content'],'山寨 假货 问题\n')
t_books[bn]['author'] = t_secd[bn]['author']
@@ -94,7 +133,7 @@ class TestKman(unittest.TestCase):
t_secd.clear()
# test drop_duplicate
t_secd = parse_section(t_hl_sec,3)
def test_drop_duplicate(self):
t_books = self.cre_tbooks()
t_secd = self.km.parse_section(t_hl_sec,3)
bn = t_secd['bookname']
@@ -104,31 +143,58 @@ class TestKman(unittest.TestCase):
self.assertIsInstance(t_books_du[bn]['3'],dict)
try:
except KeyError as keyerror:
t_books_du = self.km.drop_duplicate(t_books_du)
t = t_books_du[bn]['3']
except KeyError as keyerror:
print("与预期匹配sidx 3 重复被删除,抛出: %s" % 'keyerror')
t_secd.clear()
def test_format_time(self):
# test function format_time()
def test_format_time(self):
self.assertEqual(t_ds, '2020/1/13 20:11:05')
t_ds = '2020年1月13日 星期一 下午 8:11:05'
t_ds = self.km.format_time(t_ds)
self.assertEqual(t_ds, '2020/1/13 20:11:05')
# test function format_data
t_out = format_data(t_books, ft='MD')
self.assertEqual(t_out[0], 'TYPE|BOOKNAME|AUTHOR|MARKTIME|CONTENT')
self.assertEqual(t_out[1], '--|--|--|--|--')
self.assertEqual(t_out[2], 'HL|薛兆丰经济学讲义 |薛兆丰|2020/1/13 8:11:05|边际就是“新增”带来的“新增”。\n')
def test_format_data(self):
t_books = self.cre_tbooks()
t_out = self.km.format_data(t_books, ft='MD')
self.assertEqual(t_out[0], 'TYPE|BOOKNAME|AUTHOR|MARKTIME|CONTENT')
self.assertEqual(t_out[1], '--|--|--|--|--')
t_books = self.cre_tbooks()
self.assertEqual(t_out[2], 'HL|薛兆丰经济学讲义|薛兆丰|2020/1/13 8:11:05|边际就是“新增”带来的“新增”。\n')
t_out.clear()
def test_add_note_to_highlight(self):
t_books = self.cre_tbooks()
t_books_remove_nt = self.km.add_note_to_highlight(t_books)
self.assertEqual((t_books_remove_nt['薛兆丰经济学讲义']['1']['content']).replace('\n',''),\
'边际就是“新增”带来的“新增”。'+NTPREF+ '山寨 假货 问题')
def test_get_kindle_path(self):
kp = self.km.get_kindle_path()
s = u"kindle disconnected" if not kp else u"kindle connected {}".format(kp)
print(s)
def test_get_bookname_num(self):
t_books = self.cre_tbooks()
[nu, bn] = self.km.get_bookname_num(t_books)
self.assertEqual(nu, self.t_num_nt)
self.assertEqual(bn['薛兆丰经济学讲义'],2)
def test_get_author_num(self):
t_books = self.cre_tbooks()
[nu, bn] = self.km.get_author_num(t_books)
self.assertEqual(nu, self.t_num_nt)
self.assertEqual(bn['薛兆丰'],2)
def test_filter_clips(self):
t_books = self.cre_tbooks()
# no filter
bn = self.km.filter_clips(t_books, '薛兆丰', 0)
print('filter 0 \n',bn)
bn = {}
# by bookname
bn = self.km.filter_clips(t_books, '枪炮、病菌与钢铁 : 人类社会的命运 (世纪人文系列丛书·开放人文)', 1)
print('filter 1 \n',bn)
@@ -149,17 +215,17 @@ class TestKman(unittest.TestCase):
def test_json2dict(self):
pass
def test_import_clips(self):
pass
"""
# clean
def tearDown(self):
pass
if __name__ == '__main__':
"""
suite = unittest2.TestSuite ()
suite.addTest(TestKman('test_format_data'))
suite.addTest(TestKman('test_parse_section'))
suite.addTest(TestKman('test_format_time'))
suite.addTest(TestKman('test_format_data'))

106
tthread.py Normal file
View File

@@ -0,0 +1,106 @@
import sys
import pyqtgraph as pg
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal, QTimer
import numpy as np
class PlotSin(QThread):
# 定义信号self.y 是 numpy.array所以信号数据类型为 object
signal = pyqtSignal(object)
def __init__(self, parent=None):
super().__init__()
self.y = None
self.phase = 0
def sin(self):
self.x = np.arange(0, 3.0, 0.01)
self.y = np.sin(2 * np.pi * self.x + self.phase)
self.phase += 0.1
QThread.msleep(200) # 等待200毫秒
def run(self):
for _ in range(300):
self.sin()
self.signal.emit(self.y) # 向连接槽发射信号 self.y
class PlotSin_MainWindow(QDialog):
def __init__(self):
super().__init__()
self.initUI()
self.clock_time = 0
self.timer = QTimer(self) # 生成定时器
self.timer.timeout.connect(self.clock) # 绑定计时函数 self.clock
def initUI(self):
self.creatContorls("时间显示:")
self.creatResult("函数绘制:")
layout = QHBoxLayout()
layout.addWidget(self.controlsGroup)
layout.addWidget(self.resultGroup)
self.setLayout(layout)
self.beginButton.clicked.connect(self.clock_begin)
self.setGeometry(300, 300, 600, 300)
self.setWindowTitle('Plot Sine')
self.show()
def creatContorls(self,title):
self.controlsGroup = QGroupBox(title)
self.beginButton = QPushButton("开始")
numberLabel = QLabel("运行时间:")
self.clockLabel = QLabel("")
controlsLayout = QGridLayout()
controlsLayout.addWidget(numberLabel, 0, 0)
controlsLayout.addWidget(self.clockLabel, 0, 1)
controlsLayout.addWidget(self.beginButton, 3, 0)
self.controlsGroup.setLayout(controlsLayout)
def creatResult(self,title):
self.resultGroup = QGroupBox(title)
self.guiplot = pg.PlotWidget()
gridLayout = QGridLayout()
gridLayout.addWidget(self.guiplot,0,2,2,3)
self.resultGroup.setLayout(gridLayout)
def clock_begin(self):
if not self.timer.isActive():
self.recorder_thread = PlotSin()
self.recorder_thread.signal.connect(self.displaySin) # 绑定信号槽函数
self.recorder_thread.start() # 线程执行
self.clock()
self.timer.start(1000)
else:
self.beginButton.setText("开始")
self.clockLabel.setText("")
self.recorder_thread.terminate() # 终止线程
self.timer.stop() # 终止定时器
self.clock_time = 0
text = str(self.clock_time) + "s"
self.clockLabel.setText(text)
def clock(self):
text = str(self.clock_time) + "s"
self.clockLabel.setText(text)
if self.clock_time == 0:
self.beginButton.setText("结束")
self.clock_time += 1
def plotSin(self, y):
self.guiplot.clear()
self.guiplot.plot(y)
def displaySin(self, y):
self.plotSin(y)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = PlotSin_MainWindow()
window.show()
sys.exit(app.exec_())

2
xx
View File

@@ -1 +1 @@
{"\u859b\u5146\u4e30\u7ecf\u6d4e\u5b66\u8bb2\u4e49 ": {"author": "\u859b\u5146\u4e30", "1": {"type": "HL", "position": "1408-1410", "day": "2020\u5e741\u670813\u65e5", "week": "\u661f\u671f\u4e00", "meridiem": "\u4e0a\u5348", "time": "8:11:05", "content": "\u4e48\u5230\u5e95\u4ec0\u4e48\u53eb\u8fb9\u9645\uff1f\u8fb9\u9645\u5c31\u662f\u201c\u65b0\u589e\u201d\u5e26\u6765\u7684\u201c\u65b0\u589e\u201d\u3002 \u4f8b\u5982\uff0c\u8fb9\u9645\u6210\u672c\u5c31\u662f\u6bcf\u65b0\u589e\u4e00\u4e2a\u5355\u4f4d\u4ea7\u54c1\u6240\u9700\u8981\u4ed8\u51fa\u7684\u65b0\u589e\u6210\u672c\uff1b\u8fb9\u9645\u6536\u5165\u662f\u6bcf\u591a\u5356\u4e00\u4e2a\u4ea7\u54c1\u80fd\u591f\u5e26\u6765\u7684\u65b0\u589e\u6536\u5165\uff1b\u8fb9\u9645\u4ea7\u91cf\u662f\u6bcf\u65b0\u589e\u4e00\u4efd\u6295\u5165\u6240\u5e26\u6765\u7684\u65b0\u589e\u4ea7\u91cf\uff1b\u8fb9\u9645\u6548\u7528\u662f\u6bcf\u6d88\u8017\u4e00\u4e2a\u5355\u4f4d\u7684\u5546\u54c1\u6240\u80fd\u5e26\u6765\u7684\u65b0\u589e\u4eab\u53d7\u3002"}, "2": {"type": "HL", "position": "4284-4286", "day": "2020\u5e741\u670830\u65e5", "week": "\u661f\u671f\u56db", "meridiem": "\u4e0a\u5348", "time": "10:23:58", "content": "\u4e00\u4e2a\u56fd\u5bb6\u5f88\u5927\uff0c\u8d2b\u5bcc\u6709\u5dee\u8ddd\uff0c\u5e76\u975e\u6bcf\u4e2a\u5b66\u6821\u548c\u5bb6\u957f\u90fd\u80fd\u8d1f\u62c5\u5f97\u8d77\u8fd9\u6837\u6807\u51c6\u7684\u6821\u8f66\u3002\u6807\u51c6\u592a\u9ad8\uff0c\u5c31\u4f1a\u903c\u7740\u5f88\u591a\u5b66\u6821\uff0c\u5c24\u5176\u662f\u519c\u6751\u7684\u5b66\u6821\u653e\u5f03\u63d0\u4f9b\u6821\u8f66\uff0c\u5bb6\u957f\u4eec\u5c31\u53ea\u80fd\u4f7f\u7528\u5b89\u5168\u6027\u80fd\u66f4\u4f4e\u7684\u4ea4\u901a\u5de5\u5177\uff0c\u6bd4\u5982\u81ea\u5df1\u9a91\u81ea\u884c\u8f66\u6216\u96c7\u7528\u9ed1\u8f66\u7b49\uff0c\u7ed3\u679c\u662f\u5b69\u5b50\u4eec\u4eab\u53d7\u5230\u7684\u5b89\u5168\u4fdd\u969c\u53cd\u800c\u964d\u4f4e\u4e86\u3002--CG\u6ce8:\u5c71\u5be8 \u5047\u8d27 \u95ee\u9898"}, "4": {"type": "HL", "position": "4382-4384", "day": "2020\u5e741\u670830\u65e5", "week": "\u661f\u671f\u56db", "meridiem": "\u4e0a\u5348", "time": "10:29:41", "content": "\u4e3a\u4e86\u514b\u670d\u4fe1\u606f\u4e0d\u5bf9\u79f0\uff0c\u5efa\u7acb\u4e92\u4fe1\uff0c\u4eba\u7c7b\u793e\u4f1a\u6784\u60f3\u51fa\u4e86\u5404\u79cd\u5404\u6837\u6709\u8da3\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ece\u91cd\u590d\u4ea4\u6613\u5230\u7b2c\u4e09\u65b9\u80cc\u4e66\uff0c\u4ece\u8d28\u4fdd\u3001\u5ef6\u4fdd\uff0c\u518d\u5230\u6536\u76ca\u5171\u4eab\u3002\u6b64\u5916\uff0c\u8fd8\u6709\u4e09\u79cd\u975e\u5e38\u63a5\u8fd1\u7684\u5efa\u7acb\u4fe1\u4efb\u7684\u529e\u6cd5\uff1a\u4ed8\u51fa\u6c89\u6ca1\u6210\u672c\u3001\u7ed9\u51fa\u4eba\u8d28\u6216\u8005\u7ed9\u51fa\u62b5\u62bc\u3002"}, "lines": 4}}
{"\u859b\u5146\u4e30\u7ecf\u6d4e\u5b66\u8bb2\u4e49": {"author": "\u859b\u5146\u4e30", "1": {"type": "HL", "position": "1408-1410", "day": "2020\u5e741\u670813\u65e5", "week": "\u661f\u671f\u4e00", "meridiem": "\u4e0a\u5348", "time": "8:11:05", "content": "\u4e48\u5230\u5e95\u4ec0\u4e48\u53eb\u8fb9\u9645\uff1f\u8fb9\u9645\u5c31\u662f\u201c\u65b0\u589e\u201d\u5e26\u6765\u7684\u201c\u65b0\u589e\u201d\u3002 \u4f8b\u5982\uff0c\u8fb9\u9645\u6210\u672c\u5c31\u662f\u6bcf\u65b0\u589e\u4e00\u4e2a\u5355\u4f4d\u4ea7\u54c1\u6240\u9700\u8981\u4ed8\u51fa\u7684\u65b0\u589e\u6210\u672c\uff1b\u8fb9\u9645\u6536\u5165\u662f\u6bcf\u591a\u5356\u4e00\u4e2a\u4ea7\u54c1\u80fd\u591f\u5e26\u6765\u7684\u65b0\u589e\u6536\u5165\uff1b\u8fb9\u9645\u4ea7\u91cf\u662f\u6bcf\u65b0\u589e\u4e00\u4efd\u6295\u5165\u6240\u5e26\u6765\u7684\u65b0\u589e\u4ea7\u91cf\uff1b\u8fb9\u9645\u6548\u7528\u662f\u6bcf\u6d88\u8017\u4e00\u4e2a\u5355\u4f4d\u7684\u5546\u54c1\u6240\u80fd\u5e26\u6765\u7684\u65b0\u589e\u4eab\u53d7\u3002"}, "2": {"type": "HL", "position": "4284-4286", "day": "2020\u5e741\u670830\u65e5", "week": "\u661f\u671f\u56db", "meridiem": "\u4e0a\u5348", "time": "10:23:58", "content": "\u4e00\u4e2a\u56fd\u5bb6\u5f88\u5927\uff0c\u8d2b\u5bcc\u6709\u5dee\u8ddd\uff0c\u5e76\u975e\u6bcf\u4e2a\u5b66\u6821\u548c\u5bb6\u957f\u90fd\u80fd\u8d1f\u62c5\u5f97\u8d77\u8fd9\u6837\u6807\u51c6\u7684\u6821\u8f66\u3002\u6807\u51c6\u592a\u9ad8\uff0c\u5c31\u4f1a\u903c\u7740\u5f88\u591a\u5b66\u6821\uff0c\u5c24\u5176\u662f\u519c\u6751\u7684\u5b66\u6821\u653e\u5f03\u63d0\u4f9b\u6821\u8f66\uff0c\u5bb6\u957f\u4eec\u5c31\u53ea\u80fd\u4f7f\u7528\u5b89\u5168\u6027\u80fd\u66f4\u4f4e\u7684\u4ea4\u901a\u5de5\u5177\uff0c\u6bd4\u5982\u81ea\u5df1\u9a91\u81ea\u884c\u8f66\u6216\u96c7\u7528\u9ed1\u8f66\u7b49\uff0c\u7ed3\u679c\u662f\u5b69\u5b50\u4eec\u4eab\u53d7\u5230\u7684\u5b89\u5168\u4fdd\u969c\u53cd\u800c\u964d\u4f4e\u4e86\u3002--CG\u6ce8:\u5c71\u5be8 \u5047\u8d27 \u95ee\u9898"}, "lines": 3}, "\u5e86\u4f59\u5e74(\u7cbe\u6821\u7248\uff09": {"author": "\u732b\u817b", "4": {"type": "HL", "position": "48484-48484", "day": "2020\u5e741\u670819\u65e5", "week": "\u661f\u671f\u65e5", "meridiem": "\u4e0b\u5348", "time": "8:00:29", "content": "\uff1a\u201c\u56ed\u5b50\u91cc\u7684\u62a4\u536b\u80fd\u63ba\u591a\u5c11\u4eba\u5c31\u63ba\u591a\u5c11\u4eba\uff0c\u6211\u4f1a\u6d3e\u4eba\u76ef\u7740\uff0c"}, "5": {"type": "HL", "position": "49901-49901", "day": "2020\u5e741\u670820\u65e5", "week": "\u661f\u671f\u4e00", "meridiem": "\u4e0b\u5348", "time": "7:57:10", "content": "\u53f6\u7075\u513f\u53f9\u4e86\u53e3"}, "lines": 2}}