Hello community,

here is the log from the commit of package anki for openSUSE:Factory checked in 
at 2019-05-07 23:19:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/anki (Old)
 and      /work/SRC/openSUSE:Factory/.anki.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "anki"

Tue May  7 23:19:10 2019 rev:8 rq:701161 version:2.1.12

Changes:
--------
--- /work/SRC/openSUSE:Factory/anki/anki.changes        2019-03-19 
10:03:05.711796688 +0100
+++ /work/SRC/openSUSE:Factory/.anki.new.5148/anki.changes      2019-05-07 
23:19:12.396949510 +0200
@@ -1,0 +2,23 @@
+Wed May  1 00:57:53 UTC 2019 - Carson Black <[email protected]>
+
+- Update to 2.1.12:
+  * Fix an issue that could prevent profile renaming/deletion on Windows.
+  * Fix fields appearing under editor buttons.
+  * Fix memory leak in card layout screen.
+  * Fix some issues with previewing in the Browse screen.
+  * Fix card counts not updating when a review is undone.
+  * Fix an error that could occur on startup on some Windows installs.
+  * The Mac build now uses the new hardened runtime on Mojave.
+  * Change focus outline colour on Windows.
+  * Fix an error caused by missing note types.
+  * A possible workaround for the audio player getting stuck on Macs.
+  * Display the installed version in the Windows uninstall screen.
+  * Fix an issue checking for add-on updates (thanks to Glutanimate).
+  * Disable add-on config button when not appropriate (thanks to Glutanimate).
+  * Tweaks to the deck age graph binning (thanks to Jian).
+  * Add-ons hosted on AnkiWeb can now define conflicts in the manifest file.
+  * Switch to mplayer on the alternate OS X build, as mpv was not working on 
some older machines.
+  * Make sure mpv doesn’t attempt to load scripts from default location.
+  * Other minor fixes.
+  
+-------------------------------------------------------------------

Old:
----
  anki-2.1.11-source.tgz

New:
----
  anki-2.1.12-source.tgz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ anki.spec ++++++
--- /var/tmp/diff_new_pack.xErzqF/_old  2019-05-07 23:19:12.932950636 +0200
+++ /var/tmp/diff_new_pack.xErzqF/_new  2019-05-07 23:19:12.936950644 +0200
@@ -18,7 +18,7 @@
 
 %bcond_without tests
 Name:           anki
-Version:        2.1.11
+Version:        2.1.12
 Release:        0
 Summary:        Spaced-Repetition Memory Training Program
 License:        AGPL-3.0-only

++++++ anki-2.1.11-source.tgz -> anki-2.1.12-source.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/README.md new/anki-2.1.12/README.md
--- old/anki-2.1.11/README.md   2017-11-13 02:02:38.000000000 +0100
+++ new/anki-2.1.12/README.md   2019-04-21 11:06:39.000000000 +0200
@@ -11,4 +11,7 @@
 
 To run from source, please see README.development.
 
+If you are interested in contributing changes to Anki, please
+see README.contributing before you begin work.
+
 [![Build 
Status](https://travis-ci.org/dae/anki.svg?branch=master)](https://travis-ci.org/dae/anki)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/__init__.py 
new/anki-2.1.12/anki/__init__.py
--- old/anki-2.1.11/anki/__init__.py    2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/anki/__init__.py    2019-04-15 04:17:36.000000000 +0200
@@ -10,6 +10,6 @@
 if sys.getfilesystemencoding().lower() in ("ascii", "ansi_x3.4-1968"):
     raise Exception("Anki requires a UTF-8 locale.")
 
-version="2.1.11" # build scripts grep this line, so preserve formatting
+version="2.1.12" # build scripts grep this line, so preserve formatting
 from anki.storage import Collection
 __all__ = ["Collection"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/buildhash.py 
new/anki-2.1.12/anki/buildhash.py
--- old/anki-2.1.11/anki/buildhash.py   2019-03-11 05:29:36.000000000 +0100
+++ new/anki-2.1.12/anki/buildhash.py   2019-04-21 12:03:30.000000000 +0200
@@ -1 +1 @@
-build='3cf770c7'
+build='eef86bf3'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/collection.py 
new/anki-2.1.12/anki/collection.py
--- old/anki-2.1.11/anki/collection.py  2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/anki/collection.py  2019-04-21 09:58:45.000000000 +0200
@@ -872,6 +872,9 @@
         curs.execute("update revlog set ivl=round(ivl),lastIvl=round(lastIvl) 
where ivl!=round(ivl) or lastIvl!=round(lastIvl)")
         if curs.rowcount:
             problems.append("Fixed %d review history entries with v2 scheduler 
bug." % curs.rowcount)
+        # models
+        if self.models.ensureNotEmpty():
+            problems.append("Added missing note type.")
         # and finally, optimize
         self.optimize()
         newSize = os.stat(self.path)[stat.ST_SIZE]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/models.py 
new/anki-2.1.12/anki/models.py
--- old/anki-2.1.11/anki/models.py      2019-03-11 04:49:24.000000000 +0100
+++ new/anki-2.1.12/anki/models.py      2019-04-21 09:58:28.000000000 +0200
@@ -96,10 +96,17 @@
     def flush(self):
         "Flush the registry if any models were changed."
         if self.changed:
+            self.ensureNotEmpty()
             self.col.db.execute("update col set models = ?",
                                  json.dumps(self.models))
             self.changed = False
 
+    def ensureNotEmpty(self):
+        if not self.models:
+            from anki.stdmodels import addBasicModel
+            addBasicModel(self.col)
+            return True
+
     # Retrieving and creating models
     #############################################################
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/mpv.py new/anki-2.1.12/anki/mpv.py
--- old/anki-2.1.11/anki/mpv.py 2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/anki/mpv.py 2019-04-21 10:07:23.000000000 +0200
@@ -349,8 +349,8 @@
         """Send a command to the mpv process and collect the result.
         """
         self.ensure_running()
-        self._send_message(message, timeout)
         try:
+            self._send_message(message, timeout)
             return self._get_response(timeout)
         except MPVCommandError as e:
             raise MPVCommandError("%r: %s" % (message["command"], e))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/sound.py 
new/anki-2.1.12/anki/sound.py
--- old/anki-2.1.11/anki/sound.py       2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/anki/sound.py       2019-04-15 04:17:36.000000000 +0200
@@ -90,10 +90,6 @@
 
 mpvPath, mpvEnv = _packagedCmd(["mpv"])
 
-def setMpvConfigBase(base):
-    global mpvEnv
-    mpvEnv['XDG_CONFIG_HOME'] = base
-
 class MpvManager(MPV):
 
     executable = mpvPath[0]
@@ -125,6 +121,13 @@
     def on_idle(self):
         runHook("mpvIdleHook")
 
+def setMpvConfigBase(base):
+    mpvConfPath = os.path.join(base, "mpv.conf")
+    MpvManager.default_argv += [
+        "--no-config",
+        "--include="+mpvConfPath,
+    ]
+
 mpvManager = None
 
 def setupMPV():
@@ -164,8 +167,8 @@
 
             print("terminating old mplayer process...")
             proc.kill()
-        except SystemError:
-            pass
+        except:
+            print("error iterating mplayer processes")
 
 mplayerCmd = ["mplayer", "-really-quiet", "-noautosub"]
 if isWin:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/anki/stats.py 
new/anki-2.1.12/anki/stats.py
--- old/anki-2.1.11/anki/stats.py       2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/anki/stats.py       2019-04-15 04:17:36.000000000 +0200
@@ -198,13 +198,24 @@
     # Due and cumulative due
     ######################################################################
 
-    def dueGraph(self):
+    def get_start_end_chunk(self, by='review'):
+        start = 0
         if self.type == 0:
-            start, end, chunk = 0, 31, 1
+            end, chunk = 31, 1
         elif self.type == 1:
-            start, end, chunk = 0, 52, 7
+            end, chunk = 52, 7
         elif self.type == 2:
-            start, end, chunk = 0, None, 30
+            end = None
+            if self._deckAge(by) <= 100:
+                chunk = 1
+            elif self._deckAge(by) <= 700:
+                chunk = 7
+            else:
+                chunk = 31
+        return start, end, chunk
+
+    def dueGraph(self):
+        start, end, chunk = self.get_start_end_chunk()
         d = self._due(start, end, chunk)
         yng = []
         mtr = []
@@ -229,10 +240,13 @@
         xaxis = dict(tickDecimals=0, min=-0.5)
         if end is not None:
             xaxis['max'] = end-0.5
-        txt += self._graph(id="due", data=data,
-                           ylabel2=_("Cumulative Cards"), conf=dict(
-                xaxis=xaxis, yaxes=[dict(min=0), dict(
-                    min=0, tickDecimals=0, position="right")]))
+        txt += self._graph(
+            id="due", data=data, xunit=chunk, ylabel2=_("Cumulative Cards"),
+            conf=dict(
+                xaxis=xaxis, yaxes=[
+                    dict(min=0), dict(min=0, tickDecimals=0, position="right")]
+            ),
+        )
         txt += self._dueInfo(tot, len(totd)*chunk)
         return txt
 
@@ -269,34 +283,26 @@
     ######################################################################
 
     def introductionGraph(self):
-        if self.type == 0:
-            days = 30; chunk = 1
-        elif self.type == 1:
-            days = 52; chunk = 7
-        else:
-            days = None; chunk = 30
-        return self._introductionGraph(self._added(days, chunk),
-                               days, _("Added"))
-
-    def _introductionGraph(self, data, days, title):
+        start, days, chunk = self.get_start_end_chunk()
+        data = self._added(days, chunk)
         if not data:
             return ""
-        d = data
         conf = dict(
             xaxis=dict(tickDecimals=0, max=0.5),
-            yaxes=[dict(min=0), dict(position="right",min=0)])
+            yaxes=[dict(min=0), dict(position="right", min=0)])
         if days is not None:
+            # pylint: disable=invalid-unary-operand-type
             conf['xaxis']['min'] = -days+0.5
         def plot(id, data, ylabel, ylabel2):
             return self._graph(
-                id, data=data, conf=conf, ylabel=ylabel, ylabel2=ylabel2)
+                id, data=data, conf=conf, xunit=chunk, ylabel=ylabel, 
ylabel2=ylabel2)
         # graph
-        (repdata, repsum) = self._splitRepData(d, ((1, colLearn, ""),))
+        repdata, repsum = self._splitRepData(data, ((1, colLearn, ""),))
         txt = self._title(
-            title, _("The number of new cards you have added."))
+            _("Added"), _("The number of new cards you have added."))
         txt += plot("intro", repdata, ylabel=_("Cards"), ylabel2=_("Cumulative 
Cards"))
         # total and per day average
-        tot = sum([i[1] for i in d])
+        tot = sum([i[1] for i in data])
         period = self._periodDays()
         if not period:
             # base off date of earliest added card
@@ -309,45 +315,35 @@
         return txt
 
     def repsGraphs(self):
-        if self.type == 0:
-            days = 30; chunk = 1
-        elif self.type == 1:
-            days = 52; chunk = 7
-        else:
-            days = None; chunk = 30
-        return self._repsGraphs(self._done(days, chunk),
-                               days,
-                               _("Review Count"),
-                               _("Review Time"))
-
-    def _repsGraphs(self, data, days, reptitle, timetitle):
+        start, days, chunk = self.get_start_end_chunk()
+        data = self._done(days, chunk)
         if not data:
             return ""
-        d = data
         conf = dict(
             xaxis=dict(tickDecimals=0, max=0.5),
-            yaxes=[dict(min=0), dict(position="right",min=0)])
+            yaxes=[dict(min=0), dict(position="right", min=0)])
         if days is not None:
+            # pylint: disable=invalid-unary-operand-type
             conf['xaxis']['min'] = -days+0.5
         def plot(id, data, ylabel, ylabel2):
             return self._graph(
-                id, data=data, conf=conf, ylabel=ylabel, ylabel2=ylabel2)
+                id, data=data, conf=conf, xunit=chunk, ylabel=ylabel, 
ylabel2=ylabel2)
         # reps
-        (repdata, repsum) = self._splitRepData(d, (
+        (repdata, repsum) = self._splitRepData(data, (
             (3, colMature, _("Mature")),
             (2, colYoung, _("Young")),
             (4, colRelearn, _("Relearn")),
             (1, colLearn, _("Learn")),
             (5, colCram, _("Cram"))))
         txt1 = self._title(
-            reptitle, _("The number of questions you have answered."))
+            _("Review Count"), _("The number of questions you have answered."))
         txt1 += plot("reps", repdata, ylabel=_("Answers"), ylabel2=_(
             "Cumulative Answers"))
         (daysStud, fstDay) = self._daysStudied()
         rep, tot = self._ansInfo(repsum, daysStud, fstDay, _("reviews"))
         txt1 += rep
         # time
-        (timdata, timsum) = self._splitRepData(d, (
+        (timdata, timsum) = self._splitRepData(data, (
             (8, colMature, _("Mature")),
             (7, colYoung, _("Young")),
             (9, colRelearn, _("Relearn")),
@@ -359,7 +355,7 @@
         else:
             t = _("Hours")
             convHours = True
-        txt2 = self._title(timetitle, _("The time taken to answer the 
questions."))
+        txt2 = self._title(_("Review Time"), _("The time taken to answer the 
questions."))
         txt2 += plot("time", timdata, ylabel=t, ylabel2=_("Cumulative %s") % t)
         rep, tot2 = self._ansInfo(
             timsum, daysStud, fstDay, _("minutes"), convHours, total=tot)
@@ -416,7 +412,6 @@
         for (n, col, lab) in spec:
             totcnt[n] = 0
             totd[n] = []
-        sum = []
         for row in data:
             for (n, col, lab) in spec:
                 if n not in sep:
@@ -519,7 +514,7 @@
     ######################################################################
 
     def ivlGraph(self):
-        (ivls, all, avg, max_) = self._ivls()
+        (ivls, all, avg, max_), chunk = self._ivls()
         tot = 0
         totd = []
         if not ivls or not all:
@@ -535,7 +530,7 @@
             ivlmax = max(5, ivls[-1][0])
         txt = self._title(_("Intervals"),
                           _("Delays until reviews are shown again."))
-        txt += self._graph(id="ivl", ylabel2=_("Percentage"), data=[
+        txt += self._graph(id="ivl", ylabel2=_("Percentage"), xunit=chunk, 
data=[
             dict(data=ivls, color=colIvl),
             dict(data=totd, color=colCum, yaxis=2,
              bars={'show': False}, lines=dict(show=True), stack=False)
@@ -548,12 +543,8 @@
         return txt + self._lineTbl(i)
 
     def _ivls(self):
-        if self.type == 0:
-            chunk = 1; lim = " and grp <= 30"
-        elif self.type == 1:
-            chunk = 7; lim = " and grp <= 52"
-        else:
-            chunk = 30; lim = ""
+        start, end, chunk = self.get_start_end_chunk()
+        lim = "and grp <= %d" % end if end else ""
         data = [self.col.db.all("""
 select ivl / :chunk as grp, count() from cards
 where did in %s and queue = 2 %s
@@ -561,7 +552,7 @@
 order by grp""" % (self._limit(), lim), chunk=chunk)]
         return data + list(self.col.db.first("""
 select count(), avg(ivl), max(ivl) from cards where did in %s and queue = 2""" 
%
-                                         self._limit()))
+                                         self._limit())), chunk
 
     # Eases
     ######################################################################
@@ -625,12 +616,7 @@
         lim = self._revlogLimit()
         if lim:
             lims.append(lim)
-        if self.type == 0:
-            days = 30
-        elif self.type == 1:
-            days = 365
-        else:
-            days = None
+        days = self._periodDays()
         if days is not None:
             lims.append("id > %d" % (
                 (self.col.sched.dayCutoff-(days*86400))*1000))
@@ -811,7 +797,7 @@
     ######################################################################
 
     def _graph(self, id, data, conf=None,
-               type="bars", ylabel=_("Cards"), timeTicks=True, ylabel2=""):
+               type="bars", xunit=1, ylabel=_("Cards"), ylabel2=""):
         if conf is None:
             conf = {}
         # display settings
@@ -825,8 +811,7 @@
         conf['yaxis']['labelWidth'] = 40
         if 'xaxis' not in conf:
             conf['xaxis'] = {}
-        if timeTicks:
-            conf['timeTicks'] = (_("d"), _("w"), _("mo"))[self.type]
+        conf['timeTicks'] = {1: _("d"), 7: _("w"), 31: _("mo")}[xunit]
         # types
         width = self.width
         height = self.height
@@ -855,8 +840,6 @@
                         opacity=0.5,
                         color="#000"
                     )))
-
-            #conf['legend'] = dict(show=False)
         return (
 """
 <table cellpadding=0 cellspacing=10>
@@ -937,12 +920,10 @@
         return period
 
     def _periodDays(self):
-        if self.type == 0:
-            return 30
-        elif self.type == 1:
-            return 365
-        else:
+        start, end, chunk = self.get_start_end_chunk()
+        if end is None:
             return None
+        return end * chunk
 
     def _avgDay(self, tot, num, unit):
         vals = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/addons.py 
new/anki-2.1.12/aqt/addons.py
--- old/anki-2.1.11/aqt/addons.py       2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/addons.py       2019-04-16 09:37:00.000000000 +0200
@@ -107,8 +107,15 @@
     def toggleEnabled(self, dir, enable=None):
         meta = self.addonMeta(dir)
         enabled = enable if enable is not None else meta.get("disabled")
-        if enabled is True and not self._checkConflicts(dir):
-            return False
+        if enabled is True:
+            conflicting = self._disableConflicting(dir)
+            if conflicting:
+                addons = ", ".join(self.addonName(f) for f in conflicting)
+                showInfo(
+                    _("The following add-ons are incompatible with %(name)s \
+and have been disabled: %(found)s") % dict(name=self.addonName(dir), 
found=addons),
+                    textFormat="plain")
+
         meta['disabled'] = not enabled
         self.writeAddonMeta(dir, meta)
 
@@ -137,29 +144,19 @@
                 all_conflicts[other_dir].append(dir)
         return all_conflicts
 
-    def _checkConflicts(self, dir, name=None, conflicts=None):
-        name = name or self.addonName(dir)
+    def _disableConflicting(self, dir, conflicts=None):
         conflicts = conflicts or self.addonConflicts(dir)
 
         installed = self.allAddons()
         found = [d for d in conflicts if d in installed and self.isEnabled(d)]
         found.extend(self.allAddonConflicts().get(dir, []))
         if not found:
-            return True
+            return []
 
-        addons = "\n".join(self.addonName(f) for f in found)
-        ret = askUser(_("""\
-The following add-on(s) are incompatible with %(name)s \
-and will have to be disabled to proceed:\n\n%(found)s\n\n\
-Are you sure you want to continue?"""
-                        % dict(name=name, found=addons)))
-        if not ret:
-            return False
-        
         for package in found:
             self.toggleEnabled(package, enable=False)
         
-        return True
+        return found
 
     # Installing and deleting add-ons
     ######################################################################
@@ -182,21 +179,24 @@
 
     def install(self, file, manifest=None):
         """Install add-on from path or file-like object. Metadata is read
-        from the manifest file by default, but this may me bypassed
-        by supplying a 'manifest' dictionary"""
+        from the manifest file, with keys overriden by supplying a 'manifest'
+        dictionary"""
         try:
             zfile = ZipFile(file)
         except zipfile.BadZipfile:
             return False, "zip"
         
         with zfile:
-            manifest = manifest or self._readManifestFile(zfile)
+            file_manifest = self._readManifestFile(zfile)
+            if manifest:
+                file_manifest.update(manifest)
+            manifest = file_manifest
             if not manifest:
                 return False, "manifest"
             package = manifest["package"]
             conflicts = manifest.get("conflicts", [])
-            if not self._checkConflicts(package, manifest["name"], conflicts):
-                return False, "conflicts"
+            found_conflicts = self._disableConflicting(package,
+                                                       conflicts)
             meta = self.addonMeta(package)
             self._install(package, zfile)
         
@@ -206,7 +206,7 @@
         meta.update(manifest_meta)
         self.writeAddonMeta(package, meta)
 
-        return True, meta["name"]
+        return True, meta["name"], found_conflicts
 
     def _install(self, dir, zfile):
         # previously installed?
@@ -245,16 +245,18 @@
                 base = os.path.basename(path)
                 ret = self.install(path)
                 if ret[0] is False:
-                    if ret[1] == "conflicts":
-                        continue
-                    elif ret[1] == "zip":
+                    if ret[1] == "zip":
                         msg = _("Corrupt add-on file.")
                     elif ret[1] == "manifest":
                         msg = _("Invalid add-on manifest.")
+                    else:
+                        msg = "Unknown error: {}".format(ret[1])
                     errs.append(_("Error installing <i>%(base)s</i>: %(error)s"
                                   % dict(base=base, error=msg)))
                 else:
                     log.append(_("Installed %(name)s" % dict(name=ret[1])))
+                    if ret[2]:
+                        log.append(_("The following conflicting add-ons were 
disabled:") + " " + " ".join(ret[2]))
         finally:
             self.mw.progress.finish()
         return log, errs
@@ -278,13 +280,19 @@
                                manifest={"package": str(n), "name": name,
                                          "mod": intTime()})
             if ret[0] is False:
-                if ret[1] == "conflicts":
-                    continue
                 if ret[1] == "zip":
-                    showWarning(_("The download was corrupt. Please try 
again."))
+                    msg = _("Corrupt add-on file.")
                 elif ret[1] == "manifest":
-                    showWarning(_("Invalid add-on manifest."))
-            log.append(_("Downloaded %(fname)s" % dict(fname=name)))
+                    msg = _("Invalid add-on manifest.")
+                else:
+                    msg = "Unknown error: {}".format(ret[1])
+                errs.append(_("Error downloading %(id)s: %(error)s") % dict(
+                    id=n, error=msg))
+            else:
+                log.append(_("Downloaded %(fname)s" % dict(fname=name)))
+                if ret[2]:
+                    log.append(_("The following conflicting add-ons were 
disabled:") + " " + " ".join(ret[2]))
+
         self.mw.progress.finish()
         return log, errs
 
@@ -325,7 +333,7 @@
         updated = []
         for dir, ts in mods:
             sid = str(dir)
-            if self.addonMeta(sid).get("mod",0) < ts:
+            if self.addonMeta(sid).get("mod", 0) < (ts or 0):
                 updated.append(sid)
         return updated
 
@@ -496,7 +504,9 @@
             addon = self.addons[row_int][1]
         except IndexError:
             addon = ''
-        self.form.viewPage.setEnabled(bool (re.match(r"^\d+$", addon)))
+        self.form.viewPage.setEnabled(bool(re.match(r"^\d+$", addon)))
+        self.form.config.setEnabled(bool(self.mgr.getConfig(addon) or
+                                         self.mgr.configAction(addon)))
 
     def selectedAddons(self):
         idxs = [x.row() for x in self.form.addonList.selectedIndexes()]
@@ -565,10 +575,14 @@
         log, errs = self.mgr.processPackages(paths)
 
         if log:
-            tooltip("<br>".join(log), parent=self)
+            log_html = "<br>".join(log)
+            if len(log) == 1:
+                tooltip(log_html, parent=self)
+            else:
+                showInfo(log_html, parent=self, textFormat="rich")
         if errs:
             msg = _("Please report this to the respective add-on author(s).")
-            showWarning("\n\n".join(errs + [msg]), parent=self, 
textFormat="plain")
+            showWarning("<br><br>".join(errs + [msg]), parent=self, 
textFormat="rich")
 
         self.redrawAddons()
 
@@ -588,7 +602,11 @@
                                "\n" + "\n".join(names)):
                 log, errs = self.mgr.downloadIds(updated)
                 if log:
-                    tooltip("<br>".join(log), parent=self)
+                    log_html = "<br>".join(log)
+                    if len(log) == 1:
+                        tooltip(log_html, parent=self)
+                    else:
+                        showInfo(log_html, parent=self, textFormat="rich")
                 if errs:
                     showWarning("\n\n".join(errs), parent=self, 
textFormat="plain")
 
@@ -646,7 +664,11 @@
         log, errs = self.mgr.downloadIds(ids)
 
         if log:
-            tooltip("<br>".join(log), parent=self.addonsDlg)
+            log_html = "<br>".join(log)
+            if len(log) == 1:
+                tooltip(log_html, parent=self)
+            else:
+                showInfo(log_html, parent=self, textFormat="rich")
         if errs:
             showWarning("\n\n".join(errs), textFormat="plain")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/browser.py 
new/anki-2.1.12/aqt/browser.py
--- old/anki-2.1.11/aqt/browser.py      2019-03-11 04:40:17.000000000 +0100
+++ new/anki-2.1.12/aqt/browser.py      2019-04-15 04:19:10.000000000 +0200
@@ -1127,6 +1127,8 @@
         info, cs = self._cardInfoData()
         reps = self._revlogData(cs)
         class CardInfoDialog(QDialog):
+            silentlyClose = True
+
             def reject(self):
                 saveGeom(self, "revlog")
                 return QDialog.reject(self)
@@ -1263,6 +1265,7 @@
 
     def _openPreview(self):
         self._previewState = "question"
+        self._lastPreviewState = None
         self._previewWindow = QDialog(None, Qt.Window)
         self._previewWindow.setWindowTitle(_("Preview"))
 
@@ -1385,6 +1388,7 @@
         if not c or not self.singleCard:
             txt = _("(please select 1 card)")
             bodyclass = ""
+            self._lastPreviewState = None
         else:
             if self._previewBothSides:
                 self._previewState = "answer"
@@ -1422,7 +1426,7 @@
             txt = mungeQA(self.col, txt)
             txt = runFilter("prepareQA", txt, c,
                             "preview"+self._previewState.capitalize())
-        self._lastPreviewState = self._previewStateAndMod()
+            self._lastPreviewState = self._previewStateAndMod()
         self._updatePreviewButtons()
         self._previewWeb.eval(
             "{}({},'{}');".format(func, json.dumps(txt), bodyclass))
@@ -1437,7 +1441,9 @@
 
     def _previewStateAndMod(self):
         c = self.card
-        return (self._previewState, c.id, c.note().mod)
+        n = c.note()
+        n.load()
+        return (self._previewState, c.id, n.mod)
 
     # Card deletion
     ######################################################################
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/clayout.py 
new/anki-2.1.12/aqt/clayout.py
--- old/anki-2.1.11/aqt/clayout.py      2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/clayout.py      2019-04-15 04:17:36.000000000 +0200
@@ -552,6 +552,8 @@
         self.mm.save(self.model, templates=True)
         self.mw.reset()
         saveGeom(self, "CardLayout")
+        self.pform.frontWeb = None
+        self.pform.backWeb = None
         return QDialog.reject(self)
 
     def onHelp(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/errors.py 
new/anki-2.1.12/aqt/errors.py
--- old/anki-2.1.11/aqt/errors.py       2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/errors.py       2019-04-15 04:17:36.000000000 +0200
@@ -80,6 +80,8 @@
             return showWarning(self.tempFolderMsg())
         if "Beautiful Soup is not an HTTP client" in error:
             return
+        if "database or disk is full" in error:
+            return showWarning(_("Your computer's storage may be full. Please 
delete some unneeded files, then try again."))
         if "disk I/O error" in error:
             return showWarning(_("""\
 An error occurred while accessing the database.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/forms/icons_rc.py 
new/anki-2.1.12/aqt/forms/icons_rc.py
--- old/anki-2.1.11/aqt/forms/icons_rc.py       2019-03-11 04:34:31.000000000 
+0100
+++ new/anki-2.1.12/aqt/forms/icons_rc.py       2019-04-21 12:02:41.000000000 
+0200
@@ -9,116 +9,54 @@
 from PyQt5 import QtCore
 
 qt_resource_data = b"\
-\x00\x00\x06\xb8\
+\x00\x00\x02\xd7\
 \x89\
 \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
-\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
-\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
-\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\
-\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
-\xd7\x07\x04\x11\x23\x35\x0b\x53\xb7\x75\x00\x00\x06\x45\x49\x44\
-\x41\x54\x58\xc3\xa5\x97\xdd\x6f\x53\xc9\x19\x87\x9f\x33\x33\xc7\
-\xc7\x07\x3b\x8e\x93\x98\xac\x0d\x74\x93\x10\xb3\x0d\xa1\x1f\x44\
-\x2a\x52\x43\xa1\x12\xbd\x43\xea\x6a\xb9\x58\x40\x6a\xd4\xa5\xe5\
-\x1f\xe8\x1f\xd0\xcb\x5e\xb4\x17\xdb\xab\xed\x55\xa5\xb6\x5c\xb4\
-\xf4\x82\xad\xa8\x8a\x44\xb9\x08\xbb\x02\xb4\x04\x2a\x05\x89\x6c\
-\x8d\x8d\x12\x05\x27\xa4\x09\x6d\xec\x26\xc1\x1f\x27\xc9\xb1\x67\
-\x7a\x91\xf5\x91\x49\x1c\x62\xca\x48\xaf\x66\x34\x3e\x3a\xef\x33\
-\xbf\xf7\xc3\x73\x2c\xf6\x18\xe7\xce\x9d\x8b\x1b\x63\x12\xc6\x18\
-\xc7\x18\xc3\x76\xd3\x5a\xd3\x6a\xdf\x18\x03\xe0\x6b\xad\x97\x36\
-\x37\x37\xcb\x13\x13\x13\xa6\xd5\xfb\xad\xdd\x1c\x9f\x3f\x7f\xde\
-\xd5\x5a\x8f\x19\x63\x2e\x34\x03\x68\xad\x01\x5e\xeb\xb8\xe9\x39\
-\x5f\x6b\xbd\x68\x8c\xb9\xd5\xdb\xdb\xfb\xc9\xb5\x6b\xd7\x4c\x5b\
-\x00\x63\x63\x63\xae\xd6\xfa\x9a\x6d\xdb\x67\xbb\xbb\xbb\x45\x38\
-\x1c\x46\x29\xb5\xfd\x74\xaf\x3b\x39\xc6\x18\x7c\xdf\xa7\x54\x2a\
-\x51\x2c\x16\xa9\x54\x2a\x7f\x16\x42\xfc\x6c\x7c\x7c\x7c\xb9\xd9\
-\x97\x6a\x05\x20\x84\x18\x0b\x87\xc3\x67\x93\xc9\xa4\x70\x1c\x67\
-\x2f\x99\x77\xfd\xcd\x71\x1c\x42\xa1\x10\xd1\x68\x94\x67\xcf\x9e\
-\x7d\xe0\xfb\xfe\x7d\xe0\x37\xaf\xf8\xda\xee\xfc\xf2\xe5\xcb\x71\
-\xa5\xd4\x85\x54\x2a\x25\x62\xb1\x18\xa1\x50\x88\x50\x28\x84\x6d\
-\xdb\x28\xa5\x76\x98\x94\x72\x87\x85\xc3\x61\xd2\xe9\x34\x1d\x1d\
-\x1d\x48\x29\x71\x5d\x97\x03\x07\x0e\xec\x53\x4a\x7d\xb4\xdd\xdf\
-\x0e\x05\xa4\x94\x09\x63\x4c\x22\x16\x8b\xa1\x94\x42\x6b\xfd\x8a\
-\xb5\x4a\xbc\xee\xee\x6e\xf6\xef\xdf\x4f\xb1\x58\xa4\x5a\xad\x72\
-\xfa\xf4\x69\x06\x0e\x1f\xe6\xaf\xd7\xaf\x33\x37\x37\x87\x31\x06\
-\xd7\x75\x71\x1c\xe7\xe8\x9e\x00\x4a\x29\x07\x70\x22\x91\x48\x4b\
-\xc7\x8d\x75\xbd\x5e\x0f\xf6\x1c\xc7\xe1\x83\x0f\x2f\xf2\xef\x72\
-\x1d\x47\x68\xfe\x59\xac\x51\x40\x04\x0a\x18\x63\x1a\x4a\x46\xdb\
-\x01\xc0\x18\x13\x9c\x7e\xbb\xe3\xc6\x5a\x08\x11\xac\xd7\xd6\xd6\
-\x58\x29\x7b\xdc\x9a\xad\x51\xf5\x35\x45\x4f\xf3\xa3\x63\x51\x06\
-\x06\x06\x98\x9e\x9e\x0e\x9e\x57\x6a\x67\xca\x89\x56\x00\x4a\x29\
-\x6c\xdb\x7e\xad\x35\x72\xa3\x91\x1f\xac\x97\xf8\x5a\x87\x42\x5a\
-\x16\x07\xa2\x8a\x6c\x61\x93\x77\xbf\x71\x82\x0b\x17\x2f\x92\x48\
-\x24\x82\xf7\xfe\xdf\x0a\xec\xa6\x84\xd6\x9a\x74\x3a\x8d\x8c\x76\
-\xb3\xb9\xb6\x49\x2a\x2a\x51\xc2\xa2\x3f\xae\x08\x49\x8b\xae\x78\
-\x9c\x68\x34\x1a\x24\xe8\x9e\x00\xb9\x5c\x0e\x29\x25\x87\x0e\x1d\
-\x42\x08\x11\x9c\xb2\x39\x21\x9b\x01\x6c\xdb\x66\x70\x70\x10\xc7\
-\x6c\xf0\xfd\x94\x45\x4d\xb8\x14\xbc\x3a\x87\x42\x1e\xf7\xef\xdc\
-\x27\x93\xc9\x50\xab\xd5\x90\x52\xb6\xa7\xc0\x8d\x1b\x37\xb0\x2c\
-\x8b\xce\xce\x4e\xa4\x94\x81\xc4\x91\x48\x84\x78\x3c\x4e\x6f\x6f\
-\x2f\x52\xca\x00\x00\xe0\xf1\xe3\xc7\x38\xb9\x1c\x00\xa3\x27\x4f\
-\x32\xd8\xd5\x43\x7e\x66\x89\x99\x99\x99\x20\xf6\xf5\x7a\xbd\x3d\
-\x80\x46\x63\xb1\x2c\x8b\x5a\xad\x86\xef\xfb\x68\xad\x29\x14\x0a\
-\xe4\xf3\x79\xa4\x94\xf4\xf4\xf4\x90\x4a\xa5\x88\x46\xa3\x44\x22\
-\x11\x2a\x95\x0a\xe5\x72\x19\xad\x35\x9f\x7f\xf6\x19\xa3\xa3\xa3\
-\x64\x32\x99\x40\xc1\x06\x6c\xdb\x00\x5f\xf5\x83\x20\xd3\x9b\x33\
-\xde\x18\x83\x94\x92\xa9\xa9\x29\xc2\xe1\x30\x9d\x9d\x9d\x24\x12\
-\x09\x92\xc9\x24\x4a\x29\x2a\x95\x0a\x13\x13\x13\x94\x4a\xa5\x20\
-\x9f\x1a\xce\xdf\x18\xa0\xa1\x44\x63\x16\x42\x30\x32\x32\xc2\x47\
-\x3f\xf9\x29\xb3\x33\xd3\x5c\xb9\x72\x85\xa5\xa5\x25\x16\x17\x17\
-\xc9\x64\x32\x1c\x3c\x78\x90\xbe\xbe\x3e\x2c\xcb\x42\x29\x85\x10\
-\x22\x00\xd8\x2d\x04\x62\x37\x80\x46\x9b\xdd\xde\x6e\x47\x47\x47\
-\x19\x5f\x94\x74\xf6\x0d\x73\xe6\xcc\x99\x60\x5f\x6b\xcd\xfc\xfc\
-\x3c\x93\x93\x93\x64\xb3\x59\x7c\xdf\x0f\xda\x77\x73\x1b\x7f\xab\
-\x10\x84\xc3\x61\x06\x87\xbf\xc5\x2f\x6e\xae\xf2\x47\x0b\x7e\x7b\
-\xf6\x7d\x72\xb9\x1c\xb9\x5c\x2e\xe8\x8c\x9e\xe7\x31\x37\x37\xc7\
-\xc2\xc2\x02\xa9\x54\x8a\x81\x81\x01\x62\xb1\x58\x00\xf1\x56\x21\
-\x18\x1e\x1e\x66\xb1\x2a\xf8\x57\xa9\x46\x7e\xb5\xc6\xa7\x39\x8f\
-\x4b\x97\x2e\x31\x3b\x3b\x1b\x54\x44\xa1\x50\xe0\xde\xbd\x7b\xbc\
-\x78\xf1\x82\x85\x85\x05\x0a\x85\x02\xa9\x54\x8a\x74\x3a\xfd\x66\
-\x00\x4a\x29\x2c\xcb\x22\x99\x4c\xd2\xd5\xd5\xc5\xf0\xf0\x30\xef\
-\x7d\x7d\x88\xeb\x73\x1b\xac\xd7\x0c\x11\xdb\xe2\x57\xf7\x57\xd0\
-\x27\xe3\xa8\xc8\xb7\x11\xd6\xd6\xe5\xe2\xe2\x77\xa3\xb8\xae\xcb\
-\xd5\xab\x57\x31\xc6\xb0\xb9\xb9\x49\x3e\x9f\x27\x9f\xcf\x6f\x75\
-\xcc\x76\x01\x1c\xc7\xe1\xc4\x89\x13\x9c\x3a\x75\x0a\xe1\x76\xf0\
-\x65\x41\xf3\xa7\x99\x0d\xbe\x78\xee\xd1\x1d\x96\x84\x84\x45\xb5\
-\x66\xf8\xe5\x17\xab\x78\xbe\xa1\xea\x6b\xce\xf4\xef\xe3\xdc\x80\
-\x60\x7a\x7a\x7a\x87\x82\x2b\x2b\x2b\x3c\x7a\xf4\xa8\x7d\x80\x48\
-\x24\xc2\xd0\xd0\x10\x2b\x56\x8c\xbf\x7d\x59\xe1\xf9\xcb\x1a\x5e\
-\xcd\x20\x85\xe1\x9d\x88\x60\x9f\x6d\xe1\x7d\xa5\x84\xe7\x1b\x8e\
-\xee\x77\xf9\xf8\x07\x5d\x8c\xff\xfd\x2f\x64\x32\x99\xa0\x73\x36\
-\x00\xa4\x94\xac\xaf\xaf\xb7\x5f\x05\xeb\xeb\xeb\xdc\xbd\x7b\x97\
-\x2e\xca\x7c\x78\x34\x4a\xba\xcb\xa6\x27\x2c\xe9\x71\x25\xdd\xae\
-\xa4\xc7\x15\x81\x25\xa3\x92\x9f\x7f\x2f\x4e\xf9\x79\x96\x07\x13\
-\x13\x08\x21\x82\x0a\x6a\xae\x22\xcb\xb2\xda\x07\x90\x52\xb2\xb8\
-\xb8\xc8\x1f\x7e\xff\x3b\x96\xb2\x93\xfc\xf8\xd8\x3e\x4e\xbf\x1b\
-\xa6\x37\x22\x79\x67\x9b\x1d\xea\x90\xbc\xd7\x69\x78\xf8\xf0\x21\
-\x5a\xeb\x1d\x37\xa4\x06\x44\xcb\x5c\xdb\xab\x0a\xaa\xd5\x2a\xb7\
-\x6f\xdf\xc6\x75\x5d\x8e\xf5\x0f\x93\x5f\xab\xe1\x29\x83\x23\xb7\
-\x72\x20\x24\xb7\x42\xb0\x50\x15\xf4\xf7\xf7\xf3\xe4\xc9\x93\x57\
-\xa4\x6f\xcc\x42\x88\x37\x53\xa0\xf9\xde\x67\x8c\xa1\x5c\x2e\x63\
-\x4b\x2b\x38\xf5\x50\x4f\x88\xef\xa4\x1c\x06\xbb\x6c\x92\x51\x49\
-\xb6\xe0\x73\x7c\x64\x64\xd7\xbb\x63\xab\x12\x7c\xa3\x3e\x60\xdb\
-\x36\xb6\x80\x84\x2b\x70\x3b\x2c\x8e\x74\x87\x70\x6d\x8b\xe5\x6a\
-\x9d\xe7\x2f\x6b\xfc\xa7\x52\x27\x1c\xdb\xba\x1b\x2e\x2f\x2f\xb7\
-\xad\x40\x2b\x80\x0d\x60\xa3\x5c\x2e\x13\x8b\xc5\x82\x2e\x68\xdb\
-\x36\xae\xb2\xf8\x66\x6f\x08\x55\x5b\xe7\xfe\xdd\x71\xb2\xd9\x2c\
-\x47\x8e\x1c\xe1\xf0\xe1\xc3\x1c\x4d\xa5\x60\xa3\x12\xfc\xf1\x6c\
-\xbf\xba\xd5\xeb\x75\x7c\xdf\x2f\xb7\x03\x50\x00\x0a\xf3\xf3\xf3\
-\x1c\x3f\x7e\x3c\x88\xe7\xea\xea\x2a\x61\x65\x51\x5d\xfb\x2f\x9f\
-\xdf\xbb\x47\x2e\x97\x43\x6b\xcd\xe4\xe4\x24\x53\x53\x53\x24\x12\
-\x09\x00\x3c\xcf\x0b\x32\xbe\xb9\x95\x97\x4a\x25\x3c\xcf\xcb\xee\
-\x50\xba\x55\x05\x02\xce\xf2\xf2\xf2\x0f\xfb\xfa\xfa\xac\x78\x3c\
-\x8e\x10\x82\x95\x95\x15\x9e\x3e\x7d\xca\x83\x07\x0f\x28\x16\x8b\
-\x81\x03\xcb\xb2\xd0\x5a\x53\x2e\x97\x79\xf9\xf2\x25\x96\x65\xed\
-\xb0\xd5\xd5\x55\x6e\xde\xbc\x59\xf5\x3c\xef\xd7\xc0\x3f\xf6\x02\
-\x00\xc8\x56\x2a\x95\x91\x7c\x3e\x9f\xee\xe8\xe8\xb0\x5c\xd7\xc5\
-\xb6\x6d\x3c\xcf\x0b\xe2\xda\x6c\x0d\x90\xe6\x19\xa0\x5a\xad\x92\
-\xcd\x66\xb9\x73\xe7\x0e\x85\x42\xe1\x53\xe0\x63\xa0\xda\xd6\xc7\
-\x29\xe0\x02\x63\xc0\x05\x20\x01\x38\xbc\xf9\xf0\x81\x45\xe0\x16\
-\xf0\x09\xd0\xde\xc7\xe9\xb6\x11\x7f\x4b\x80\x25\xa0\xdc\xca\x39\
-\xc0\xff\x00\x27\xf2\xcd\xbe\x4f\x7b\xc5\xe3\x00\x00\x00\x00\x49\
-\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x3c\x00\x00\x00\x3c\x08\x06\x00\x00\x00\x3a\xfc\xd9\x72\
+\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\
+\x00\x41\x64\x6f\x62\x65\x20\x49\x6d\x61\x67\x65\x52\x65\x61\x64\
+\x79\x71\xc9\x65\x3c\x00\x00\x02\x79\x49\x44\x41\x54\x78\xda\xec\
+\x9a\xd1\x6d\xc2\x30\x10\x40\x0d\x62\x80\x6c\x40\x3a\x01\xde\xa0\
+\x19\x21\x23\xa4\x13\xc0\x06\xf5\x06\xa8\x13\xa4\x1b\xa4\x1b\x44\
+\x4c\x10\x98\x20\x6c\x10\x36\x68\x8d\xe4\x48\xc8\x75\x82\xef\xb0\
+\x0f\x87\xf8\xa4\xfb\x31\x89\xc3\xf3\x9d\xed\xbb\xb3\x17\x8c\x56\
+\xb8\xd4\x5c\xea\x46\x6a\xa2\xda\x2e\x52\x4f\x52\x7f\xa4\x1e\xd9\
+\x8b\xc8\x15\xb2\x91\xfa\x7b\x47\x5b\xf5\xec\x64\xe5\x6a\xc5\xca\
+\x02\x54\xd7\xea\xc6\x03\x26\x05\xdb\x20\x60\x7b\x6d\xd4\x14\x98\
+\x05\x6c\xaf\xdd\x54\x2c\xed\x02\xf6\xd6\xd2\x41\x8b\x70\x08\xdb\
+\xab\x08\x15\x36\xf5\x00\xdb\x6b\x1a\x22\x70\xe9\x11\xb8\x9e\x93\
+\x75\x9d\x59\x79\xe9\x10\x78\x4b\x30\xa8\xdb\x90\x2c\xdc\x12\x58\
+\xb8\x0b\x05\x96\x13\xc0\xf6\xca\x43\x70\xe9\x8c\x38\x2e\x47\xcb\
+\xea\x0e\x04\x57\x19\xcc\x59\xe9\x90\x6c\x08\x81\x37\x3e\x81\x3f\
+\xb5\xb6\x2b\xfc\x97\xd4\x6f\xc3\x0a\x4d\xb9\x1b\xe8\x61\x6c\xae\
+\xda\xfb\xb4\x93\xab\xb4\xf3\x0d\x02\x3c\x34\x57\xd3\x27\xbb\x34\
+\x1f\xd8\xff\x4d\xf1\x3c\x68\x0e\xbf\x0f\xb4\x87\x96\xa4\x5f\x7c\
+\x2f\x5a\x17\x36\x61\x59\xb2\x99\xc9\x12\x61\xc9\xf4\x55\x81\x4f\
+\x13\x01\x4e\x7c\xbb\xf4\xfa\xc9\x0b\xd9\xd1\x62\xd5\x1e\xfc\x4f\
+\x4b\x40\xc7\x63\x1f\x38\x3f\x71\x55\xe6\x90\x29\x89\x05\x4e\x2c\
+\xdd\xdf\x87\x1c\x2c\x23\xaf\x03\xa6\xf3\x6e\x20\x80\xcf\x0d\x81\
+\x07\x55\xf2\x90\x21\xff\xa3\x95\x0c\xd5\x94\x4b\xc0\xe0\xf8\x4c\
+\x0f\xf3\x91\x67\x51\xd5\xce\x02\xd0\x61\x49\x00\x5c\x5a\x7e\x13\
+\x5d\xe9\x4c\x98\x7d\x25\x91\x13\xbb\xf3\x58\x49\x69\xf7\xc8\x22\
+\x51\x31\xfb\x22\x79\x4d\x58\xc4\x2b\x7d\xd5\xbe\x32\x80\x95\xb3\
+\x00\xac\x5b\xfa\xae\x57\x71\x82\xb9\x5c\x01\x3c\xc9\x49\xaa\x3a\
+\xb6\x1a\x36\x9a\x6b\x27\x8e\x0b\x7a\xad\xd6\xbf\x60\x44\xb5\xeb\
+\x1a\xe0\x46\xdc\xd1\x36\xd5\x69\x1e\x94\xfb\x2c\xf0\x41\x2b\x93\
+\xae\xa1\x75\xd8\x7b\xfd\xed\x7d\x84\x75\x02\x01\x8d\x39\x49\x6c\
+\x80\xb0\x2d\xf3\x78\xac\x5a\x33\xd8\xe9\x7d\xa2\x06\xaa\xb3\xb4\
+\xaa\xd0\xde\x2f\x98\xe7\x5a\xb5\x4d\x30\xd2\x58\x2c\x34\x99\xe1\
+\xbd\x42\x0d\x48\xab\x3d\x5b\xa9\xdf\xf4\x81\xb2\xb9\x2e\x51\x50\
+\x55\x0e\x3b\xcb\xed\x04\x13\x04\xec\x2c\xfb\x17\x94\x95\x06\xc8\
+\xa2\x54\x1b\x2c\x68\xea\x6f\x0f\xe8\x13\x15\x60\x2c\x1e\x84\x4e\
+\x95\x15\x21\x73\xe8\x6c\x28\x18\x40\x83\x85\x0f\xf6\xff\x30\x80\
+\xb4\xa6\x84\xb9\x9a\x84\xdd\xaa\x82\xb9\xc7\xb5\x63\x7e\x73\xe2\
+\x9a\x05\x78\xa3\x27\xf1\x10\x4b\x4f\xe2\x76\x5e\xaa\xc0\x1f\xb1\
+\x78\x43\xb5\xe5\xb8\xb6\x78\xa1\xe0\x5b\x4b\x6b\x0a\x36\xa1\x1b\
+\x78\xd8\xbc\x9a\x6c\x5f\x8d\x67\x4b\x11\x38\x02\x47\xe0\x08\x1c\
+\x81\x03\x92\x15\xf2\x3d\x8e\x88\x6b\x6d\x82\x89\x35\x22\x73\x32\
+\x65\x5f\xe4\x65\x1e\x4a\x15\xd1\xa5\x23\x70\x04\x9e\x8f\xfc\x09\
+\x30\x00\xa0\x1c\x74\x67\x26\xea\x15\x76\x00\x00\x00\x00\x49\x45\
+\x4e\x44\xae\x42\x60\x82\
 \x00\x00\x05\x69\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -208,95 +146,6 @@
 \x20\x20\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x20\
 \x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\
 \x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
-\x00\x00\x02\x68\
-\x00\
-\x00\x10\x25\x78\x9c\xed\x97\x5b\x6f\xd3\x30\x14\xc7\xdf\xf7\x29\
-\x8c\x25\x24\x90\x52\x5f\x13\x3b\xce\x9a\x4d\xda\x85\x09\x69\xc0\
-\x24\x36\x10\xbc\x85\xc4\x6b\xcd\xd2\x24\x4a\xb2\xb6\xfb\xf6\x9c\
-\x64\xed\xb4\x6e\xd5\x40\x88\xf1\xb2\xb4\x55\xeb\x73\x72\x7c\x2e\
-\x3f\xfb\xff\xd0\xf1\xfe\x72\x96\xa3\xb9\xad\x1b\x57\x16\x31\xe6\
-\x84\x61\x64\x8b\xb4\xcc\x5c\x31\x89\xf1\xc5\xf9\xbb\x51\x88\x51\
-\xd3\x26\x45\x96\xe4\x65\x61\x63\x5c\x94\x78\x7f\x6f\x67\xfc\xea\
-\xe8\xd3\xe1\xf9\xb7\xb3\x63\xd4\xcc\x27\xe8\xec\xe2\xe0\xf4\xfd\
-\x21\xc2\x23\x4a\xbf\xca\x43\x4a\x8f\xce\x8f\xd0\xe7\x2f\x27\x88\
-\x13\x4e\xe9\xf1\x47\x8c\xf0\xb4\x6d\xab\x88\xd2\xc5\x62\x41\x16\
-\x92\x94\xf5\x84\x9e\xd4\x49\x35\x75\x69\x43\x21\x90\x76\x81\xb0\
-\x89\x42\x32\xce\x49\xd6\x66\x18\x4a\x74\x99\x17\x2e\x6b\xa7\xd0\
-\x16\x63\xaf\x31\x9a\x5a\x37\x99\xb6\x6b\x6b\xee\xec\xe2\xa0\x5c\
-\xc6\x98\x21\x86\x54\xf7\xc1\xf7\xe7\xe0\x18\xc1\x64\x45\x13\x6f\
-\xa9\x2d\x18\x63\x5d\xad\x55\x48\xb4\xcc\x5d\x71\xb5\x2d\x90\x1b\
-\x63\x68\xff\xb4\x0f\x8d\x9a\x2a\x49\x81\x41\x55\xdb\xc6\xd6\x73\
-\xdb\x91\xb9\xc9\xc1\x71\xe9\xf2\x7c\x54\x5f\xe7\x36\xb2\x73\x5b\
-\x94\x59\xb6\x9b\xe6\xae\xda\xf4\x34\x6d\x5d\x5e\xd9\x11\x24\xb3\
-\x69\x52\x45\x75\x79\x5d\x6c\x38\x7f\x96\xae\xd8\xf4\xce\x5c\x6b\
-\xeb\xdc\xc1\x4f\xc4\x49\xb0\x0b\x4c\x10\xbc\xc6\x13\xd4\xd6\x49\
-\xd1\x5c\x96\xf5\x2c\xc6\xb3\xa4\xad\xdd\xf2\x0d\xf7\x18\xbc\xb9\
-\x37\xf2\xb9\xf6\xd8\xdb\x55\xe8\x2a\xdc\x65\x31\x4e\xcb\x3c\xb7\
-\x69\x0b\x70\xf0\x53\xdb\xb9\xd0\xfe\xe6\xfe\x3e\x47\x0d\x5b\x11\
-\xa0\xe6\xca\x00\xd7\x1b\x60\x8e\xd7\x47\xd3\x61\x5f\x1f\x4c\xb7\
-\xbe\x47\x24\x2a\xe0\xc6\xec\x62\xfa\x20\xd9\xb6\xfe\x19\x31\x7e\
-\xe0\x4b\xd9\xf7\x71\x67\x18\x41\x94\x62\xdc\x13\x84\x2b\xa5\xcc\
-\xc3\xb6\x9e\xc8\xa6\x82\x80\x73\xc8\x46\x18\xe3\x4a\xfa\x42\x78\
-\xa3\x7e\x6d\x84\x66\x06\xdc\x5a\x8b\x00\x48\x71\x61\x0c\x31\xd2\
-\x13\x21\x91\xa1\x0e\xb7\x15\xe8\x8b\x54\x49\x3b\x45\x40\xf1\x83\
-\xd2\xd2\xd3\xa7\x2a\x10\xab\x6f\x0e\xbd\xf2\x53\xa5\x42\x22\xa0\
-\x4f\xb8\xbb\x8c\xcb\x5b\xd3\x97\x9e\x14\xc4\x30\x30\xf5\xc6\x52\
-\x7f\xdf\x02\xe9\xf6\xc4\xa3\x1f\x79\x92\x5e\xad\x8f\xbf\x07\x1c\
-\xf9\xd5\xf2\x11\xc2\xbe\x27\x3a\xf9\xe7\x34\x24\x93\xc0\xc1\x13\
-\x01\x11\x81\x0a\x5e\x3a\x0d\x61\x14\xd1\xa1\x27\x41\x7b\xdc\xff\
-\x0b\x1a\xff\x77\xe0\xc7\x8e\x3f\xd7\x99\x52\x83\xce\x06\x9d\x0d\
-\x3a\x7b\x6e\x9d\xc1\xa0\x4c\x19\xe5\x8d\x84\x26\x42\x85\x6a\x10\
-\xda\x33\x5f\xad\x41\x68\x2f\x53\x68\x1a\xe6\xf7\x75\x30\x08\x6d\
-\x10\xda\x20\xb4\xdf\x0d\xbc\xe1\xb8\x33\xfa\xc5\xb8\xfb\x97\xbc\
-\xb7\xf3\x0b\x46\x33\xee\x37\
-\x00\x00\x02\xd7\
-\x89\
-\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
-\x00\x00\x3c\x00\x00\x00\x3c\x08\x06\x00\x00\x00\x3a\xfc\xd9\x72\
-\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\
-\x00\x41\x64\x6f\x62\x65\x20\x49\x6d\x61\x67\x65\x52\x65\x61\x64\
-\x79\x71\xc9\x65\x3c\x00\x00\x02\x79\x49\x44\x41\x54\x78\xda\xec\
-\x9a\xd1\x6d\xc2\x30\x10\x40\x0d\x62\x80\x6c\x40\x3a\x01\xde\xa0\
-\x19\x21\x23\xa4\x13\xc0\x06\xf5\x06\xa8\x13\xa4\x1b\xa4\x1b\x44\
-\x4c\x10\x98\x20\x6c\x10\x36\x68\x8d\xe4\x48\xc8\x75\x82\xef\xb0\
-\x0f\x87\xf8\xa4\xfb\x31\x89\xc3\xf3\x9d\xed\xbb\xb3\x17\x8c\x56\
-\xb8\xd4\x5c\xea\x46\x6a\xa2\xda\x2e\x52\x4f\x52\x7f\xa4\x1e\xd9\
-\x8b\xc8\x15\xb2\x91\xfa\x7b\x47\x5b\xf5\xec\x64\xe5\x6a\xc5\xca\
-\x02\x54\xd7\xea\xc6\x03\x26\x05\xdb\x20\x60\x7b\x6d\xd4\x14\x98\
-\x05\x6c\xaf\xdd\x54\x2c\xed\x02\xf6\xd6\xd2\x41\x8b\x70\x08\xdb\
-\xab\x08\x15\x36\xf5\x00\xdb\x6b\x1a\x22\x70\xe9\x11\xb8\x9e\x93\
-\x75\x9d\x59\x79\xe9\x10\x78\x4b\x30\xa8\xdb\x90\x2c\xdc\x12\x58\
-\xb8\x0b\x05\x96\x13\xc0\xf6\xca\x43\x70\xe9\x8c\x38\x2e\x47\xcb\
-\xea\x0e\x04\x57\x19\xcc\x59\xe9\x90\x6c\x08\x81\x37\x3e\x81\x3f\
-\xb5\xb6\x2b\xfc\x97\xd4\x6f\xc3\x0a\x4d\xb9\x1b\xe8\x61\x6c\xae\
-\xda\xfb\xb4\x93\xab\xb4\xf3\x0d\x02\x3c\x34\x57\xd3\x27\xbb\x34\
-\x1f\xd8\xff\x4d\xf1\x3c\x68\x0e\xbf\x0f\xb4\x87\x96\xa4\x5f\x7c\
-\x2f\x5a\x17\x36\x61\x59\xb2\x99\xc9\x12\x61\xc9\xf4\x55\x81\x4f\
-\x13\x01\x4e\x7c\xbb\xf4\xfa\xc9\x0b\xd9\xd1\x62\xd5\x1e\xfc\x4f\
-\x4b\x40\xc7\x63\x1f\x38\x3f\x71\x55\xe6\x90\x29\x89\x05\x4e\x2c\
-\xdd\xdf\x87\x1c\x2c\x23\xaf\x03\xa6\xf3\x6e\x20\x80\xcf\x0d\x81\
-\x07\x55\xf2\x90\x21\xff\xa3\x95\x0c\xd5\x94\x4b\xc0\xe0\xf8\x4c\
-\x0f\xf3\x91\x67\x51\xd5\xce\x02\xd0\x61\x49\x00\x5c\x5a\x7e\x13\
-\x5d\xe9\x4c\x98\x7d\x25\x91\x13\xbb\xf3\x58\x49\x69\xf7\xc8\x22\
-\x51\x31\xfb\x22\x79\x4d\x58\xc4\x2b\x7d\xd5\xbe\x32\x80\x95\xb3\
-\x00\xac\x5b\xfa\xae\x57\x71\x82\xb9\x5c\x01\x3c\xc9\x49\xaa\x3a\
-\xb6\x1a\x36\x9a\x6b\x27\x8e\x0b\x7a\xad\xd6\xbf\x60\x44\xb5\xeb\
-\x1a\xe0\x46\xdc\xd1\x36\xd5\x69\x1e\x94\xfb\x2c\xf0\x41\x2b\x93\
-\xae\xa1\x75\xd8\x7b\xfd\xed\x7d\x84\x75\x02\x01\x8d\x39\x49\x6c\
-\x80\xb0\x2d\xf3\x78\xac\x5a\x33\xd8\xe9\x7d\xa2\x06\xaa\xb3\xb4\
-\xaa\xd0\xde\x2f\x98\xe7\x5a\xb5\x4d\x30\xd2\x58\x2c\x34\x99\xe1\
-\xbd\x42\x0d\x48\xab\x3d\x5b\xa9\xdf\xf4\x81\xb2\xb9\x2e\x51\x50\
-\x55\x0e\x3b\xcb\xed\x04\x13\x04\xec\x2c\xfb\x17\x94\x95\x06\xc8\
-\xa2\x54\x1b\x2c\x68\xea\x6f\x0f\xe8\x13\x15\x60\x2c\x1e\x84\x4e\
-\x95\x15\x21\x73\xe8\x6c\x28\x18\x40\x83\x85\x0f\xf6\xff\x30\x80\
-\xb4\xa6\x84\xb9\x9a\x84\xdd\xaa\x82\xb9\xc7\xb5\x63\x7e\x73\xe2\
-\x9a\x05\x78\xa3\x27\xf1\x10\x4b\x4f\xe2\x76\x5e\xaa\xc0\x1f\xb1\
-\x78\x43\xb5\xe5\xb8\xb6\x78\xa1\xe0\x5b\x4b\x6b\x0a\x36\xa1\x1b\
-\x78\xd8\xbc\x9a\x6c\x5f\x8d\x67\x4b\x11\x38\x02\x47\xe0\x08\x1c\
-\x81\x03\x92\x15\xf2\x3d\x8e\x88\x6b\x6d\x82\x89\x35\x22\x73\x32\
-\x65\x5f\xe4\x65\x1e\x4a\x15\xd1\xa5\x23\x70\x04\x9e\x8f\xfc\x09\
-\x30\x00\xa0\x1c\x74\x67\x26\xea\x15\x76\x00\x00\x00\x00\x49\x45\
-\x4e\x44\xae\x42\x60\x82\
 \x00\x00\x04\x06\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -364,6 +213,116 @@
 \x20\x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\
 \x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\
 \x73\x76\x67\x3e\x0a\
+\x00\x00\x06\xb8\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
+\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
+\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\
+\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
+\xd7\x07\x04\x11\x23\x35\x0b\x53\xb7\x75\x00\x00\x06\x45\x49\x44\
+\x41\x54\x58\xc3\xa5\x97\xdd\x6f\x53\xc9\x19\x87\x9f\x33\x33\xc7\
+\xc7\x07\x3b\x8e\x93\x98\xac\x0d\x74\x93\x10\xb3\x0d\xa1\x1f\x44\
+\x2a\x52\x43\xa1\x12\xbd\x43\xea\x6a\xb9\x58\x40\x6a\xd4\xa5\xe5\
+\x1f\xe8\x1f\xd0\xcb\x5e\xb4\x17\xdb\xab\xed\x55\xa5\xb6\x5c\xb4\
+\xf4\x82\xad\xa8\x8a\x44\xb9\x08\xbb\x02\xb4\x04\x2a\x05\x89\x6c\
+\x8d\x8d\x12\x05\x27\xa4\x09\x6d\xec\x26\xc1\x1f\x27\xc9\xb1\x67\
+\x7a\x91\xf5\x91\x49\x1c\x62\xca\x48\xaf\x66\x34\x3e\x3a\xef\x33\
+\xbf\xf7\xc3\x73\x2c\xf6\x18\xe7\xce\x9d\x8b\x1b\x63\x12\xc6\x18\
+\xc7\x18\xc3\x76\xd3\x5a\xd3\x6a\xdf\x18\x03\xe0\x6b\xad\x97\x36\
+\x37\x37\xcb\x13\x13\x13\xa6\xd5\xfb\xad\xdd\x1c\x9f\x3f\x7f\xde\
+\xd5\x5a\x8f\x19\x63\x2e\x34\x03\x68\xad\x01\x5e\xeb\xb8\xe9\x39\
+\x5f\x6b\xbd\x68\x8c\xb9\xd5\xdb\xdb\xfb\xc9\xb5\x6b\xd7\x4c\x5b\
+\x00\x63\x63\x63\xae\xd6\xfa\x9a\x6d\xdb\x67\xbb\xbb\xbb\x45\x38\
+\x1c\x46\x29\xb5\xfd\x74\xaf\x3b\x39\xc6\x18\x7c\xdf\xa7\x54\x2a\
+\x51\x2c\x16\xa9\x54\x2a\x7f\x16\x42\xfc\x6c\x7c\x7c\x7c\xb9\xd9\
+\x97\x6a\x05\x20\x84\x18\x0b\x87\xc3\x67\x93\xc9\xa4\x70\x1c\x67\
+\x2f\x99\x77\xfd\xcd\x71\x1c\x42\xa1\x10\xd1\x68\x94\x67\xcf\x9e\
+\x7d\xe0\xfb\xfe\x7d\xe0\x37\xaf\xf8\xda\xee\xfc\xf2\xe5\xcb\x71\
+\xa5\xd4\x85\x54\x2a\x25\x62\xb1\x18\xa1\x50\x88\x50\x28\x84\x6d\
+\xdb\x28\xa5\x76\x98\x94\x72\x87\x85\xc3\x61\xd2\xe9\x34\x1d\x1d\
+\x1d\x48\x29\x71\x5d\x97\x03\x07\x0e\xec\x53\x4a\x7d\xb4\xdd\xdf\
+\x0e\x05\xa4\x94\x09\x63\x4c\x22\x16\x8b\xa1\x94\x42\x6b\xfd\x8a\
+\xb5\x4a\xbc\xee\xee\x6e\xf6\xef\xdf\x4f\xb1\x58\xa4\x5a\xad\x72\
+\xfa\xf4\x69\x06\x0e\x1f\xe6\xaf\xd7\xaf\x33\x37\x37\x87\x31\x06\
+\xd7\x75\x71\x1c\xe7\xe8\x9e\x00\x4a\x29\x07\x70\x22\x91\x48\x4b\
+\xc7\x8d\x75\xbd\x5e\x0f\xf6\x1c\xc7\xe1\x83\x0f\x2f\xf2\xef\x72\
+\x1d\x47\x68\xfe\x59\xac\x51\x40\x04\x0a\x18\x63\x1a\x4a\x46\xdb\
+\x01\xc0\x18\x13\x9c\x7e\xbb\xe3\xc6\x5a\x08\x11\xac\xd7\xd6\xd6\
+\x58\x29\x7b\xdc\x9a\xad\x51\xf5\x35\x45\x4f\xf3\xa3\x63\x51\x06\
+\x06\x06\x98\x9e\x9e\x0e\x9e\x57\x6a\x67\xca\x89\x56\x00\x4a\x29\
+\x6c\xdb\x7e\xad\x35\x72\xa3\x91\x1f\xac\x97\xf8\x5a\x87\x42\x5a\
+\x16\x07\xa2\x8a\x6c\x61\x93\x77\xbf\x71\x82\x0b\x17\x2f\x92\x48\
+\x24\x82\xf7\xfe\xdf\x0a\xec\xa6\x84\xd6\x9a\x74\x3a\x8d\x8c\x76\
+\xb3\xb9\xb6\x49\x2a\x2a\x51\xc2\xa2\x3f\xae\x08\x49\x8b\xae\x78\
+\x9c\x68\x34\x1a\x24\xe8\x9e\x00\xb9\x5c\x0e\x29\x25\x87\x0e\x1d\
+\x42\x08\x11\x9c\xb2\x39\x21\x9b\x01\x6c\xdb\x66\x70\x70\x10\xc7\
+\x6c\xf0\xfd\x94\x45\x4d\xb8\x14\xbc\x3a\x87\x42\x1e\xf7\xef\xdc\
+\x27\x93\xc9\x50\xab\xd5\x90\x52\xb6\xa7\xc0\x8d\x1b\x37\xb0\x2c\
+\x8b\xce\xce\x4e\xa4\x94\x81\xc4\x91\x48\x84\x78\x3c\x4e\x6f\x6f\
+\x2f\x52\xca\x00\x00\xe0\xf1\xe3\xc7\x38\xb9\x1c\x00\xa3\x27\x4f\
+\x32\xd8\xd5\x43\x7e\x66\x89\x99\x99\x99\x20\xf6\xf5\x7a\xbd\x3d\
+\x80\x46\x63\xb1\x2c\x8b\x5a\xad\x86\xef\xfb\x68\xad\x29\x14\x0a\
+\xe4\xf3\x79\xa4\x94\xf4\xf4\xf4\x90\x4a\xa5\x88\x46\xa3\x44\x22\
+\x11\x2a\x95\x0a\xe5\x72\x19\xad\x35\x9f\x7f\xf6\x19\xa3\xa3\xa3\
+\x64\x32\x99\x40\xc1\x06\x6c\xdb\x00\x5f\xf5\x83\x20\xd3\x9b\x33\
+\xde\x18\x83\x94\x92\xa9\xa9\x29\xc2\xe1\x30\x9d\x9d\x9d\x24\x12\
+\x09\x92\xc9\x24\x4a\x29\x2a\x95\x0a\x13\x13\x13\x94\x4a\xa5\x20\
+\x9f\x1a\xce\xdf\x18\xa0\xa1\x44\x63\x16\x42\x30\x32\x32\xc2\x47\
+\x3f\xf9\x29\xb3\x33\xd3\x5c\xb9\x72\x85\xa5\xa5\x25\x16\x17\x17\
+\xc9\x64\x32\x1c\x3c\x78\x90\xbe\xbe\x3e\x2c\xcb\x42\x29\x85\x10\
+\x22\x00\xd8\x2d\x04\x62\x37\x80\x46\x9b\xdd\xde\x6e\x47\x47\x47\
+\x19\x5f\x94\x74\xf6\x0d\x73\xe6\xcc\x99\x60\x5f\x6b\xcd\xfc\xfc\
+\x3c\x93\x93\x93\x64\xb3\x59\x7c\xdf\x0f\xda\x77\x73\x1b\x7f\xab\
+\x10\x84\xc3\x61\x06\x87\xbf\xc5\x2f\x6e\xae\xf2\x47\x0b\x7e\x7b\
+\xf6\x7d\x72\xb9\x1c\xb9\x5c\x2e\xe8\x8c\x9e\xe7\x31\x37\x37\xc7\
+\xc2\xc2\x02\xa9\x54\x8a\x81\x81\x01\x62\xb1\x58\x00\xf1\x56\x21\
+\x18\x1e\x1e\x66\xb1\x2a\xf8\x57\xa9\x46\x7e\xb5\xc6\xa7\x39\x8f\
+\x4b\x97\x2e\x31\x3b\x3b\x1b\x54\x44\xa1\x50\xe0\xde\xbd\x7b\xbc\
+\x78\xf1\x82\x85\x85\x05\x0a\x85\x02\xa9\x54\x8a\x74\x3a\xfd\x66\
+\x00\x4a\x29\x2c\xcb\x22\x99\x4c\xd2\xd5\xd5\xc5\xf0\xf0\x30\xef\
+\x7d\x7d\x88\xeb\x73\x1b\xac\xd7\x0c\x11\xdb\xe2\x57\xf7\x57\xd0\
+\x27\xe3\xa8\xc8\xb7\x11\xd6\xd6\xe5\xe2\xe2\x77\xa3\xb8\xae\xcb\
+\xd5\xab\x57\x31\xc6\xb0\xb9\xb9\x49\x3e\x9f\x27\x9f\xcf\x6f\x75\
+\xcc\x76\x01\x1c\xc7\xe1\xc4\x89\x13\x9c\x3a\x75\x0a\xe1\x76\xf0\
+\x65\x41\xf3\xa7\x99\x0d\xbe\x78\xee\xd1\x1d\x96\x84\x84\x45\xb5\
+\x66\xf8\xe5\x17\xab\x78\xbe\xa1\xea\x6b\xce\xf4\xef\xe3\xdc\x80\
+\x60\x7a\x7a\x7a\x87\x82\x2b\x2b\x2b\x3c\x7a\xf4\xa8\x7d\x80\x48\
+\x24\xc2\xd0\xd0\x10\x2b\x56\x8c\xbf\x7d\x59\xe1\xf9\xcb\x1a\x5e\
+\xcd\x20\x85\xe1\x9d\x88\x60\x9f\x6d\xe1\x7d\xa5\x84\xe7\x1b\x8e\
+\xee\x77\xf9\xf8\x07\x5d\x8c\xff\xfd\x2f\x64\x32\x99\xa0\x73\x36\
+\x00\xa4\x94\xac\xaf\xaf\xb7\x5f\x05\xeb\xeb\xeb\xdc\xbd\x7b\x97\
+\x2e\xca\x7c\x78\x34\x4a\xba\xcb\xa6\x27\x2c\xe9\x71\x25\xdd\xae\
+\xa4\xc7\x15\x81\x25\xa3\x92\x9f\x7f\x2f\x4e\xf9\x79\x96\x07\x13\
+\x13\x08\x21\x82\x0a\x6a\xae\x22\xcb\xb2\xda\x07\x90\x52\xb2\xb8\
+\xb8\xc8\x1f\x7e\xff\x3b\x96\xb2\x93\xfc\xf8\xd8\x3e\x4e\xbf\x1b\
+\xa6\x37\x22\x79\x67\x9b\x1d\xea\x90\xbc\xd7\x69\x78\xf8\xf0\x21\
+\x5a\xeb\x1d\x37\xa4\x06\x44\xcb\x5c\xdb\xab\x0a\xaa\xd5\x2a\xb7\
+\x6f\xdf\xc6\x75\x5d\x8e\xf5\x0f\x93\x5f\xab\xe1\x29\x83\x23\xb7\
+\x72\x20\x24\xb7\x42\xb0\x50\x15\xf4\xf7\xf7\xf3\xe4\xc9\x93\x57\
+\xa4\x6f\xcc\x42\x88\x37\x53\xa0\xf9\xde\x67\x8c\xa1\x5c\x2e\x63\
+\x4b\x2b\x38\xf5\x50\x4f\x88\xef\xa4\x1c\x06\xbb\x6c\x92\x51\x49\
+\xb6\xe0\x73\x7c\x64\x64\xd7\xbb\x63\xab\x12\x7c\xa3\x3e\x60\xdb\
+\x36\xb6\x80\x84\x2b\x70\x3b\x2c\x8e\x74\x87\x70\x6d\x8b\xe5\x6a\
+\x9d\xe7\x2f\x6b\xfc\xa7\x52\x27\x1c\xdb\xba\x1b\x2e\x2f\x2f\xb7\
+\xad\x40\x2b\x80\x0d\x60\xa3\x5c\x2e\x13\x8b\xc5\x82\x2e\x68\xdb\
+\x36\xae\xb2\xf8\x66\x6f\x08\x55\x5b\xe7\xfe\xdd\x71\xb2\xd9\x2c\
+\x47\x8e\x1c\xe1\xf0\xe1\xc3\x1c\x4d\xa5\x60\xa3\x12\xfc\xf1\x6c\
+\xbf\xba\xd5\xeb\x75\x7c\xdf\x2f\xb7\x03\x50\x00\x0a\xf3\xf3\xf3\
+\x1c\x3f\x7e\x3c\x88\xe7\xea\xea\x2a\x61\x65\x51\x5d\xfb\x2f\x9f\
+\xdf\xbb\x47\x2e\x97\x43\x6b\xcd\xe4\xe4\x24\x53\x53\x53\x24\x12\
+\x09\x00\x3c\xcf\x0b\x32\xbe\xb9\x95\x97\x4a\x25\x3c\xcf\xcb\xee\
+\x50\xba\x55\x05\x02\xce\xf2\xf2\xf2\x0f\xfb\xfa\xfa\xac\x78\x3c\
+\x8e\x10\x82\x95\x95\x15\x9e\x3e\x7d\xca\x83\x07\x0f\x28\x16\x8b\
+\x81\x03\xcb\xb2\xd0\x5a\x53\x2e\x97\x79\xf9\xf2\x25\x96\x65\xed\
+\xb0\xd5\xd5\x55\x6e\xde\xbc\x59\xf5\x3c\xef\xd7\xc0\x3f\xf6\x02\
+\x00\xc8\x56\x2a\x95\x91\x7c\x3e\x9f\xee\xe8\xe8\xb0\x5c\xd7\xc5\
+\xb6\x6d\x3c\xcf\x0b\xe2\xda\x6c\x0d\x90\xe6\x19\xa0\x5a\xad\x92\
+\xcd\x66\xb9\x73\xe7\x0e\x85\x42\xe1\x53\xe0\x63\xa0\xda\xd6\xc7\
+\x29\xe0\x02\x63\xc0\x05\x20\x01\x38\xbc\xf9\xf0\x81\x45\xe0\x16\
+\xf0\x09\xd0\xde\xc7\xe9\xb6\x11\x7f\x4b\x80\x25\xa0\xdc\xca\x39\
+\xc0\xff\x00\x27\xf2\xcd\xbe\x4f\x7b\xc5\xe3\x00\x00\x00\x00\x49\
+\x45\x4e\x44\xae\x42\x60\x82\
 \x00\x00\x04\x30\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -521,6 +480,47 @@
 \x20\x20\x3c\x2f\x67\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\
 \x2f\x67\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\
 \x76\x67\x3e\x0a\
+\x00\x00\x02\x68\
+\x00\
+\x00\x10\x25\x78\x9c\xed\x97\x5b\x6f\xd3\x30\x14\xc7\xdf\xf7\x29\
+\x8c\x25\x24\x90\x52\x5f\x13\x3b\xce\x9a\x4d\xda\x85\x09\x69\xc0\
+\x24\x36\x10\xbc\x85\xc4\x6b\xcd\xd2\x24\x4a\xb2\xb6\xfb\xf6\x9c\
+\x64\xed\xb4\x6e\xd5\x40\x88\xf1\xb2\xb4\x55\xeb\x73\x72\x7c\x2e\
+\x3f\xfb\xff\xd0\xf1\xfe\x72\x96\xa3\xb9\xad\x1b\x57\x16\x31\xe6\
+\x84\x61\x64\x8b\xb4\xcc\x5c\x31\x89\xf1\xc5\xf9\xbb\x51\x88\x51\
+\xd3\x26\x45\x96\xe4\x65\x61\x63\x5c\x94\x78\x7f\x6f\x67\xfc\xea\
+\xe8\xd3\xe1\xf9\xb7\xb3\x63\xd4\xcc\x27\xe8\xec\xe2\xe0\xf4\xfd\
+\x21\xc2\x23\x4a\xbf\xca\x43\x4a\x8f\xce\x8f\xd0\xe7\x2f\x27\x88\
+\x13\x4e\xe9\xf1\x47\x8c\xf0\xb4\x6d\xab\x88\xd2\xc5\x62\x41\x16\
+\x92\x94\xf5\x84\x9e\xd4\x49\x35\x75\x69\x43\x21\x90\x76\x81\xb0\
+\x89\x42\x32\xce\x49\xd6\x66\x18\x4a\x74\x99\x17\x2e\x6b\xa7\xd0\
+\x16\x63\xaf\x31\x9a\x5a\x37\x99\xb6\x6b\x6b\xee\xec\xe2\xa0\x5c\
+\xc6\x98\x21\x86\x54\xf7\xc1\xf7\xe7\xe0\x18\xc1\x64\x45\x13\x6f\
+\xa9\x2d\x18\x63\x5d\xad\x55\x48\xb4\xcc\x5d\x71\xb5\x2d\x90\x1b\
+\x63\x68\xff\xb4\x0f\x8d\x9a\x2a\x49\x81\x41\x55\xdb\xc6\xd6\x73\
+\xdb\x91\xb9\xc9\xc1\x71\xe9\xf2\x7c\x54\x5f\xe7\x36\xb2\x73\x5b\
+\x94\x59\xb6\x9b\xe6\xae\xda\xf4\x34\x6d\x5d\x5e\xd9\x11\x24\xb3\
+\x69\x52\x45\x75\x79\x5d\x6c\x38\x7f\x96\xae\xd8\xf4\xce\x5c\x6b\
+\xeb\xdc\xc1\x4f\xc4\x49\xb0\x0b\x4c\x10\xbc\xc6\x13\xd4\xd6\x49\
+\xd1\x5c\x96\xf5\x2c\xc6\xb3\xa4\xad\xdd\xf2\x0d\xf7\x18\xbc\xb9\
+\x37\xf2\xb9\xf6\xd8\xdb\x55\xe8\x2a\xdc\x65\x31\x4e\xcb\x3c\xb7\
+\x69\x0b\x70\xf0\x53\xdb\xb9\xd0\xfe\xe6\xfe\x3e\x47\x0d\x5b\x11\
+\xa0\xe6\xca\x00\xd7\x1b\x60\x8e\xd7\x47\xd3\x61\x5f\x1f\x4c\xb7\
+\xbe\x47\x24\x2a\xe0\xc6\xec\x62\xfa\x20\xd9\xb6\xfe\x19\x31\x7e\
+\xe0\x4b\xd9\xf7\x71\x67\x18\x41\x94\x62\xdc\x13\x84\x2b\xa5\xcc\
+\xc3\xb6\x9e\xc8\xa6\x82\x80\x73\xc8\x46\x18\xe3\x4a\xfa\x42\x78\
+\xa3\x7e\x6d\x84\x66\x06\xdc\x5a\x8b\x00\x48\x71\x61\x0c\x31\xd2\
+\x13\x21\x91\xa1\x0e\xb7\x15\xe8\x8b\x54\x49\x3b\x45\x40\xf1\x83\
+\xd2\xd2\xd3\xa7\x2a\x10\xab\x6f\x0e\xbd\xf2\x53\xa5\x42\x22\xa0\
+\x4f\xb8\xbb\x8c\xcb\x5b\xd3\x97\x9e\x14\xc4\x30\x30\xf5\xc6\x52\
+\x7f\xdf\x02\xe9\xf6\xc4\xa3\x1f\x79\x92\x5e\xad\x8f\xbf\x07\x1c\
+\xf9\xd5\xf2\x11\xc2\xbe\x27\x3a\xf9\xe7\x34\x24\x93\xc0\xc1\x13\
+\x01\x11\x81\x0a\x5e\x3a\x0d\x61\x14\xd1\xa1\x27\x41\x7b\xdc\xff\
+\x0b\x1a\xff\x77\xe0\xc7\x8e\x3f\xd7\x99\x52\x83\xce\x06\x9d\x0d\
+\x3a\x7b\x6e\x9d\xc1\xa0\x4c\x19\xe5\x8d\x84\x26\x42\x85\x6a\x10\
+\xda\x33\x5f\xad\x41\x68\x2f\x53\x68\x1a\xe6\xf7\x75\x30\x08\x6d\
+\x10\xda\x20\xb4\xdf\x0d\xbc\xe1\xb8\x33\xfa\xc5\xb8\xfb\x97\xbc\
+\xb7\xf3\x0b\x46\x33\xee\x37\
 "
 
 qt_resource_name = b"\
@@ -528,26 +528,22 @@
 \x00\x6f\xa6\x53\
 \x00\x69\
 \x00\x63\x00\x6f\x00\x6e\x00\x73\
-\x00\x08\
-\x05\x1c\x5a\x47\
-\x00\x61\
-\x00\x6e\x00\x6b\x00\x69\x00\x2e\x00\x70\x00\x6e\x00\x67\
-\x00\x08\
-\x0b\x9e\x57\x87\
-\x00\x64\
-\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0e\
-\x04\x44\x35\x07\
-\x00\x63\
-\x00\x6f\x00\x6c\x00\x6c\x00\x65\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x10\
 \x08\x12\xae\xa7\
 \x00\x6d\
 
\x00\x65\x00\x64\x00\x69\x00\x61\x00\x2d\x00\x72\x00\x65\x00\x63\x00\x6f\x00\x72\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x08\
+\x0b\x9e\x57\x87\
+\x00\x64\
+\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x09\
 \x08\x97\x87\xa7\
 \x00\x68\
 \x00\x65\x00\x61\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x05\x1c\x5a\x47\
+\x00\x61\
+\x00\x6e\x00\x6b\x00\x69\x00\x2e\x00\x70\x00\x6e\x00\x67\
 \x00\x07\
 \x0a\x7a\x5a\x27\
 \x00\x74\
@@ -556,18 +552,22 @@
 \x0e\xcd\x03\x47\
 \x00\x6e\
 
\x00\x6f\x00\x74\x00\x65\x00\x74\x00\x79\x00\x70\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0e\
+\x04\x44\x35\x07\
+\x00\x63\
+\x00\x6f\x00\x6c\x00\x6c\x00\x65\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
 "
 
 qt_resource_struct_v1 = b"\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\
-\x00\x00\x00\x3c\x00\x01\x00\x00\x00\x01\x00\x00\x0c\x29\
+\x00\x00\x00\xac\x00\x01\x00\x00\x00\x01\x00\x00\x1c\x9b\
+\x00\x00\x00\x64\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x52\
 \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x01\x00\x00\x0e\x95\
-\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x11\x70\
-\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x15\x7a\
-\x00\x00\x00\x26\x00\x00\x00\x00\x00\x01\x00\x00\x06\xbc\
-\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x19\xae\
+\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x08\x48\
+\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x01\x00\x00\x13\x0e\
+\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x02\xdb\
+\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x17\x42\
 "
 
 qt_resource_struct_v2 = b"\
@@ -575,19 +575,19 @@
 \x00\x00\x00\x00\x00\x00\x00\x00\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\
 \x00\x00\x00\x00\x00\x00\x00\x00\
-\x00\x00\x00\x3c\x00\x01\x00\x00\x00\x01\x00\x00\x0c\x29\
+\x00\x00\x00\xac\x00\x01\x00\x00\x00\x01\x00\x00\x1c\x9b\
 \x00\x00\x01\x5f\xb2\xe6\x4b\xb0\
-\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x00\x64\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x52\
 \x00\x00\x01\x37\x58\x6b\x1d\xa0\
-\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x01\x00\x00\x0e\x95\
+\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
 \x00\x00\x01\x5f\xb2\xe6\x4b\xb0\
-\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x11\x70\
+\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x08\x48\
 \x00\x00\x01\x5f\xb2\xe6\x4b\xb0\
-\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x15\x7a\
+\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x01\x00\x00\x13\x0e\
 \x00\x00\x01\x5f\xb2\xe6\x4b\xb0\
-\x00\x00\x00\x26\x00\x00\x00\x00\x00\x01\x00\x00\x06\xbc\
+\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x02\xdb\
 \x00\x00\x01\x5f\xb2\xe6\x4b\xb0\
-\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x19\xae\
+\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x17\x42\
 \x00\x00\x01\x5f\xb2\xe6\x4b\xb0\
 "
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/main.py new/anki-2.1.12/aqt/main.py
--- old/anki-2.1.11/aqt/main.py 2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/main.py 2019-04-21 10:55:29.000000000 +0200
@@ -39,12 +39,6 @@
         aqt.mw = self
         self.app = app
         self.pm = profileManager
-        # running 2.0 for the first time?
-        if self.pm.meta['firstRun']:
-            # load the new deck user profile
-            self.pm.load(self.pm.profiles()[0])
-            self.pm.meta['firstRun'] = False
-            self.pm.save()
         # init rest of app
         self.safeMode = self.app.queryKeyboardModifiers() & Qt.ShiftModifier
         try:
@@ -62,7 +56,11 @@
             self.onAppMsg(args[0])
         # Load profile in a timer so we can let the window finish init and not
         # close on profile load error.
-        self.progress.timer(10, self.setupProfile, False, 
requiresCollection=False)
+        if isWin:
+            fn = self.setupProfileAfterWebviewsLoaded
+        else:
+            fn = self.setupProfile
+        self.progress.timer(10, fn, False, requiresCollection=False)
 
     def setupUI(self):
         self.col = None
@@ -90,6 +88,16 @@
         self.setupOverview()
         self.setupReviewer()
 
+    def setupProfileAfterWebviewsLoaded(self):
+        for w in (self.web, self.bottomWeb):
+            if not w._domDone:
+                self.progress.timer(10, self.setupProfileAfterWebviewsLoaded, 
False, requiresCollection=False)
+                return
+            else:
+                w.requiresCol = True
+
+        self.setupProfile()
+
     # Profiles
     ##########################################################################
 
@@ -108,6 +116,12 @@
             self.closeFires = True
 
     def setupProfile(self):
+        if self.pm.meta['firstRun']:
+            # load the new deck user profile
+            self.pm.load(self.pm.profiles()[0])
+            self.pm.meta['firstRun'] = False
+            self.pm.save()
+
         self.pendingImport = None
         self.restoringBackup = False
         # profile not provided on command line?
@@ -292,7 +306,7 @@
                 if getattr(w, "silentlyClose", None):
                     w.close()
                 else:
-                    showWarning("Window should have been closed: {}".format(w))
+                    print("Window should have been closed: {}".format(w))
 
     def unloadProfileAndExit(self):
         self.unloadProfile(self.cleanupAndExit)
@@ -342,6 +356,7 @@
                 self.col = None
 
             # return to profile manager
+            self.hide()
             self.showProfileManager()
             return False
 
@@ -607,6 +622,13 @@
         self.mainLayout.addWidget(sweb)
         self.form.centralwidget.setLayout(self.mainLayout)
 
+        # force webengine processes to load before cwd is changed
+        if isWin:
+            for o in self.web, self.bottomWeb:
+                o.requiresCol = False
+                o._domReady = False
+                o._page.setContent(bytes("", "ascii"))
+
     def closeAllWindows(self, onsuccess):
         aqt.dialogs.closeAll(onsuccess)
 
@@ -793,6 +815,7 @@
         cid = self.col.undo()
         if cid and self.state == "review":
             card = self.col.getCard(cid)
+            self.col.sched.reset()
             self.reviewer.cardQueue.append(card)
             self.reviewer.nextCard()
             self.maybeEnableUndo()
@@ -1294,7 +1317,8 @@
     def onAppMsg(self, buf):
         if self.state == "startup":
             # try again in a second
-            return self.progress.timer(1000, lambda: self.onAppMsg(buf), False)
+            return self.progress.timer(1000, lambda: self.onAppMsg(buf), False,
+                                       requiresCollection=False)
         elif self.state == "profileManager":
             # can't raise window while in profile manager
             if buf == "raise":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/preferences.py 
new/anki-2.1.12/aqt/preferences.py
--- old/anki-2.1.11/aqt/preferences.py  2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/preferences.py  2019-04-21 10:55:29.000000000 +0200
@@ -12,9 +12,6 @@
 class Preferences(QDialog):
 
     def __init__(self, mw):
-        if not mw.col:
-            showInfo(_("Please open a profile first."))
-            return
         QDialog.__init__(self, mw, Qt.Window)
         self.mw = mw
         self.prof = self.mw.pm.profile
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/sync.py new/anki-2.1.12/aqt/sync.py
--- old/anki-2.1.11/aqt/sync.py 2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/sync.py 2019-04-21 10:41:00.000000000 +0200
@@ -74,7 +74,7 @@
 to download the collection you have just uploaded from this computer. \
 After doing so, future reviews and added cards will be merged \
 automatically."""))
-        self.mw.progress.timer(1000, delayedInfo, False)
+        self.mw.progress.timer(1000, delayedInfo, False, 
requiresCollection=False)
 
     def _updateLabel(self):
         self.mw.progress.update(label="%s\n%s" % (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/toolbar.py 
new/anki-2.1.12/aqt/toolbar.py
--- old/anki-2.1.11/aqt/toolbar.py      2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/toolbar.py      2019-04-15 04:17:36.000000000 +0200
@@ -44,7 +44,7 @@
         buf = ""
         for ln, name, title in links:
             buf += '''
-            <a class=hitem aria-label="%s" title="%s" href=# onclick="return 
pycmd('%s')">%s</a>''' % (
+            <a class=hitem tabindex="-1" aria-label="%s" title="%s" href=# 
onclick="return pycmd('%s')">%s</a>''' % (
                 name, title, ln, name)
         return buf
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/aqt/webview.py 
new/anki-2.1.12/aqt/webview.py
--- old/anki-2.1.11/aqt/webview.py      2019-03-09 23:22:42.000000000 +0100
+++ new/anki-2.1.12/aqt/webview.py      2019-04-21 11:11:27.000000000 +0200
@@ -75,7 +75,7 @@
         # catch buggy <a href='#' onclick='func()'> links
         from aqt import mw
         if url.matches(QUrl(mw.serverURL()), QUrl.RemoveFragment):
-            sys.stderr.write("onclick handler needs to return false\n")
+            print("onclick handler needs to return false")
             return False
         # load all other links in browser
         openLink(url)
@@ -228,10 +228,15 @@
             css = []
         if js is None:
             js = ["jquery.js"]
+
+        palette = self.style().standardPalette()
+        color_hl = palette.color(QPalette.Highlight).name()
+
         if isWin:
             #T: include a font for your language on Windows, eg: "Segoe UI", 
"MS Mincho"
             family = _('"Segoe UI"')
             widgetspec = "button { font-size: 12px; font-family:%s; }" % family
+            widgetspec += "\n:focus { outline: 1px solid %s; }" % color_hl
             fontspec = 'font-size:12px;font-family:%s;' % family
         elif isMac:
             family="Helvetica"
@@ -241,9 +246,7 @@
 button { font-size: 13px; -webkit-appearance: none; background: #fff; border: 
1px solid #ccc;
 border-radius:5px; font-family: Helvetica }"""
         else:
-            palette = self.style().standardPalette()
             family = self.font().family()
-            color_hl = palette.color(QPalette.Highlight).name()
             color_hl_txt = palette.color(QPalette.HighlightedText).name()
             color_btn = palette.color(QPalette.Button).name()
             fontspec = 'font-size:14px;font-family:"%s";'% family
@@ -345,14 +348,14 @@
         return False
 
     def _onBridgeCmd(self, cmd):
-        if not self._filterSet:
-            self.focusProxy().installEventFilter(self)
-            self._filterSet = True
-
         if self._shouldIgnoreWebEvent():
             print("ignored late bridge cmd", cmd)
             return
 
+        if not self._filterSet:
+            self.focusProxy().installEventFilter(self)
+            self._filterSet = True
+
         if cmd == "domDone":
             self._domDone = True
             self._maybeRunActions()
Binary files old/anki-2.1.11/locale/af/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/af/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ar/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ar/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/az/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/az/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/bg/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/bg/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/bn/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/bn/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ca/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ca/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ca@valencia/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ca@valencia/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/cs/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/cs/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/da/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/da/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/de/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/de/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/el/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/el/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/en_GB/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/en_GB/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/eo/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/eo/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/es/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/es/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/et/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/et/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/eu/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/eu/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/fa/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/fa/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/fi/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/fi/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/fr/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/fr/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/fr_CA/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/fr_CA/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ga/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ga/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/gl/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/gl/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/gu/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/gu/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/he/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/he/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/hr/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/hr/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/hu/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/hu/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/hy/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/hy/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ia/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ia/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/is/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/is/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/it/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/it/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ja/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ja/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/jbo/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/jbo/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/kab/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/kab/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/km/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/km/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ko/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ko/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ku/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ku/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/la/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/la/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/lt/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/lt/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/lv/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/lv/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/mn/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/mn/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/mr/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/mr/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ms/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ms/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/nb/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/nb/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/nl/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/nl/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/oc/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/oc/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/pl/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/pl/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/pt/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/pt/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/pt_BR/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/pt_BR/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ro/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ro/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ru/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ru/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/sco/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/sco/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/sk/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/sk/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/sl/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/sl/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/sr/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/sr/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/sv/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/sv/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/szl/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/szl/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/th/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/th/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/tlh/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/tlh/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/tr/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/tr/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/uk/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/uk/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/ur/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/ur/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/vi/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/vi/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/wo/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/wo/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/zh_CN/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/zh_CN/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/zh_HK/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/zh_HK/LC_MESSAGES/anki.mo differ
Binary files old/anki-2.1.11/locale/zh_TW/LC_MESSAGES/anki.mo and 
new/anki-2.1.12/locale/zh_TW/LC_MESSAGES/anki.mo differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/web/editor.css 
new/anki-2.1.12/web/editor.css
--- old/anki-2.1.11/web/editor.css      2019-02-26 00:45:07.000000000 +0100
+++ new/anki-2.1.12/web/editor.css      2019-04-16 10:50:33.000000000 +0200
@@ -8,9 +8,7 @@
     padding: 5px;
     overflow-wrap: break-word;
 }
-.field:empty:before {
-    content: "\00a0"; /* nbsp */
-}
+
 .clearfix:after {
     content: "";
     display: table;
@@ -32,7 +30,6 @@
 
 #topbutsOuter {
     position: fixed;
-    height: 24px;
     top: 0;
     padding: 2px;
     left: 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/web/editor.js 
new/anki-2.1.12/web/editor.js
--- old/anki-2.1.11/web/editor.js       2019-03-11 04:31:36.000000000 +0100
+++ new/anki-2.1.12/web/editor.js       2019-04-16 10:50:33.000000000 +0200
@@ -91,6 +91,11 @@
 }
 
 function onInput() {
+    // empty field?
+    if (currentField.innerHTML === "") {
+        currentField.innerHTML = "<br>";
+    }
+
     // make sure IME changes get saved
     triggerKeyTimer();
 }
@@ -293,6 +298,9 @@
     for (var i = 0; i < fields.length; i++) {
         var n = fields[i][0];
         var f = fields[i][1];
+        if (!f) {
+            f = "<br>";
+        }
         txt += "<tr><td class=fname>{0}</td></tr><tr><td 
width=100%>".format(n);
         txt += "<div id=f{0} onkeydown='onKey();' oninput='onInput()' 
onmouseup='onKey();'".format(i);
         txt += " onfocus='onFocus(this);' onblur='onBlur();' class='field 
clearfix' ";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/anki-2.1.11/web/toolbar.css 
new/anki-2.1.12/web/toolbar.css
--- old/anki-2.1.11/web/toolbar.css     2019-02-26 00:45:07.000000000 +0100
+++ new/anki-2.1.12/web/toolbar.css     2019-04-15 04:17:36.000000000 +0200
@@ -32,3 +32,5 @@
 .hitem:hover {
     text-decoration: underline;
 }
+
+.hitem:focus { outline: 0; }


Reply via email to