summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/sqlite/patches/0001-Fix-CVE-2019-16168-in-SQLite.patch42
-rw-r--r--src/3rdparty/sqlite/qt_attribution.json4
-rw-r--r--src/3rdparty/sqlite/sqlite3.c7122
-rw-r--r--src/3rdparty/sqlite/sqlite3.h53
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java19
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java295
-rw-r--r--src/android/templates/AndroidManifest.xml2
-rw-r--r--src/android/templates/build.gradle5
-rw-r--r--src/android/templates/res/values/libs.xml10
-rw-r--r--src/angle/src/config.pri1
-rw-r--r--src/concurrent/qtconcurrentmapkernel.h20
-rw-r--r--src/corelib/animation/qanimationgroup.cpp5
-rw-r--r--src/corelib/codecs/qicucodec.cpp9
-rw-r--r--src/corelib/codecs/qtextcodec.cpp5
-rw-r--r--src/corelib/configure.json22
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp2
-rw-r--r--src/corelib/doc/snippets/hellotrmain.cpp4
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h1
-rw-r--r--src/corelib/global/qfloat16.cpp49
-rw-r--r--src/corelib/global/qfloat16.h4
-rw-r--r--src/corelib/global/qglobal.cpp69
-rw-r--r--src/corelib/global/qlibraryinfo.cpp243
-rw-r--r--src/corelib/global/qlibraryinfo.h1
-rw-r--r--src/corelib/global/qlogging.cpp8
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/global/qnumeric.cpp2
-rw-r--r--src/corelib/global/qnumeric.h7
-rw-r--r--src/corelib/global/qnumeric_p.h3
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp8
-rw-r--r--src/corelib/global/qoperatingsystemversion.h1
-rw-r--r--src/corelib/global/qrandom.cpp42
-rw-r--r--src/corelib/global/qrandom_p.h8
-rw-r--r--src/corelib/io/qfileinfo.cpp85
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp6
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp19
-rw-r--r--src/corelib/io/qloggingcategory.cpp267
-rw-r--r--src/corelib/io/qresource.cpp10
-rw-r--r--src/corelib/io/qsavefile.cpp14
-rw-r--r--src/corelib/io/qsettings.cpp7
-rw-r--r--src/corelib/io/qstandardpaths.cpp4
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp3
-rw-r--r--src/corelib/io/qtldurl.cpp8
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h1
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm6
-rw-r--r--src/corelib/kernel/qcore_mac_p.h8
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp37
-rw-r--r--src/corelib/kernel/qcoreapplication.h3
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm13
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf_p.h6
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp23
-rw-r--r--src/corelib/kernel/qmetaobject.cpp22
-rw-r--r--src/corelib/kernel/qmetaobject.h3
-rw-r--r--src/corelib/kernel/qobject.cpp61
-rw-r--r--src/corelib/kernel/qobject_p.h9
-rw-r--r--src/corelib/kernel/qobjectdefs.h4
-rw-r--r--src/corelib/kernel/qpointer.h15
-rw-r--r--src/corelib/kernel/qtimer.cpp4
-rw-r--r--src/corelib/kernel/qtranslator.cpp8
-rw-r--r--src/corelib/kernel/qvariant.cpp4
-rw-r--r--src/corelib/kernel/qvariant.h8
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp4
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp12
-rw-r--r--src/corelib/plugin/qlibrary.cpp2
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp8
-rw-r--r--src/corelib/plugin/qpluginloader.cpp10
-rw-r--r--src/corelib/serialization/qdatastream.h7
-rw-r--r--src/corelib/serialization/qjsonarray.h1
-rw-r--r--src/corelib/serialization/qjsondocument.cpp2
-rw-r--r--src/corelib/serialization/qtextstream.cpp2
-rw-r--r--src/corelib/statemachine/qsignaleventgenerator_p.h7
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp96
-rw-r--r--src/corelib/text/qbytearray.cpp11
-rw-r--r--src/corelib/text/qbytearray.h2
-rw-r--r--src/corelib/text/qchar.cpp27
-rw-r--r--src/corelib/text/qlocale.cpp86
-rw-r--r--src/corelib/text/qlocale_p.h1
-rw-r--r--src/corelib/text/qlocale_tools.cpp4
-rw-r--r--src/corelib/text/qlocale_tools_p.h16
-rw-r--r--src/corelib/text/qregexp.cpp24
-rw-r--r--src/corelib/text/qregularexpression.cpp2
-rw-r--r--src/corelib/text/qstring.cpp34
-rw-r--r--src/corelib/text/qunicodetables.cpp5304
-rw-r--r--src/corelib/text/qunicodetables_p.h59
-rw-r--r--src/corelib/thread/qbasicatomic.h12
-rw-r--r--src/corelib/thread/qfutureinterface.cpp7
-rw-r--r--src/corelib/thread/qfutureinterface.h13
-rw-r--r--src/corelib/thread/qreadwritelock.cpp13
-rw-r--r--src/corelib/thread/qreadwritelock_p.h18
-rw-r--r--src/corelib/thread/qsemaphore.h7
-rw-r--r--src/corelib/thread/qwaitcondition_p.h153
-rw-r--r--src/corelib/thread/thread.pri1
-rw-r--r--src/corelib/time/qcalendar.cpp551
-rw-r--r--src/corelib/time/qcalendar.h10
-rw-r--r--src/corelib/time/qcalendarbackend_p.h6
-rw-r--r--src/corelib/time/qdatetime.cpp98
-rw-r--r--src/corelib/time/qdatetimeparser.cpp26
-rw-r--r--src/corelib/time/qgregoriancalendar.cpp2
-rw-r--r--src/corelib/time/qhijricalendar.cpp49
-rw-r--r--src/corelib/time/qhijricalendar_p.h2
-rw-r--r--src/corelib/time/qislamiccivilcalendar.cpp32
-rw-r--r--src/corelib/time/qromancalendar.cpp22
-rw-r--r--src/corelib/time/qromancalendar_p.h2
-rw-r--r--src/corelib/time/qtimezone.cpp23
-rw-r--r--src/corelib/time/qtimezoneprivate.cpp48
-rw-r--r--src/corelib/time/qtimezoneprivate_p.h3
-rw-r--r--src/corelib/time/qtimezoneprivate_win.cpp42
-rw-r--r--src/corelib/tools/qarraydata.cpp2
-rw-r--r--src/corelib/tools/qcontainertools_impl.h4
-rw-r--r--src/corelib/tools/qeasingcurve.cpp12
-rw-r--r--src/corelib/tools/qlist.cpp7
-rw-r--r--src/corelib/tools/qlist.h20
-rw-r--r--src/corelib/tools/qpair.qdoc1
-rw-r--r--src/corelib/tools/qset.h70
-rw-r--r--src/corelib/tools/qset.qdoc8
-rw-r--r--src/corelib/tools/qsimd.cpp127
-rw-r--r--src/corelib/tools/qsimd_p.h18
-rw-r--r--src/corelib/tools/qvarlengtharray.h2
-rw-r--r--src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp1
-rw-r--r--src/dbus/doc/snippets/code/src_qdbus_qdbusargument.cpp2
-rw-r--r--src/dbus/doc/src/dbus-adaptors.qdoc3
-rw-r--r--src/dbus/qdbus_symbols.cpp12
-rw-r--r--src/dbus/qdbusabstractadaptor.cpp118
-rw-r--r--src/dbus/qdbusabstractadaptor_p.h9
-rw-r--r--src/dbus/qdbusconnection.cpp12
-rw-r--r--src/dbus/qdbusserver.cpp8
-rw-r--r--src/gui/configure.pri24
-rw-r--r--src/gui/image/qiconloader.cpp2
-rw-r--r--src/gui/image/qimage.cpp4
-rw-r--r--src/gui/image/qimage.h1
-rw-r--r--src/gui/image/qimage_conversions.cpp218
-rw-r--r--src/gui/image/qimagereader.cpp6
-rw-r--r--src/gui/image/qmovie.cpp2
-rw-r--r--src/gui/image/qpicture.cpp1
-rw-r--r--src/gui/image/qpnghandler.cpp4
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.h2
-rw-r--r--src/gui/kernel/qevent.cpp38
-rw-r--r--src/gui/kernel/qevent.h3
-rw-r--r--src/gui/kernel/qevent_p.h4
-rw-r--r--src/gui/kernel/qguiapplication.cpp40
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp32
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp11
-rw-r--r--src/gui/kernel/qplatformwindow.cpp4
-rw-r--r--src/gui/kernel/qscreen.cpp19
-rw-r--r--src/gui/kernel/qscreen.h1
-rw-r--r--src/gui/kernel/qtouchdevice.cpp10
-rw-r--r--src/gui/kernel/qwindowdefs.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp16
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h6
-rw-r--r--src/gui/opengl/qopengldebug.cpp2
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp3
-rw-r--r--src/gui/opengl/qopenglprogrambinarycache.cpp96
-rw-r--r--src/gui/opengl/qopenglprogrambinarycache_p.h46
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp137
-rw-r--r--src/gui/opengl/qopengltexture.cpp2
-rw-r--r--src/gui/opengl/qopengltexture.h2
-rw-r--r--src/gui/painting/XCONSORTIUM_LICENSE.txt43
-rw-r--r--src/gui/painting/qbackingstore.cpp5
-rw-r--r--src/gui/painting/qbezier.cpp32
-rw-r--r--src/gui/painting/qcolormatrix_p.h22
-rw-r--r--src/gui/painting/qcolorspace.cpp157
-rw-r--r--src/gui/painting/qcolorspace.h27
-rw-r--r--src/gui/painting/qcolorspace_p.h16
-rw-r--r--src/gui/painting/qcolortransferfunction_p.h4
-rw-r--r--src/gui/painting/qcolortransform.cpp12
-rw-r--r--src/gui/painting/qdrawhelper.cpp199
-rw-r--r--src/gui/painting/qdrawhelper_p.h2
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp45
-rw-r--r--src/gui/painting/qicc.cpp10
-rw-r--r--src/gui/painting/qicc_p.h4
-rw-r--r--src/gui/painting/qpagesize.cpp8
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp59
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp2
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp31
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
-rw-r--r--src/gui/painting/qregion.cpp54
-rw-r--r--src/gui/painting/qrgba64_p.h2
-rw-r--r--src/gui/painting/qt_attribution.json15
-rw-r--r--src/gui/rhi/cs_tdr_p.h225
-rw-r--r--src/gui/rhi/qrhi.cpp558
-rw-r--r--src/gui/rhi/qrhi_p.h200
-rw-r--r--src/gui/rhi/qrhi_p_p.h241
-rw-r--r--src/gui/rhi/qrhid3d11.cpp802
-rw-r--r--src/gui/rhi/qrhid3d11_p.h3
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h46
-rw-r--r--src/gui/rhi/qrhigles2.cpp642
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h37
-rw-r--r--src/gui/rhi/qrhimetal.mm756
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h13
-rw-r--r--src/gui/rhi/qrhinull.cpp165
-rw-r--r--src/gui/rhi/qrhinull_p_p.h11
-rw-r--r--src/gui/rhi/qrhiprofiler.cpp14
-rw-r--r--src/gui/rhi/qrhiprofiler_p_p.h6
-rw-r--r--src/gui/rhi/qrhivulkan.cpp918
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h35
-rw-r--r--src/gui/rhi/qshader.cpp8
-rw-r--r--src/gui/rhi/qshaderdescription.cpp2
-rw-r--r--src/gui/rhi/tdr.hlsl9
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp2
-rw-r--r--src/gui/text/qfont.cpp14
-rw-r--r--src/gui/text/qfontdatabase.cpp2
-rw-r--r--src/gui/text/qfontdatabase.h1
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qtextdocument.cpp31
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp2
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp44
-rw-r--r--src/gui/text/qtextengine.cpp15
-rw-r--r--src/gui/text/qtextformat.cpp1
-rw-r--r--src/gui/text/qtextformat.h2
-rw-r--r--src/gui/text/qtextmarkdownimporter.cpp6
-rw-r--r--src/gui/text/qtextmarkdownimporter_p.h2
-rw-r--r--src/gui/text/qtextmarkdownwriter.cpp4
-rw-r--r--src/gui/text/qtextodfwriter.cpp2
-rw-r--r--src/gui/text/qtextoption.h2
-rw-r--r--src/gui/vulkan/qplatformvulkaninstance.cpp5
-rw-r--r--src/gui/vulkan/qplatformvulkaninstance.h1
-rw-r--r--src/gui/vulkan/qvulkaninstance.cpp14
-rw-r--r--src/gui/vulkan/qvulkaninstance.h1
-rw-r--r--src/gui/vulkan/qvulkanwindow.cpp129
-rw-r--r--src/gui/vulkan/qvulkanwindow.h7
-rw-r--r--src/gui/vulkan/qvulkanwindow_p.h1
-rw-r--r--src/network/access/access.pri7
-rw-r--r--src/network/access/qabstractnetworkcache.h1
-rw-r--r--src/network/access/qhsts_p.h1
-rw-r--r--src/network/access/qhttp2configuration.cpp2
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp52
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp55
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h2
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp95
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h7
-rw-r--r--src/network/access/qhttpnetworkreply.cpp14
-rw-r--r--src/network/access/qhttpnetworkreply_p.h12
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp14
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h4
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp27
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp8
-rw-r--r--src/network/access/qnetworkaccessmanager.h1
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp25
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp18
-rw-r--r--src/network/access/qnetworkrequest.cpp17
-rw-r--r--src/network/access/qnetworkrequest.h8
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp1304
-rw-r--r--src/network/access/qspdyprotocolhandler_p.h232
-rw-r--r--src/network/configure.json41
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qauthenticator.cpp6
-rw-r--r--src/network/kernel/qhostinfo.cpp4
-rw-r--r--src/network/kernel/qnetconmonitor_win.cpp4
-rw-r--r--src/network/kernel/qnetworkinterface.h1
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp1
-rw-r--r--src/network/kernel/qnetworkproxy.cpp8
-rw-r--r--src/network/network.pro2
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp15
-rw-r--r--src/network/ssl/qsslconfiguration.cpp89
-rw-r--r--src/network/ssl/qsslconfiguration.h7
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp44
-rw-r--r--src/network/ssl/qsslsocket.cpp47
-rw-r--r--src/network/ssl/qsslsocket.h16
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp7
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp5
-rw-r--r--src/network/ssl/qsslsocket_qt.cpp1
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp24
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h1
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp3
-rw-r--r--src/platformsupport/edid/qedidparser.cpp8
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp30
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm266
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h3
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp22
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp2
-rw-r--r--src/platformsupport/input/tslib/qtslib.cpp2
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp12
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice_p.h1
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp37
-rw-r--r--src/plugins/platforms/android/android.pro12
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp18
-rw-r--r--src/plugins/platforms/android/androidjnimain.h1
-rw-r--r--src/plugins/platforms/android/main.cpp63
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp356
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.h8
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp5
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro41
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm48
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm85
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm28
-rw-r--r--src/plugins/platforms/cocoa/qnsview_dragging.mm5
-rw-r--r--src/plugins/platforms/cocoa/qnsview_drawing.mm208
-rw-r--r--src/plugins/platforms/cocoa/qnsview_mouse.mm4
-rw-r--r--src/plugins/platforms/cocoa/qnswindow.mm14
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp3
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor_p.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp37
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm2
-rw-r--r--src/plugins/platforms/ios/quiview_accessibility.mm2
-rw-r--r--src/plugins/platforms/wasm/qwasmbackingstore.cpp9
-rw-r--r--src/plugins/platforms/wasm/qwasmbackingstore.h1
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp2
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json14
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp76
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h5
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp18
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp30
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp3
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp12
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp12
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp26
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h2
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp10
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp38
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp21
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp11
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h2
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp4
-rw-r--r--src/plugins/sqldrivers/ibase/qsql_ibase.cpp13
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp156
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp21
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp5
-rw-r--r--src/plugins/styles/android/qandroidstyle.cpp2
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm41
-rw-r--r--src/plugins/styles/windowsvista/main.cpp4
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle.cpp113
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp158
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h61
-rw-r--r--src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp2
-rw-r--r--src/sql/kernel/qsqldatabase.cpp8
-rw-r--r--src/sql/kernel/qsqldriver.cpp3
-rw-r--r--src/sql/kernel/qsqldriver.h3
-rw-r--r--src/src.pro11
-rw-r--r--src/testlib/qtestcase.cpp92
-rw-r--r--src/tools/androiddeployqt/main.cpp184
-rw-r--r--src/tools/bootstrap/bootstrap.pro1
-rw-r--r--src/tools/moc/collectjson.cpp103
-rw-r--r--src/tools/moc/collectjson.h42
-rw-r--r--src/tools/moc/generator.cpp28
-rw-r--r--src/tools/moc/main.cpp41
-rw-r--r--src/tools/moc/moc.cpp205
-rw-r--r--src/tools/moc/moc.h13
-rw-r--r--src/tools/moc/moc.pri7
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp39
-rw-r--r--src/widgets/dialogs/qwizard.cpp190
-rw-r--r--src/widgets/doc/snippets/javastyle.cpp2
-rw-r--r--src/widgets/doc/snippets/qsplashscreen/main.cpp7
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/styles.qdoc2
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp9
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.h3
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex_p.h1
-rw-r--r--src/widgets/graphicsview/qgraphicsview.h4
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp42
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp2
-rw-r--r--src/widgets/itemviews/qdirmodel.cpp4
-rw-r--r--src/widgets/itemviews/qdirmodel.h11
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp6
-rw-r--r--src/widgets/itemviews/qtablewidget.h5
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp13
-rw-r--r--src/widgets/kernel/qapplication.cpp6
-rw-r--r--src/widgets/kernel/qapplication.h1
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp1
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp8
-rw-r--r--src/widgets/kernel/qshortcut.cpp6
-rw-r--r--src/widgets/kernel/qwidget.cpp21
-rw-r--r--src/widgets/kernel/qwidgetrepaintmanager.cpp2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp1
-rw-r--r--src/widgets/styles/qfusionstyle.cpp18
-rw-r--r--src/widgets/styles/qstyle.cpp1
-rw-r--r--src/widgets/styles/qstyle.h6
-rw-r--r--src/widgets/styles/qstyleoption.cpp2
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp25
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp30
-rw-r--r--src/widgets/styles/qwindowsstyle_p_p.h4
-rw-r--r--src/widgets/util/qcompleter.cpp10
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp5
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp2
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp4
-rw-r--r--src/widgets/widgets/qcombobox.cpp36
-rw-r--r--src/widgets/widgets/qcombobox_p.h10
-rw-r--r--src/widgets/widgets/qgroupbox.cpp8
-rw-r--r--src/widgets/widgets/qmenu.cpp17
-rw-r--r--src/widgets/widgets/qmenubar.cpp13
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp38
-rw-r--r--src/widgets/widgets/qsplashscreen.h4
-rw-r--r--src/widgets/widgets/qsplitter.h1
-rw-r--r--src/widgets/widgets/qtextedit.cpp3
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp2
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp8
-rw-r--r--src/xml/dom/qdom.cpp14
-rw-r--r--src/xml/dom/qdom.h14
411 files changed, 15394 insertions, 13107 deletions
diff --git a/src/3rdparty/sqlite/patches/0001-Fix-CVE-2019-16168-in-SQLite.patch b/src/3rdparty/sqlite/patches/0001-Fix-CVE-2019-16168-in-SQLite.patch
new file mode 100644
index 0000000000..e56a6a2411
--- /dev/null
+++ b/src/3rdparty/sqlite/patches/0001-Fix-CVE-2019-16168-in-SQLite.patch
@@ -0,0 +1,42 @@
+From 3442a3ce9c2bd366eb0bd1c18d37a6ce732a888d Mon Sep 17 00:00:00 2001
+From: Andy Shaw <andy.shaw@qt.io>
+Date: Wed, 25 Sep 2019 09:17:01 +0200
+Subject: [PATCH] Fix CVE-2019-16168 in SQLite
+
+v3.29.0 is the latest and there is no indication as to when the next
+release is so we will apply this separately for now and it can be
+reverted once it is in a release that we ship with.
+
+This patch is taken from https://www.sqlite.org/src/info/98357d8c1263920b
+
+Change-Id: I82d398b093b67842a4369e3220c01e7eea30763a
+---
+ src/3rdparty/sqlite/sqlite3.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
+index 61bfdeb766..b3e6ae27b6 100644
+--- a/src/3rdparty/sqlite/sqlite3.c
++++ b/src/3rdparty/sqlite/sqlite3.c
+@@ -105933,7 +105933,9 @@ static void decodeIntArray(
+ if( sqlite3_strglob("unordered*", z)==0 ){
+ pIndex->bUnordered = 1;
+ }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
+- pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
++ int sz = sqlite3Atoi(z+3);
++ if( sz<2 ) sz = 2;
++ pIndex->szIdxRow = sqlite3LogEst(sz);
+ }else if( sqlite3_strglob("noskipscan*", z)==0 ){
+ pIndex->noSkipScan = 1;
+ }
+@@ -143260,6 +143262,7 @@ static int whereLoopAddBtreeIndex(
+ ** it to pNew->rRun, which is currently set to the cost of the index
+ ** seek only. Then, if this is a non-covering index, add the cost of
+ ** visiting the rows in the main table. */
++ assert( pSrc->pTab->szTabRow>0 );
+ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+ pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
+ if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
+--
+2.20.1 (Apple Git-117)
+
diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json
index e6647b2700..2ad20f8637 100644
--- a/src/3rdparty/sqlite/qt_attribution.json
+++ b/src/3rdparty/sqlite/qt_attribution.json
@@ -6,8 +6,8 @@
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
"Homepage": "https://www.sqlite.org/",
- "Version": "3.28.0",
- "DownloadLocation": "https://www.sqlite.org/2019/sqlite-amalgamation-3280000.zip",
+ "Version": "3.29.0",
+ "DownloadLocation": "https://www.sqlite.org/2019/sqlite-amalgamation-3290000.zip",
"License": "Public Domain",
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
}
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index 440429527d..b3e6ae27b6 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.28.0. By combining all the individual C code files into this
+** version 3.29.0. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -39,7 +39,7 @@
** SQLite was built with.
*/
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */
/*
** Include the configuration header output by 'configure' if we're using the
@@ -888,6 +888,11 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
#pragma warning(disable : 4706)
#endif /* defined(_MSC_VER) */
+#if defined(_MSC_VER) && !defined(_WIN64)
+#undef SQLITE_4_BYTE_ALIGNED_MALLOC
+#define SQLITE_4_BYTE_ALIGNED_MALLOC
+#endif /* defined(_MSC_VER) && !defined(_WIN64) */
+
#endif /* SQLITE_MSVC_H */
/************** End of msvc.h ************************************************/
@@ -1162,9 +1167,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.28.0"
-#define SQLITE_VERSION_NUMBER 3028000
-#define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50"
+#define SQLITE_VERSION "3.29.0"
+#define SQLITE_VERSION_NUMBER 3029000
+#define SQLITE_SOURCE_ID "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -2335,8 +2340,14 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. The file can be a
-** directory.
+** to test whether a file is at least readable. The SQLITE_ACCESS_READ
+** flag is never actually used and is not implemented in the built-in
+** VFSes of SQLite. The file is named by the second argument and can be a
+** directory. The xAccess method returns [SQLITE_OK] on success or some
+** non-zero error code if there is an I/O error or if the name of
+** the file given in the second argument is illegal. If SQLITE_OK
+** is returned, then non-zero or zero is written into *pResOut to indicate
+** whether or not the file is accessible.
**
** ^SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname. The exact size of the output buffer
@@ -3237,6 +3248,7 @@ struct sqlite3_mem_methods {
** features include but are not limited to the following:
** <ul>
** <li> The [PRAGMA writable_schema=ON] statement.
+** <li> The [PRAGMA journal_mode=OFF] statement.
** <li> Writes to the [sqlite_dbpage] virtual table.
** <li> Direct writes to [shadow tables].
** </ul>
@@ -3252,6 +3264,34 @@ struct sqlite3_mem_methods {
** integer into which is written 0 or 1 to indicate whether the writable_schema
** is enabled or disabled following this call.
** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
+** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
+** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
+** the legacy behavior of the [ALTER TABLE RENAME] command such it
+** behaves as it did prior to [version 3.24.0] (2018-06-04). See the
+** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
+** additional information. This feature can also be turned on and off
+** using the [PRAGMA legacy_alter_table] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DML]]
+** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DML statement
+** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DDL]]
+** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DDL statements,
+** such as CREATE TABLE and CREATE INDEX. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -3266,7 +3306,10 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */
-#define SQLITE_DBCONFIG_MAX 1011 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -8358,7 +8401,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
-#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_RESULT_INTREAL 27
+#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
@@ -13952,12 +13996,13 @@ typedef INT16_TYPE LogEst;
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
-# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
- defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
- defined(__arm__) || defined(_M_ARM64)
+# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
+ defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
# define SQLITE_BYTEORDER 1234
-# elif defined(sparc) || defined(__ppc__)
+# elif defined(sparc) || defined(__ppc__) || \
+ defined(__ARMEB__) || defined(__AARCH64EB__)
# define SQLITE_BYTEORDER 4321
# else
# define SQLITE_BYTEORDER 0
@@ -16470,6 +16515,8 @@ struct sqlite3 {
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
+#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/
+#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
/* Flags used only if debugging */
#define HI(X) ((u64)(X)<<32)
@@ -17176,6 +17223,7 @@ struct Index {
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
+ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -17403,7 +17451,7 @@ struct Expr {
** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 op2; /* TK_REGISTER: original value of Expr.op
+ u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
@@ -17437,7 +17485,7 @@ struct Expr {
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
+#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win 0x008000 /* Contains window functions */
@@ -17453,6 +17501,8 @@ struct Expr {
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
+#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
+#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
@@ -17468,6 +17518,8 @@ struct Expr {
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
+#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
+#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only. It works like ExprSetProperty() during VVA
@@ -17684,7 +17736,7 @@ struct NameContext {
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
- u16 ncFlags; /* Zero or more NC_* flags defined below */
+ int ncFlags; /* Zero or more NC_* flags defined below */
Select *pWinSelect; /* SELECT statement for any window functions */
};
@@ -17711,6 +17763,7 @@ struct NameContext {
#define NC_Complex 0x2000 /* True if a function or subquery seen */
#define NC_AllowWin 0x4000 /* Window functions are allowed here */
#define NC_HasWin 0x8000 /* One or more window functions seen */
+#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */
/*
** An instance of the following object describes a single ON CONFLICT
@@ -18717,8 +18770,12 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
+# define EXP754 (((u64)0x7ff)<<52)
+# define MAN754 ((((u64)1)<<52)-1)
+# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
SQLITE_PRIVATE int sqlite3IsNaN(double);
#else
+# define IsNaN(X) 0
# define sqlite3IsNaN(X) 0
#endif
@@ -18777,10 +18834,12 @@ SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
+SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
@@ -19089,6 +19148,7 @@ SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*);
SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
+SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64);
SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite3Atoi(const char*);
@@ -19190,6 +19250,9 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
+#ifndef SQLITE_UNTESTABLE
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*);
+#endif
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
@@ -19752,8 +19815,15 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
-#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
+#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN)
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+#else
+# if !SQLITE_ALLOW_COVERING_INDEX_SCAN
+# error "Compile-time disabling of covering index scan using the\
+ -DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\
+ Contact SQLite developers if this is a problem for you, and\
+ delete this #error macro to continue with your build."
+# endif
#endif
/* The minimum PMA size is set to this value multiplied by the database
@@ -20180,12 +20250,12 @@ struct sqlite3_value {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
-#define MEM_AffMask 0x001f /* Mask of affinity bits */
-#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
-/* Available 0x0040 */
+#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
+#define MEM_AffMask 0x003f /* Mask of affinity bits */
+#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
-#define MEM_TypeMask 0xc1df /* Mask of type bits */
+#define MEM_TypeMask 0xc1bf /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
@@ -21305,7 +21375,7 @@ static int parseDateOrTime(
return 0;
}else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
return setDateTimeToCurrent(context, p);
- }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
+ }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
setRawDateNumber(p, r);
return 0;
}
@@ -21639,7 +21709,7 @@ static int parseModifier(
** date is already on the appropriate weekday, this is a no-op.
*/
if( sqlite3_strnicmp(z, "weekday ", 8)==0
- && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
+ && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite3_int64 Z;
computeYMD_HMS(p);
@@ -21698,7 +21768,7 @@ static int parseModifier(
double rRounder;
int i;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
- if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
+ if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
rc = 1;
break;
}
@@ -27331,6 +27401,12 @@ static const et_info fmtinfo[] = {
{ 'r', 10, 1, etORDINAL, 0, 0 },
};
+/* Floating point constants used for rounding */
+static const double arRound[] = {
+ 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05,
+ 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10,
+};
+
/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
@@ -27749,8 +27825,18 @@ SQLITE_API void sqlite3_str_vappendf(
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
- for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
- if( xtype==etFLOAT ) realvalue += rounder;
+ idx = precision & 0xfff;
+ rounder = arRound[idx%10];
+ while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
+ if( xtype==etFLOAT ){
+ double rx = (double)realvalue;
+ sqlite3_uint64 u;
+ int ex;
+ memcpy(&u, &rx, sizeof(u));
+ ex = -1023 + (int)((u>>52)&0x7ff);
+ if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
+ realvalue += rounder;
+ }
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
@@ -29030,7 +29116,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
};
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
assert( pExpr->pRight );
- assert( pExpr->pRight->op==TK_TRUEFALSE );
+ assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE );
x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
zUniOp = azOp[x];
break;
@@ -30212,9 +30298,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
*/
/* #include "sqliteInt.h" */
/* #include <stdarg.h> */
-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
-# include <math.h>
-#endif
+#include <math.h>
/*
** Routine needed to support the testcase() macro.
@@ -30255,47 +30339,11 @@ SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
-**
-** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
-** Otherwise, we have our own implementation that works on most systems.
*/
SQLITE_PRIVATE int sqlite3IsNaN(double x){
- int rc; /* The value return */
-#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
- /*
- ** Systems that support the isnan() library function should probably
- ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
- ** found that many systems do not have a working isnan() function so
- ** this implementation is provided as an alternative.
- **
- ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
- ** On the other hand, the use of -ffast-math comes with the following
- ** warning:
- **
- ** This option [-ffast-math] should never be turned on by any
- ** -O option since it can result in incorrect output for programs
- ** which depend on an exact implementation of IEEE or ISO
- ** rules/specifications for math functions.
- **
- ** Under MSVC, this NaN test may fail if compiled with a floating-
- ** point precision mode other than /fp:precise. From the MSDN
- ** documentation:
- **
- ** The compiler [with /fp:precise] will properly handle comparisons
- ** involving NaN. For example, x != x evaluates to true if x is NaN
- ** ...
- */
-#ifdef __FAST_MATH__
-# error SQLite will not work correctly with the -ffast-math option of GCC.
-#endif
- volatile double y = x;
- volatile double z = y;
- rc = (y!=z);
-#else /* if HAVE_ISNAN */
- rc = isnan(x);
-#endif /* HAVE_ISNAN */
- testcase( rc );
- return rc;
+ u64 y;
+ memcpy(&y,&x,sizeof(y));
+ return IsNaN(y);
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -30517,12 +30565,18 @@ SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
}
SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
unsigned char *a, *b;
- int c;
+ int c, x;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
for(;;){
- c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
- if( c || *a==0 ) break;
+ c = *a;
+ x = *b;
+ if( c==x ){
+ if( c==0 ) break;
+ }else{
+ c = (int)UpperToLower[c] - (int)UpperToLower[x];
+ if( c ) break;
+ }
a++;
b++;
}
@@ -30550,15 +30604,15 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
static LONGDOUBLE_TYPE sqlite3Pow10(int E){
#if defined(_MSC_VER)
static const LONGDOUBLE_TYPE x[] = {
- 1.0e+001,
- 1.0e+002,
- 1.0e+004,
- 1.0e+008,
- 1.0e+016,
- 1.0e+032,
- 1.0e+064,
- 1.0e+128,
- 1.0e+256
+ 1.0e+001L,
+ 1.0e+002L,
+ 1.0e+004L,
+ 1.0e+008L,
+ 1.0e+016L,
+ 1.0e+032L,
+ 1.0e+064L,
+ 1.0e+128L,
+ 1.0e+256L
};
LONGDOUBLE_TYPE r = 1.0;
int i;
@@ -30588,8 +30642,15 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
** uses the encoding enc. The string is not necessarily zero-terminated.
**
** Return TRUE if the result is a valid real number (or integer) and FALSE
-** if the string is empty or contains extraneous text. Valid numbers
-** are in one of these formats:
+** if the string is empty or contains extraneous text. More specifically
+** return
+** 1 => The input string is a pure integer
+** 2 or more => The input has a decimal point or eNNN clause
+** 0 or less => The input string is not a valid number
+** -1 => Not a valid number, but has a valid prefix which
+** includes a decimal point and/or an eNNN clause
+**
+** Valid numbers are in one of these formats:
**
** [+-]digits[E[+-]digits]
** [+-]digits.[digits][E[+-]digits]
@@ -30614,8 +30675,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int e = 0; /* exponent */
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
- int nDigits = 0;
- int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
+ int nDigit = 0; /* Number of digits processed */
+ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -30626,8 +30687,10 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int i;
incr = 2;
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ testcase( enc==SQLITE_UTF16LE );
+ testcase( enc==SQLITE_UTF16BE );
for(i=3-enc; i<length && z[i]==0; i+=2){}
- nonNum = i<length;
+ if( i<length ) eType = -100;
zEnd = &z[i^1];
z += (enc&1);
}
@@ -30645,27 +30708,30 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
}
/* copy max significant digits to significand */
- while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+ while( z<zEnd && sqlite3Isdigit(*z) ){
s = s*10 + (*z - '0');
- z+=incr; nDigits++;
+ z+=incr; nDigit++;
+ if( s>=((LARGEST_INT64-9)/10) ){
+ /* skip non-significant significand digits
+ ** (increase exponent by d to shift decimal left) */
+ while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; }
+ }
}
-
- /* skip non-significant significand digits
- ** (increase exponent by d to shift decimal left) */
- while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
if( z>=zEnd ) goto do_atof_calc;
/* if decimal point is present */
if( *z=='.' ){
z+=incr;
+ eType++;
/* copy digits from after decimal to significand
** (decrease exponent by d to shift decimal right) */
while( z<zEnd && sqlite3Isdigit(*z) ){
if( s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
d--;
+ nDigit++;
}
- z+=incr; nDigits++;
+ z+=incr;
}
}
if( z>=zEnd ) goto do_atof_calc;
@@ -30674,6 +30740,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
if( *z=='e' || *z=='E' ){
z+=incr;
eValid = 0;
+ eType++;
/* This branch is needed to avoid a (harmless) buffer overread. The
** special comment alerts the mutation tester that the correct answer
@@ -30772,7 +30839,13 @@ do_atof_calc:
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
- return z==zEnd && nDigits>0 && eValid && nonNum==0;
+ if( z==zEnd && nDigit>0 && eValid && eType>0 ){
+ return eType;
+ }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){
+ return -1;
+ }else{
+ return 0;
+ }
#else
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -30815,6 +30888,7 @@ static int compare2pow63(const char *zNum, int incr){
**
** Returns:
**
+** -1 Not even a prefix of the input text looks like an integer
** 0 Successful transformation. Fits in a 64-bit signed integer.
** 1 Excess non-space text after the integer value
** 2 Integer too large for a 64-bit signed integer or is malformed
@@ -30874,9 +30948,9 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
*pNum = (i64)u;
}
rc = 0;
- if( (i==0 && zStart==zNum) /* No digits */
- || nonNum /* UTF16 with high-order bytes non-zero */
- ){
+ if( i==0 && zStart==zNum ){ /* No digits */
+ rc = -1;
+ }else if( nonNum ){ /* UTF16 with high-order bytes non-zero */
rc = 1;
}else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */
int jj = i;
@@ -31107,23 +31181,12 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
u32 a,b,s;
- a = *p;
- /* a: p0 (unmasked) */
- if (!(a&0x80))
- {
- *v = a;
+ if( ((signed char*)p)[0]>=0 ){
+ *v = *p;
return 1;
}
-
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- a &= 0x7f;
- a = a<<7;
- a |= b;
- *v = a;
+ if( ((signed char*)p)[1]>=0 ){
+ *v = ((u32)(p[0]&0x7f)<<7) | p[1];
return 2;
}
@@ -31131,8 +31194,9 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
- p++;
- a = a<<14;
+ a = ((u32)p[0])<<14;
+ b = p[1];
+ p += 2;
a |= *p;
/* a: p0<<14 | p2 (unmasked) */
if (!(a&0x80))
@@ -48002,9 +48066,10 @@ static int numberOfCachePages(PCache *p){
** suggested cache size is set to N. */
return p->szCache;
}else{
- /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
- ** the number of cache pages is adjusted to use approximately abs(N*1024)
- ** bytes of memory. */
+ /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
+ ** number of cache pages is adjusted to be a number of pages that would
+ ** use approximately abs(N*1024) bytes of memory based on the current
+ ** page size. */
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
@@ -49420,6 +49485,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
}else{
pGroup = &pcache1.grp;
}
+ pcache1EnterMutex(pGroup);
if( pGroup->lru.isAnchor==0 ){
pGroup->lru.isAnchor = 1;
pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
@@ -49429,7 +49495,6 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pCache->szExtra = szExtra;
pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
- pcache1EnterMutex(pGroup);
pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
@@ -61222,9 +61287,9 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
}
nCollide = HASHTABLE_NSLOT;
for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
- u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
- if( iFrame<=iLast && iFrame>=pWal->minFrame
- && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
+ u32 iH = sLoc.aHash[iKey];
+ u32 iFrame = iH + sLoc.iZero;
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
@@ -64816,7 +64881,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
** However, that integer is too large to be stored in a 2-byte unsigned
** integer, so a value of 0 is used in its place. */
top = get2byte(&data[hdr+5]);
- assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
+ assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
if( gap>top ){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
@@ -65113,7 +65178,7 @@ static int btreeComputeFreeSpace(MemPage *pPage){
** serves to verify that the offset to the start of the cell-content
** area, according to the page header, lies within the page.
*/
- if( nFree>usableSize ){
+ if( nFree>usableSize || nFree<iCellFirst ){
return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->nFree = (u16)(nFree - iCellFirst);
@@ -67342,6 +67407,18 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
}
/*
+** Set the pBt->nPage field correctly, according to the current
+** state of the database. Assume pBt->pPage1 is valid.
+*/
+static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
+ int nPage = get4byte(&pPage1->aData[28]);
+ testcase( nPage==0 );
+ if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
+ testcase( pBt->nPage!=nPage );
+ pBt->nPage = nPage;
+}
+
+/*
** Rollback the transaction in progress.
**
** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
@@ -67386,11 +67463,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
- int nPage = get4byte(28+(u8*)pPage1->aData);
- testcase( nPage==0 );
- if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
- testcase( pBt->nPage!=nPage );
- pBt->nPage = nPage;
+ btreeSetNPage(pBt, pPage1);
releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
@@ -67470,12 +67543,11 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
pBt->nPage = 0;
}
rc = newDatabase(pBt);
- pBt->nPage = get4byte(28 + pBt->pPage1->aData);
+ btreeSetNPage(pBt, pBt->pPage1);
- /* The database size was written into the offset 28 of the header
- ** when the transaction started, so we know that the value at offset
- ** 28 is nonzero. */
- assert( pBt->nPage>0 );
+ /* pBt->nPage might be zero if the database was corrupt when
+ ** the transaction was started. Otherwise, it must be at least 1. */
+ assert( CORRUPT_DB || pBt->nPage>0 );
}
sqlite3BtreeLeave(p);
}
@@ -68483,6 +68555,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( pCur->ix==pCur->pPage->nCell-1 );
assert( pCur->pPage->leaf );
#endif
+ *pRes = 0;
return SQLITE_OK;
}
@@ -68704,6 +68777,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** case this happens. */
void *pCellKey;
u8 * const pCellBody = pCell - pPage->childPtrSize;
+ const int nOverrun = 18; /* Size of the overrun padding */
pPage->xParseCell(pPage, pCellBody, &pCur->info);
nCell = (int)pCur->info.nKey;
testcase( nCell<0 ); /* True if key size is 2^32 or more */
@@ -68714,13 +68788,14 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
- pCellKey = sqlite3Malloc( nCell+18 );
+ pCellKey = sqlite3Malloc( nCell+nOverrun );
if( pCellKey==0 ){
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
+ memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
sqlite3_free(pCellKey);
@@ -70825,6 +70900,7 @@ static int balance_nonroot(
u16 maskPage = pOld->maskPage;
u8 *piCell = aData + pOld->cellOffset;
u8 *piEnd;
+ VVA_ONLY( int nCellAtStart = b.nCell; )
/* Verify that all sibling pages are of the same "type" (table-leaf,
** table-interior, index-leaf, or index-interior).
@@ -70853,6 +70929,10 @@ static int balance_nonroot(
*/
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
+ if( limit<pOld->aiOvfl[0] ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto balance_cleanup;
+ }
limit = pOld->aiOvfl[0];
for(j=0; j<limit; j++){
b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
@@ -70872,6 +70952,7 @@ static int balance_nonroot(
piCell += 2;
b.nCell++;
}
+ assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );
cntOld[i] = b.nCell;
if( i<nOld-1 && !leafData){
@@ -71172,6 +71253,7 @@ static int balance_nonroot(
while( i==cntOldNext ){
iOld++;
assert( iOld<nNew || iOld<nOld );
+ assert( iOld>=0 && iOld<NB );
pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
}
@@ -73892,7 +73974,7 @@ static int backupOnePage(
if( nSrcReserve!=nDestReserve ){
u32 newPgsz = nSrcPgsz;
rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
- if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
+ if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
}
#endif
@@ -74439,6 +74521,11 @@ copy_finished:
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
+/* True if X is a power of two. 0 is considered a power of two here.
+** In other words, return true if X has at most one bit set.
+*/
+#define ISPOWEROF2(X) (((X)&((X)-1))==0)
+
#ifdef SQLITE_DEBUG
/*
** Check invariants on a Mem object.
@@ -74458,8 +74545,8 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
** That saves a few cycles in inner loops. */
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
- /* Cannot be both MEM_Int and MEM_Real at the same time */
- assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+ /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
+ assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
@@ -74513,9 +74600,31 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
}
#endif
+/*
+** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
+** into a buffer.
+*/
+static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
+ StrAccum acc;
+ assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
+ sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
+ if( p->flags & MEM_Int ){
+ sqlite3_str_appendf(&acc, "%lld", p->u.i);
+ }else if( p->flags & MEM_IntReal ){
+ sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
+ }else{
+ sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
+ }
+ assert( acc.zText==zBuf && acc.mxAlloc<=0 );
+ zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
+}
+
#ifdef SQLITE_DEBUG
/*
-** Check that string value of pMem agrees with its integer or real value.
+** Validity checks on pMem. pMem holds a string.
+**
+** (1) Check that string value of pMem agrees with its integer or real value.
+** (2) Check that the string is correctly zero terminated
**
** A single int or real value always converts to the same strings. But
** many different strings can be converted into the same int or real.
@@ -74533,17 +74642,24 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
**
** This routine is for use inside of assert() statements only.
*/
-SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
+SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){
char zBuf[100];
char *z;
int i, j, incr;
if( (p->flags & MEM_Str)==0 ) return 1;
- if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
- if( p->flags & MEM_Int ){
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
- }else{
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
- }
+ if( p->flags & MEM_Term ){
+ /* Insure that the string is properly zero-terminated. Pay particular
+ ** attention to the case where p->n is odd */
+ if( p->szMalloc>0 && p->z==p->zMalloc ){
+ assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 );
+ assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 );
+ }
+ assert( p->z[p->n]==0 );
+ assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 );
+ assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
+ }
+ if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
+ vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
z = p->z;
i = j = 0;
incr = 1;
@@ -74655,8 +74771,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
**
** Any prior string or blob content in the pMem object may be discarded.
** The pMem->xDel destructor is called, if it exists. Though MEM_Str
-** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
-** values are preserved.
+** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
+** and MEM_Null values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
@@ -74669,20 +74785,26 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
}
assert( (pMem->flags & MEM_Dyn)==0 );
pMem->z = pMem->zMalloc;
- pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
+ pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
return SQLITE_OK;
}
/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
+**
+** Three bytes of zero are added. In this way, there is guaranteed
+** to be a double-zero byte at an even byte boundary in order to
+** terminate a UTF16 string, even if the initial size of the buffer
+** is an odd number of bytes.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
+ if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
+ pMem->z[pMem->n+2] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
@@ -74756,12 +74878,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
}
/*
-** Add MEM_Str to the set of representations for the given Mem. Numbers
-** are converted using sqlite3_snprintf(). Converting a BLOB to a string
-** is a no-op.
+** Add MEM_Str to the set of representations for the given Mem. This
+** routine is only called if pMem is a number of some kind, not a NULL
+** or a BLOB.
**
-** Existing representations MEM_Int and MEM_Real are invalidated if
-** bForce is true but are retained if bForce is false.
+** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
+** if bForce is true but are retained if bForce is false.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
@@ -74770,13 +74892,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
** user and the latter is an internal programming error.
*/
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
- int fg = pMem->flags;
const int nByte = 32;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( !(fg&MEM_Zero) );
- assert( !(fg&(MEM_Str|MEM_Blob)) );
- assert( fg&(MEM_Int|MEM_Real) );
+ assert( !(pMem->flags&MEM_Zero) );
+ assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
+ assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -74786,23 +74907,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
return SQLITE_NOMEM_BKPT;
}
- /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
- ** string representation of the value. Then, if the required encoding
- ** is UTF-16le or UTF-16be do a translation.
- **
- ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
- */
- if( fg & MEM_Int ){
- sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
- }else{
- assert( fg & MEM_Real );
- sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
- }
+ vdbeMemRenderNum(nByte, pMem->z, pMem);
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30NN(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
- if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
+ if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
sqlite3VdbeChangeEncoding(pMem, enc);
return SQLITE_OK;
}
@@ -74976,7 +75086,8 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
flags = pMem->flags;
- if( flags & MEM_Int ){
+ if( flags & (MEM_Int|MEM_IntReal) ){
+ testcase( flags & MEM_IntReal );
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
@@ -75005,7 +75116,8 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( pMem->flags & MEM_Real ){
return pMem->u.r;
- }else if( pMem->flags & MEM_Int ){
+ }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pMem->flags & MEM_IntReal );
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
return memRealValue(pMem);
@@ -75020,7 +75132,8 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
** Return the value ifNull if pMem is NULL.
*/
SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
- if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
+ testcase( pMem->flags & MEM_IntReal );
+ if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
if( pMem->flags & MEM_Null ) return ifNull;
return sqlite3VdbeRealValue(pMem)!=0.0;
}
@@ -75083,17 +75196,21 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
/* Compare a floating point value to an integer. Return true if the two
** values are the same within the precision of the floating point value.
**
+** This function assumes that i was obtained by assignment from r1.
+**
** For some versions of GCC on 32-bit machines, if you do the more obvious
** comparison of "r1==(double)i" you sometimes get an answer of false even
** though the r1 and (double)i values are bit-for-bit the same.
*/
-static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
+SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
double r2 = (double)i;
- return memcmp(&r1, &r2, sizeof(r1))==0;
+ return r1==0.0
+ || (memcmp(&r1, &r2, sizeof(r1))==0
+ && i >= -2251799813685248LL && i < 2251799813685248LL);
}
/*
-** Convert pMem so that it has types MEM_Real or MEM_Int or both.
+** Convert pMem so that it has type MEM_Real or MEM_Int.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
@@ -75101,25 +75218,26 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
** as much of the string as we can and ignore the rest.
*/
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
- if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
+ testcase( pMem->flags & MEM_Int );
+ testcase( pMem->flags & MEM_Real );
+ testcase( pMem->flags & MEM_IntReal );
+ testcase( pMem->flags & MEM_Null );
+ if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
int rc;
+ sqlite3_int64 ix;
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
- if( rc==0 ){
+ rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+ if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1)
+ || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r))
+ ){
+ pMem->u.i = ix;
MemSetTypeFlag(pMem, MEM_Int);
}else{
- i64 i = pMem->u.i;
- sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
- if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
- pMem->u.i = i;
- MemSetTypeFlag(pMem, MEM_Int);
- }else{
- MemSetTypeFlag(pMem, MEM_Real);
- }
+ MemSetTypeFlag(pMem, MEM_Real);
}
}
- assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
+ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
return SQLITE_OK;
}
@@ -75162,7 +75280,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
- pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
+ pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
break;
}
}
@@ -75346,7 +75464,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
** dual type, are allowed, as long as the underlying value is the
** same. */
u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
- assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
+ assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
@@ -75621,7 +75739,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
- assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+ assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}else{
return 0;
@@ -75644,7 +75762,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( !sqlite3VdbeMemIsRowSet(pVal) );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
- assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+ assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}
if( pVal->flags&MEM_Null ){
@@ -75909,7 +76027,12 @@ static int valueFromExpr(
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}
- if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
+ assert( (pVal->flags & MEM_IntReal)==0 );
+ if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
+ testcase( pVal->flags & MEM_Int );
+ testcase( pVal->flags & MEM_Real );
+ pVal->flags &= ~MEM_Str;
+ }
if( enc!=SQLITE_UTF8 ){
rc = sqlite3VdbeChangeEncoding(pVal, enc);
}
@@ -75932,7 +76055,7 @@ static int valueFromExpr(
}else if( op==TK_NULL ){
pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
- sqlite3VdbeMemNumerify(pVal);
+ sqlite3VdbeMemSetNull(pVal);
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
@@ -76944,6 +77067,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int hasAbort = 0;
int hasFkCounter = 0;
int hasCreateTable = 0;
+ int hasCreateIndex = 0;
int hasInitCoroutine = 0;
Op *pOp;
VdbeOpIter sIter;
@@ -76962,6 +77086,14 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
break;
}
if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
+ if( mayAbort ){
+ /* hasCreateIndex may also be set for some DELETE statements that use
+ ** OP_Clear. So this routine may end up returning true in the case
+ ** where a "DELETE FROM tbl" has a statement-journal but does not
+ ** require one. This is not so bad - it is an inefficiency, not a bug. */
+ if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;
+ if( opcode==OP_Clear ) hasCreateIndex = 1;
+ }
if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
@@ -76977,7 +77109,8 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** true for this case to prevent the assert() in the callers frame
** from failing. */
return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
- || (hasCreateTable && hasInitCoroutine) );
+ || (hasCreateTable && hasInitCoroutine) || hasCreateIndex
+ );
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
@@ -77849,7 +77982,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
Mem *pMem = pOp->p4.pMem;
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
- }else if( pMem->flags & MEM_Int ){
+ }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
sqlite3_str_appendf(&x, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
@@ -79211,7 +79344,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}
/* Check for immediate foreign key violations. */
- if( p->rc==SQLITE_OK ){
+ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
sqlite3VdbeCheckFk(p, 0);
}
@@ -79737,6 +79870,8 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
/*
** Return the serial-type for the value stored in pMem.
+**
+** This routine might convert a large MEM_IntReal value into MEM_Real.
*/
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
@@ -79747,11 +79882,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
*pLen = 0;
return 0;
}
- if( flags&MEM_Int ){
+ if( flags&(MEM_Int|MEM_IntReal) ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
+ testcase( flags & MEM_Int );
+ testcase( flags & MEM_IntReal );
if( i<0 ){
u = ~i;
}else{
@@ -79771,6 +79908,15 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
if( u<=2147483647 ){ *pLen = 4; return 4; }
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
*pLen = 8;
+ if( flags&MEM_IntReal ){
+ /* If the value is IntReal and is going to take up 8 bytes to store
+ ** as an integer, then we might as well make it an 8-byte floating
+ ** point value */
+ pMem->u.r = (double)pMem->u.i;
+ pMem->flags &= ~MEM_IntReal;
+ pMem->flags |= MEM_Real;
+ return 7;
+ }
return 6;
}
if( flags&MEM_Real ){
@@ -79944,7 +80090,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
** routine so that in most cases the overhead of moving the stack pointer
** is avoided.
*/
-static u32 SQLITE_NOINLINE serialGet(
+static u32 serialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
@@ -79976,7 +80122,7 @@ static u32 SQLITE_NOINLINE serialGet(
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->u.r, &x, sizeof(x));
- pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
+ pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
}
return 8;
}
@@ -80426,8 +80572,13 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
/* At least one of the two values is a number
*/
- if( combined_flags&(MEM_Int|MEM_Real) ){
- if( (f1 & f2 & MEM_Int)!=0 ){
+ if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
+ testcase( combined_flags & MEM_Int );
+ testcase( combined_flags & MEM_Real );
+ testcase( combined_flags & MEM_IntReal );
+ if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
+ testcase( f1 & f2 & MEM_Int );
+ testcase( f1 & f2 & MEM_IntReal );
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
@@ -80437,15 +80588,23 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
if( pMem1->u.r > pMem2->u.r ) return +1;
return 0;
}
- if( (f1&MEM_Int)!=0 ){
+ if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
+ testcase( f1 & MEM_Int );
+ testcase( f1 & MEM_IntReal );
if( (f2&MEM_Real)!=0 ){
return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
+ }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
+ if( pMem1->u.i < pMem2->u.i ) return -1;
+ if( pMem1->u.i > pMem2->u.i ) return +1;
+ return 0;
}else{
return -1;
}
}
if( (f1&MEM_Real)!=0 ){
- if( (f2&MEM_Int)!=0 ){
+ if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
+ testcase( f2 & MEM_Int );
+ testcase( f2 & MEM_IntReal );
return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
}else{
return -1;
@@ -80594,7 +80753,9 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
u32 serial_type;
/* RHS is an integer */
- if( pRhs->flags & MEM_Int ){
+ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pRhs->flags & MEM_Int );
+ testcase( pRhs->flags & MEM_IntReal );
serial_type = aKey1[idx1];
testcase( serial_type==12 );
if( serial_type>=10 ){
@@ -80939,7 +81100,9 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
testcase( flags & MEM_Real );
testcase( flags & MEM_Null );
testcase( flags & MEM_Blob );
- if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
+ if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
+ && p->pKeyInfo->aColl[0]==0
+ ){
assert( flags & MEM_Str );
return vdbeRecordCompareString;
}
@@ -81529,39 +81692,86 @@ SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
*/
SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
- SQLITE_BLOB, /* 0x00 */
- SQLITE_NULL, /* 0x01 */
- SQLITE_TEXT, /* 0x02 */
- SQLITE_NULL, /* 0x03 */
- SQLITE_INTEGER, /* 0x04 */
- SQLITE_NULL, /* 0x05 */
- SQLITE_INTEGER, /* 0x06 */
- SQLITE_NULL, /* 0x07 */
- SQLITE_FLOAT, /* 0x08 */
- SQLITE_NULL, /* 0x09 */
- SQLITE_FLOAT, /* 0x0a */
- SQLITE_NULL, /* 0x0b */
- SQLITE_INTEGER, /* 0x0c */
- SQLITE_NULL, /* 0x0d */
- SQLITE_INTEGER, /* 0x0e */
- SQLITE_NULL, /* 0x0f */
- SQLITE_BLOB, /* 0x10 */
- SQLITE_NULL, /* 0x11 */
- SQLITE_TEXT, /* 0x12 */
- SQLITE_NULL, /* 0x13 */
- SQLITE_INTEGER, /* 0x14 */
- SQLITE_NULL, /* 0x15 */
- SQLITE_INTEGER, /* 0x16 */
- SQLITE_NULL, /* 0x17 */
- SQLITE_FLOAT, /* 0x18 */
- SQLITE_NULL, /* 0x19 */
- SQLITE_FLOAT, /* 0x1a */
- SQLITE_NULL, /* 0x1b */
- SQLITE_INTEGER, /* 0x1c */
- SQLITE_NULL, /* 0x1d */
- SQLITE_INTEGER, /* 0x1e */
- SQLITE_NULL, /* 0x1f */
+ SQLITE_BLOB, /* 0x00 (not possible) */
+ SQLITE_NULL, /* 0x01 NULL */
+ SQLITE_TEXT, /* 0x02 TEXT */
+ SQLITE_NULL, /* 0x03 (not possible) */
+ SQLITE_INTEGER, /* 0x04 INTEGER */
+ SQLITE_NULL, /* 0x05 (not possible) */
+ SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */
+ SQLITE_NULL, /* 0x07 (not possible) */
+ SQLITE_FLOAT, /* 0x08 FLOAT */
+ SQLITE_NULL, /* 0x09 (not possible) */
+ SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */
+ SQLITE_NULL, /* 0x0b (not possible) */
+ SQLITE_INTEGER, /* 0x0c (not possible) */
+ SQLITE_NULL, /* 0x0d (not possible) */
+ SQLITE_INTEGER, /* 0x0e (not possible) */
+ SQLITE_NULL, /* 0x0f (not possible) */
+ SQLITE_BLOB, /* 0x10 BLOB */
+ SQLITE_NULL, /* 0x11 (not possible) */
+ SQLITE_TEXT, /* 0x12 (not possible) */
+ SQLITE_NULL, /* 0x13 (not possible) */
+ SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */
+ SQLITE_NULL, /* 0x15 (not possible) */
+ SQLITE_INTEGER, /* 0x16 (not possible) */
+ SQLITE_NULL, /* 0x17 (not possible) */
+ SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */
+ SQLITE_NULL, /* 0x19 (not possible) */
+ SQLITE_FLOAT, /* 0x1a (not possible) */
+ SQLITE_NULL, /* 0x1b (not possible) */
+ SQLITE_INTEGER, /* 0x1c (not possible) */
+ SQLITE_NULL, /* 0x1d (not possible) */
+ SQLITE_INTEGER, /* 0x1e (not possible) */
+ SQLITE_NULL, /* 0x1f (not possible) */
+ SQLITE_FLOAT, /* 0x20 INTREAL */
+ SQLITE_NULL, /* 0x21 (not possible) */
+ SQLITE_TEXT, /* 0x22 INTREAL + TEXT */
+ SQLITE_NULL, /* 0x23 (not possible) */
+ SQLITE_FLOAT, /* 0x24 (not possible) */
+ SQLITE_NULL, /* 0x25 (not possible) */
+ SQLITE_FLOAT, /* 0x26 (not possible) */
+ SQLITE_NULL, /* 0x27 (not possible) */
+ SQLITE_FLOAT, /* 0x28 (not possible) */
+ SQLITE_NULL, /* 0x29 (not possible) */
+ SQLITE_FLOAT, /* 0x2a (not possible) */
+ SQLITE_NULL, /* 0x2b (not possible) */
+ SQLITE_FLOAT, /* 0x2c (not possible) */
+ SQLITE_NULL, /* 0x2d (not possible) */
+ SQLITE_FLOAT, /* 0x2e (not possible) */
+ SQLITE_NULL, /* 0x2f (not possible) */
+ SQLITE_BLOB, /* 0x30 (not possible) */
+ SQLITE_NULL, /* 0x31 (not possible) */
+ SQLITE_TEXT, /* 0x32 (not possible) */
+ SQLITE_NULL, /* 0x33 (not possible) */
+ SQLITE_FLOAT, /* 0x34 (not possible) */
+ SQLITE_NULL, /* 0x35 (not possible) */
+ SQLITE_FLOAT, /* 0x36 (not possible) */
+ SQLITE_NULL, /* 0x37 (not possible) */
+ SQLITE_FLOAT, /* 0x38 (not possible) */
+ SQLITE_NULL, /* 0x39 (not possible) */
+ SQLITE_FLOAT, /* 0x3a (not possible) */
+ SQLITE_NULL, /* 0x3b (not possible) */
+ SQLITE_FLOAT, /* 0x3c (not possible) */
+ SQLITE_NULL, /* 0x3d (not possible) */
+ SQLITE_FLOAT, /* 0x3e (not possible) */
+ SQLITE_NULL, /* 0x3f (not possible) */
};
+#ifdef SQLITE_DEBUG
+ {
+ int eType = SQLITE_BLOB;
+ if( pVal->flags & MEM_Null ){
+ eType = SQLITE_NULL;
+ }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
+ eType = SQLITE_FLOAT;
+ }else if( pVal->flags & MEM_Int ){
+ eType = SQLITE_INTEGER;
+ }else if( pVal->flags & MEM_Str ){
+ eType = SQLITE_TEXT;
+ }
+ assert( eType == aType[pVal->flags&MEM_AffMask] );
+ }
+#endif
return aType[pVal->flags&MEM_AffMask];
}
@@ -81811,6 +82021,21 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
sqlite3OomFault(pCtx->pOut->db);
}
+#ifndef SQLITE_UNTESTABLE
+/* Force the INT64 value currently stored as the result to be
+** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL
+** test-control.
+*/
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ if( pCtx->pOut->flags & MEM_Int ){
+ pCtx->pOut->flags &= ~MEM_Int;
+ pCtx->pOut->flags |= MEM_IntReal;
+ }
+}
+#endif
+
+
/*
** This function is called after a transaction has been committed. It
** invokes callbacks registered with sqlite3_wal_hook() as required.
@@ -83097,7 +83322,9 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa
}else if( iIdx>=p->pUnpacked->nField ){
*ppValue = (sqlite3_value *)columnNullValue();
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
- if( pMem->flags & MEM_Int ){
+ if( pMem->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pMem->flags & MEM_Int );
+ testcase( pMem->flags & MEM_IntReal );
sqlite3VdbeMemRealify(pMem);
}
}
@@ -83416,7 +83643,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){
sqlite3_str_append(&out, "NULL", 4);
- }else if( pVar->flags & MEM_Int ){
+ }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
sqlite3_str_appendf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
@@ -83679,14 +83906,6 @@ SQLITE_API int sqlite3_found_count = 0;
#endif
/*
-** Convert the given register into a string if it isn't one
-** already. Return non-zero if a malloc() fails.
-*/
-#define Stringify(P, enc) \
- if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
- { goto no_mem; }
-
-/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string. Because the register
@@ -83747,7 +83966,7 @@ static VdbeCursor *allocateCursor(
** is clear. Otherwise, if this is an ephemeral cursor created by
** OP_OpenDup, the cursor will not be closed and will still be part
** of a BtShared.pCursor list. */
- p->apCsr[iCur]->isEphemeral = 0;
+ if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
@@ -83768,6 +83987,21 @@ static VdbeCursor *allocateCursor(
}
/*
+** The string in pRec is known to look like an integer and to have a
+** floating point value of rValue. Return true and set *piValue to the
+** integer value if the string is in range to be an integer. Otherwise,
+** return false.
+*/
+static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
+ i64 iValue = (double)rValue;
+ if( sqlite3RealSameAsInt(rValue,iValue) ){
+ *piValue = iValue;
+ return 1;
+ }
+ return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc);
+}
+
+/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information. In other words, if the string
** looks like a number, convert it into a number. If it does not
@@ -83784,12 +84018,12 @@ static VdbeCursor *allocateCursor(
*/
static void applyNumericAffinity(Mem *pRec, int bTryForInt){
double rValue;
- i64 iValue;
u8 enc = pRec->enc;
- assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
- if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
- if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
- pRec->u.i = iValue;
+ int rc;
+ assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
+ rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc);
+ if( rc<=0 ) return;
+ if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){
pRec->flags |= MEM_Int;
}else{
pRec->u.r = rValue;
@@ -83843,11 +84077,14 @@ static void applyAffinity(
** there is already a string rep, but it is pointless to waste those
** CPU cycles. */
if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
- if( (pRec->flags&(MEM_Real|MEM_Int)) ){
+ if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
+ testcase( pRec->flags & MEM_Int );
+ testcase( pRec->flags & MEM_Real );
+ testcase( pRec->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pRec, enc, 1);
}
}
- pRec->flags &= ~(MEM_Real|MEM_Int);
+ pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
}
}
@@ -83886,13 +84123,21 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
** accordingly.
*/
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
- assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
+ int rc;
+ sqlite3_int64 ix;
+ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
ExpandBlob(pMem);
- if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
- return 0;
- }
- if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){
+ rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+ if( rc<=0 ){
+ if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){
+ pMem->u.i = ix;
+ return MEM_Int;
+ }else{
+ return MEM_Real;
+ }
+ }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){
+ pMem->u.i = ix;
return MEM_Int;
}
return MEM_Real;
@@ -83906,10 +84151,15 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
** But it does set pMem->u.r and pMem->u.i appropriately.
*/
static u16 numericType(Mem *pMem){
- if( pMem->flags & (MEM_Int|MEM_Real) ){
- return pMem->flags & (MEM_Int|MEM_Real);
+ if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
+ testcase( pMem->flags & MEM_Int );
+ testcase( pMem->flags & MEM_Real );
+ testcase( pMem->flags & MEM_IntReal );
+ return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
}
if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ testcase( pMem->flags & MEM_Str );
+ testcase( pMem->flags & MEM_Blob );
return computeNumericType(pMem);
}
return 0;
@@ -84005,6 +84255,8 @@ static void memTracePrint(Mem *p){
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
+ }else if( (p->flags & (MEM_IntReal))!=0 ){
+ printf(" ir:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -85035,33 +85287,57 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
- i64 nByte;
+ i64 nByte; /* Total size of the output string or blob */
+ u16 flags1; /* Initial flags for P1 */
+ u16 flags2; /* Initial flags for P2 */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
+ testcase( pIn1==pIn2 );
+ testcase( pOut==pIn2 );
assert( pIn1!=pOut );
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
+ flags1 = pIn1->flags;
+ testcase( flags1 & MEM_Null );
+ testcase( pIn2->flags & MEM_Null );
+ if( (flags1 | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
- if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
- Stringify(pIn1, encoding);
- Stringify(pIn2, encoding);
+ if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
+ if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
+ flags1 = pIn1->flags & ~MEM_Str;
+ }else if( (flags1 & MEM_Zero)!=0 ){
+ if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
+ flags1 = pIn1->flags & ~MEM_Str;
+ }
+ flags2 = pIn2->flags;
+ if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
+ if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
+ flags2 = pIn2->flags & ~MEM_Str;
+ }else if( (flags2 & MEM_Zero)!=0 ){
+ if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
+ flags2 = pIn2->flags & ~MEM_Str;
+ }
nByte = pIn1->n + pIn2->n;
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
goto no_mem;
}
MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
+ assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
+ pIn2->flags = flags2;
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
+ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+ pIn1->flags = flags1;
pOut->z[nByte]=0;
pOut->z[nByte+1] = 0;
+ pOut->z[nByte+2] = 0;
pOut->flags |= MEM_Term;
pOut->n = (int)nByte;
pOut->enc = encoding;
@@ -85112,7 +85388,6 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
- char bIntint; /* Started out as two integer operands */
u16 flags; /* Combined MEM_* flags from both inputs */
u16 type1; /* Numeric type of left operand */
u16 type2; /* Numeric type of right operand */
@@ -85130,7 +85405,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if( (type1 & type2 & MEM_Int)!=0 ){
iA = pIn1->u.i;
iB = pIn2->u.i;
- bIntint = 1;
switch( pOp->opcode ){
case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
@@ -85153,7 +85427,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
}else if( (flags & MEM_Null)!=0 ){
goto arithmetic_result_is_null;
}else{
- bIntint = 0;
fp_math:
rA = sqlite3VdbeRealValue(pIn1);
rB = sqlite3VdbeRealValue(pIn2);
@@ -85185,9 +85458,6 @@ fp_math:
}
pOut->u.r = rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
- sqlite3VdbeIntegerAffinity(pOut);
- }
#endif
}
break;
@@ -85356,7 +85626,9 @@ case OP_MustBeInt: { /* jump, in1 */
*/
case OP_RealAffinity: { /* in1 */
pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Int ){
+ if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pIn1->flags & MEM_Int );
+ testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemRealify(pIn1);
}
break;
@@ -85548,7 +85820,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
- if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
assert( flags3==pIn3->flags );
/* testcase( flags3!=pIn3->flags );
@@ -85558,7 +85830,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** in case our analysis is incorrect, so it is left in. */
flags3 = pIn3->flags;
}
- if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
@@ -85571,17 +85843,19 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
- if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
+ if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
+ testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
assert( pIn1!=pIn3 );
}
- if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
+ if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
+ testcase( pIn3->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn3, encoding, 1);
testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
@@ -86337,12 +86611,21 @@ case OP_Affinity: {
assert( pOp->p2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- do{
+ while( 1 /*edit-by-break*/ ){
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
- applyAffinity(pIn1, *(zAffinity++), encoding);
+ applyAffinity(pIn1, zAffinity[0], encoding);
+ if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
+ /* When applying REAL affinity, if the result is still MEM_Int,
+ ** indicate that REAL is actually desired */
+ pIn1->flags |= MEM_IntReal;
+ pIn1->flags &= ~MEM_Int;
+ }
+ REGISTER_TRACE((int)(pIn1-aMem), pIn1);
+ zAffinity++;
+ if( zAffinity[0]==0 ) break;
pIn1++;
- }while( zAffinity[0] );
+ }
break;
}
@@ -86363,7 +86646,6 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity BLOB.
*/
case OP_MakeRecord: {
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
@@ -86376,9 +86658,9 @@ case OP_MakeRecord: {
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] header */
- int j; /* Space used in zNewRecord[] content */
u32 len; /* Length of a field */
+ u8 *zHdr; /* Where to write next byte of the header */
+ u8 *zPayload; /* Where to write next byte of the payload */
/* Assuming the record contains N fields, the record format looks
** like this:
@@ -86417,7 +86699,14 @@ case OP_MakeRecord: {
if( zAffinity ){
pRec = pData0;
do{
- applyAffinity(pRec++, *(zAffinity++), encoding);
+ applyAffinity(pRec, zAffinity[0], encoding);
+ if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){
+ pRec->flags |= MEM_IntReal;
+ pRec->flags &= ~(MEM_Int);
+ }
+ REGISTER_TRACE((int)(pRec-aMem), pRec);
+ zAffinity++;
+ pRec++;
assert( zAffinity[0]==0 || pRec<=pLast );
}while( zAffinity[0] );
}
@@ -86505,34 +86794,34 @@ case OP_MakeRecord: {
goto no_mem;
}
}
- zNewRecord = (u8 *)pOut->z;
+ pOut->n = (int)nByte;
+ pOut->flags = MEM_Blob;
+ if( nZero ){
+ pOut->u.nZero = nZero;
+ pOut->flags |= MEM_Zero;
+ }
+ UPDATE_MAX_BLOBSIZE(pOut);
+ zHdr = (u8 *)pOut->z;
+ zPayload = zHdr + nHdr;
/* Write the record */
- i = putVarint32(zNewRecord, nHdr);
- j = nHdr;
+ zHdr += putVarint32(zHdr, nHdr);
assert( pData0<=pLast );
pRec = pData0;
do{
serial_type = pRec->uTemp;
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
** additional varints, one per column. */
- i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
+ zHdr += putVarint32(zHdr, serial_type); /* serial type */
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
** immediately follow the header. */
- j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
+ zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
}while( (++pRec)<=pLast );
- assert( i==nHdr );
- assert( j==nByte );
+ assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
+ assert( nByte==(int)(zPayload - (u8*)pOut->z) );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
- pOut->n = (int)nByte;
- pOut->flags = MEM_Blob;
- if( nZero ){
- pOut->u.nZero = nZero;
- pOut->flags |= MEM_Zero;
- }
REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -86562,8 +86851,9 @@ case OP_Count: { /* out2 */
/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
-** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
-** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
+** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
+** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
+** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
*/
case OP_Savepoint: {
int p1; /* Value of P1 operand */
@@ -86631,6 +86921,7 @@ case OP_Savepoint: {
}
}
}else{
+ assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
@@ -86684,6 +86975,7 @@ case OP_Savepoint: {
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}else{
+ assert( p1==SAVEPOINT_RELEASE );
isSchemaChange = 0;
}
for(ii=0; ii<db->nDb; ii++){
@@ -86720,6 +87012,7 @@ case OP_Savepoint: {
db->nSavepoint--;
}
}else{
+ assert( p1==SAVEPOINT_ROLLBACK );
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
@@ -87258,11 +87551,15 @@ case OP_OpenEphemeral: {
if( pCx ){
/* If the ephermeral table is already open, erase all existing content
** so that the table is empty again, rather than creating a new table. */
- rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
+ assert( pCx->isEphemeral );
+ pCx->seqCount = 0;
+ pCx->cacheStatus = CACHE_STALE;
+ if( pCx->pBtx ){
+ rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
+ }
}else{
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
pCx->isEphemeral = 1;
rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
@@ -87298,6 +87595,7 @@ case OP_OpenEphemeral: {
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
}
if( rc ) goto abort_due_to_error;
+ pCx->nullRow = 1;
break;
}
@@ -87526,6 +87824,8 @@ case OP_SeekGT: { /* jump, in3, group */
pC->seekOp = pOp->opcode;
#endif
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
if( pC->isTable ){
/* The BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
@@ -87535,20 +87835,24 @@ case OP_SeekGT: { /* jump, in3, group */
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so convert it. */
pIn3 = &aMem[pOp->p3];
- if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3, 0);
}
iKey = sqlite3VdbeIntValue(pIn3);
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
- if( (pIn3->flags & MEM_Int)==0 ){
+ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
- /* If the P3 value cannot be converted into any kind of a number,
- ** then the seek is not possible, so jump to P2 */
- VdbeBranchTaken(1,2); goto jump_to_p2;
- break;
- }
+ if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
+ VdbeBranchTaken(1,2); goto jump_to_p2;
+ break;
+ }else{
+ rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ goto seek_not_found;
+ }
+ }else
/* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
@@ -87572,7 +87876,7 @@ case OP_SeekGT: { /* jump, in3, group */
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
}
- }
+ }
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
@@ -87626,8 +87930,6 @@ case OP_SeekGT: { /* jump, in3, group */
goto seek_not_found;
}
}
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
@@ -87927,7 +88229,9 @@ case OP_SeekRowid: { /* jump, in3 */
u64 iKey;
pIn3 = &aMem[pOp->p3];
- if( (pIn3->flags & MEM_Int)==0 ){
+ testcase( pIn3->flags & MEM_Int );
+ testcase( pIn3->flags & MEM_IntReal );
+ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
/* Make sure pIn3->u.i contains a valid integer representation of
** the key value, but do not change the datatype of the register, as
** other parts of the perpared statement might be depending on the
@@ -88302,7 +88606,7 @@ case OP_Delete: {
** OP_Delete will have also set the pC->movetoTarget field to the rowid of
** the row that is being deleted */
i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
- assert( pC->movetoTarget==iKey );
+ assert( CORRUPT_DB || pC->movetoTarget==iKey );
}
#endif
@@ -95262,6 +95566,23 @@ SQLITE_PRIVATE int sqlite3MatchSpanName(
}
/*
+** Return TRUE if the double-quoted string mis-feature should be supported.
+*/
+static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
+ if( db->init.busy ) return 1; /* Always support for legacy schemas */
+ if( pTopNC->ncFlags & NC_IsDDL ){
+ /* Currently parsing a DDL statement */
+ if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){
+ return 1;
+ }
+ return (db->flags & SQLITE_DqsDDL)!=0;
+ }else{
+ /* Currently parsing a DML statement */
+ return (db->flags & SQLITE_DqsDML)!=0;
+ }
+}
+
+/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
** expression node refer back to that source column. The following changes
@@ -95589,7 +95910,9 @@ static int lookupName(
*/
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
- if( ExprHasProperty(pExpr,EP_DblQuoted) ){
+ if( ExprHasProperty(pExpr,EP_DblQuoted)
+ && areDoubleQuotedStringsEnabled(db, pTopNC)
+ ){
/* If a double-quoted identifier does not match any known column name,
** then treat it as a string.
**
@@ -95858,7 +96181,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}else{
is_agg = pDef->xFinalize!=0;
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
- ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
+ ExprSetProperty(pExpr, EP_Unlikely);
if( n==2 ){
pExpr->iTable = exprProbability(pList->a[1].pExpr);
if( pExpr->iTable<0 ){
@@ -95979,7 +96302,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pExpr->y.pWin ){
Select *pSel = pNC->pWinSelect;
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
+ if( IN_RENAME_OBJECT==0 ){
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
+ }
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
@@ -96039,11 +96364,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
case TK_IS:
case TK_ISNOT: {
- Expr *pRight;
+ Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
- if( (pRight = pExpr->pRight)->op==TK_ID ){
+ if( pRight->op==TK_ID ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
@@ -96765,7 +97090,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
- u16 savedHasAgg;
+ int savedHasAgg;
Walker w;
if( pExpr==0 ) return SQLITE_OK;
@@ -96879,7 +97204,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference(
}
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
- sNC.ncFlags = type;
+ sNC.ncFlags = type | NC_IsDDL;
if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
return rc;
@@ -96933,8 +97258,12 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
int op;
- pExpr = sqlite3ExprSkipCollate(pExpr);
if( pExpr->flags & EP_Generic ) return 0;
+ while( ExprHasProperty(pExpr, EP_Skip) ){
+ assert( pExpr->op==TK_COLLATE );
+ pExpr = pExpr->pLeft;
+ assert( pExpr!=0 );
+ }
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
@@ -96995,7 +97324,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
** or likelihood() function at the root of an expression.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
- while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
+ while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
@@ -97662,7 +97991,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
- pNew->flags |= EP_IntValue|EP_Leaf;
+ pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
pNew->u.iValue = iValue;
}else{
pNew->u.zToken = (char*)&pNew[1];
@@ -97739,20 +98068,16 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
Expr *pRight /* Right operand */
){
Expr *p;
- if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
- /* Take advantage of short-circuit false optimization for AND */
- p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
- }else{
- p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
- if( p ){
- memset(p, 0, sizeof(Expr));
- p->op = op & 0xff;
- p->iAgg = -1;
- }
+ p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
+ if( p ){
+ memset(p, 0, sizeof(Expr));
+ p->op = op & 0xff;
+ p->iAgg = -1;
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
- }
- if( p ) {
sqlite3ExprCheckHeight(pParse, p->nHeight);
+ }else{
+ sqlite3ExprDelete(pParse->db, pLeft);
+ sqlite3ExprDelete(pParse->db, pRight);
}
return p;
}
@@ -97774,33 +98099,6 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pS
/*
-** If the expression is always either TRUE or FALSE (respectively),
-** then return 1. If one cannot determine the truth value of the
-** expression at compile-time return 0.
-**
-** This is an optimization. If is OK to return 0 here even if
-** the expression really is always false or false (a false negative).
-** But it is a bug to return 1 if the expression might have different
-** boolean values in different circumstances (a false positive.)
-**
-** Note that if the expression is part of conditional for a
-** LEFT JOIN, then we cannot determine at compile-time whether or not
-** is it true or false, so always return 0.
-*/
-static int exprAlwaysTrue(Expr *p){
- int v = 0;
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
- return v!=0;
-}
-static int exprAlwaysFalse(Expr *p){
- int v = 0;
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
- return v==0;
-}
-
-/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
**
@@ -97808,19 +98106,18 @@ static int exprAlwaysFalse(Expr *p){
** of returning an AND expression, just return a constant expression with
** a value of false.
*/
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
- if( pLeft==0 ){
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
+ sqlite3 *db = pParse->db;
+ if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
- }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
+ }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
+ sqlite3ExprUnmapAndDelete(pParse, pLeft);
+ sqlite3ExprUnmapAndDelete(pParse, pRight);
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
}else{
- Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
- sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
- return pNew;
+ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
}
}
@@ -97977,6 +98274,18 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
+/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
+** expression.
+*/
+SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
+ if( p ){
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameExprUnmap(pParse, p);
+ }
+ sqlite3ExprDeleteNN(pParse->db, p);
+ }
+}
+
/*
** Return the number of bytes allocated for the expression structure
** passed as the first argument. This is always one of EXPR_FULLSIZE,
@@ -98559,10 +98868,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
}
vector_append_error:
- if( IN_RENAME_OBJECT ){
- sqlite3RenameExprUnmap(pParse, pExpr);
- }
- sqlite3ExprDelete(db, pExpr);
+ sqlite3ExprUnmapAndDelete(pParse, pExpr);
sqlite3IdListDelete(db, pColumns);
return pList;
}
@@ -98710,6 +99016,7 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0)
){
pExpr->op = TK_TRUEFALSE;
+ ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
return 1;
}
return 0;
@@ -98720,12 +99027,40 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
** and 0 if it is FALSE.
*/
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
+ pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
assert( pExpr->op==TK_TRUEFALSE );
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
return pExpr->u.zToken[4]==0;
}
+/*
+** If pExpr is an AND or OR expression, try to simplify it by eliminating
+** terms that are always true or false. Return the simplified expression.
+** Or return the original expression if no simplification is possible.
+**
+** Examples:
+**
+** (x<10) AND true => (x<10)
+** (x<10) AND false => false
+** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
+** (x<10) AND (y=22 OR true) => (x<10)
+** (y=22) OR true => true
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
+ assert( pExpr!=0 );
+ if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
+ Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
+ Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
+ if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
+ pExpr = pExpr->op==TK_AND ? pRight : pLeft;
+ }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
+ pExpr = pExpr->op==TK_AND ? pLeft : pRight;
+ }
+ }
+ return pExpr;
+}
+
/*
** These routines are Walker callbacks used to check expressions to
@@ -98970,7 +99305,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
*/
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
- if( p==0 ) return 0; /* Can only happen following on OOM */
+ if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
@@ -99699,6 +100034,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
*/
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce);
+ ExprClearProperty(pExpr, EP_Subrtn);
addrOnce = 0;
}
@@ -100265,7 +100601,8 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
** register iReg. The caller must ensure that iReg already contains
** the correct value for the expression.
*/
-static void exprToRegister(Expr *p, int iReg){
+static void exprToRegister(Expr *pExpr, int iReg){
+ Expr *p = sqlite3ExprSkipCollate(pExpr);
p->op2 = p->op;
p->op = TK_REGISTER;
p->iTable = iReg;
@@ -101317,18 +101654,23 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
- case TK_AND: {
- int d2 = sqlite3VdbeMakeLabel(pParse);
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- break;
- }
+ case TK_AND:
case TK_OR: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
+ if( pAlt!=pExpr ){
+ sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
+ }else if( op==TK_AND ){
+ int d2 = sqlite3VdbeMakeLabel(pParse);
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
+ jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ }else{
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ }
break;
}
case TK_NOT: {
@@ -101414,9 +101756,9 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
#endif
default: {
default_expr:
- if( exprAlwaysTrue(pExpr) ){
+ if( ExprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
- }else if( exprAlwaysFalse(pExpr) ){
+ }else if( ExprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -101484,18 +101826,23 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
assert( pExpr->op!=TK_GE || op==OP_Lt );
switch( pExpr->op ){
- case TK_AND: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- break;
- }
+ case TK_AND:
case TK_OR: {
- int d2 = sqlite3VdbeMakeLabel(pParse);
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
+ if( pAlt!=pExpr ){
+ sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
+ }else if( pExpr->op==TK_AND ){
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ }else{
+ int d2 = sqlite3VdbeMakeLabel(pParse);
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
+ jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ }
break;
}
case TK_NOT: {
@@ -101584,9 +101931,9 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
#endif
default: {
default_expr:
- if( exprAlwaysFalse(pExpr) ){
+ if( ExprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
- }else if( exprAlwaysTrue(pExpr) ){
+ }else if( ExprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -101742,6 +102089,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
&& (combinedFlags & EP_Reduced)==0
){
if( pA->iColumn!=pB->iColumn ) return 2;
+ if( pA->op2!=pB->op2 ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
@@ -101790,6 +102138,76 @@ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
}
/*
+** Return non-zero if Expr p can only be true if pNN is not NULL.
+*/
+static int exprImpliesNotNull(
+ Parse *pParse, /* Parsing context */
+ Expr *p, /* The expression to be checked */
+ Expr *pNN, /* The expression that is NOT NULL */
+ int iTab, /* Table being evaluated */
+ int seenNot /* True if p is an operand of NOT */
+){
+ assert( p );
+ assert( pNN );
+ if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ) return 1;
+ switch( p->op ){
+ case TK_IN: {
+ if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
+ assert( ExprHasProperty(p,EP_xIsSelect)
+ || (p->x.pList!=0 && p->x.pList->nExpr>0) );
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_BETWEEN: {
+ ExprList *pList = p->x.pList;
+ assert( pList!=0 );
+ assert( pList->nExpr==2 );
+ if( seenNot ) return 0;
+ if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot)
+ || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot)
+ ){
+ return 1;
+ }
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_EQ:
+ case TK_NE:
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_PLUS:
+ case TK_MINUS:
+ case TK_STAR:
+ case TK_REM:
+ case TK_BITAND:
+ case TK_BITOR:
+ case TK_SLASH:
+ case TK_LSHIFT:
+ case TK_RSHIFT:
+ case TK_CONCAT: {
+ if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
+ /* Fall thru into the next case */
+ }
+ case TK_SPAN:
+ case TK_COLLATE:
+ case TK_BITNOT:
+ case TK_UPLUS:
+ case TK_UMINUS: {
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_TRUTH: {
+ if( seenNot ) return 0;
+ if( p->op2!=TK_IS ) return 0;
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_NOT: {
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
+ }
+ }
+ return 0;
+}
+
+/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
** be false. Examples:
@@ -101824,10 +102242,10 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, i
){
return 1;
}
- if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
- Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
- testcase( pX!=pE1->pLeft );
- if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
+ if( pE2->op==TK_NOTNULL
+ && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
+ ){
+ return 1;
}
return 0;
}
@@ -102401,7 +102819,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM \"%w\".%s "
- "WHERE name NOT LIKE 'sqlite_%%'"
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
zDb, MASTER_NAME,
@@ -102412,7 +102830,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM temp.%s "
- "WHERE name NOT LIKE 'sqlite_%%'"
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
MASTER_NAME, zDb
@@ -102533,7 +102951,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
- "AND name NOT LIKE 'sqlite_%%'"
+ "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
, zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
);
@@ -102544,7 +102962,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
"tbl_name = %Q, "
"name = CASE "
"WHEN type='table' THEN %Q "
- "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
+ "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
+ " AND type='index' THEN "
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
"ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND "
@@ -102918,7 +103337,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
- "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
+ " AND (type != 'index' OR tbl_name = %Q)"
" AND sql NOT LIKE 'create virtual%%'",
zDb, MASTER_NAME,
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
@@ -103073,6 +103493,29 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
}
/*
+** Walker callback used by sqlite3RenameExprUnmap().
+*/
+static int renameUnmapSelectCb(Walker *pWalker, Select *p){
+ Parse *pParse = pWalker->pParse;
+ int i;
+ if( ALWAYS(p->pEList) ){
+ ExprList *pList = p->pEList;
+ for(i=0; i<pList->nExpr; i++){
+ if( pList->a[i].zName ){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zName);
+ }
+ }
+ }
+ if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
+ SrcList *pSrc = p->pSrc;
+ for(i=0; i<pSrc->nSrc; i++){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
+ }
+ }
+ return WRC_Continue;
+}
+
+/*
** Remove all nodes that are part of expression pExpr from the rename list.
*/
SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
@@ -103080,6 +103523,7 @@ SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = pParse;
sWalker.xExprCallback = renameUnmapExprCb;
+ sWalker.xSelectCallback = renameUnmapSelectCb;
sqlite3WalkExpr(&sWalker, pExpr);
}
@@ -105489,7 +105933,9 @@ static void decodeIntArray(
if( sqlite3_strglob("unordered*", z)==0 ){
pIndex->bUnordered = 1;
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
- pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
+ int sz = sqlite3Atoi(z+3);
+ if( sz<2 ) sz = 2;
+ pIndex->szIdxRow = sqlite3LogEst(sz);
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
pIndex->noSkipScan = 1;
}
@@ -107459,10 +107905,14 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
- ** prior to doing any free() operations. Since schema Tables do not use
- ** lookaside, this number should not change. */
+ ** prior to doing any free() operations. Since schema Tables do not use
+ ** lookaside, this number should not change.
+ **
+ ** If malloc has already failed, it may be that it failed while allocating
+ ** a Table object that was going to be marked ephemeral. So do not check
+ ** that no lookaside memory is used in this case either. */
int nLookaside = 0;
- if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
+ if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
nLookaside = sqlite3LookasideUsed(db, 0);
}
#endif
@@ -108170,7 +108620,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(
** accept it. This routine does the necessary conversion. It converts
** the expression given in its argument from a TK_STRING into a TK_ID
** if the expression is just a TK_STRING with an optional COLLATE clause.
-** If the epxression is anything other than TK_STRING, the expression is
+** If the expression is anything other than TK_STRING, the expression is
** unchanged.
*/
static void sqlite3StringToId(Expr *p){
@@ -108567,10 +109017,51 @@ static void estimateIndexWidth(Index *pIdx){
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}
-/* Return true if value x is found any of the first nCol entries of aiCol[]
+/* Return true if column number x is any of the first nCol entries of aiCol[].
+** This is used to determine if the column number x appears in any of the
+** first nCol entries of an index.
*/
static int hasColumn(const i16 *aiCol, int nCol, int x){
- while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
+ while( nCol-- > 0 ){
+ assert( aiCol[0]>=0 );
+ if( x==*(aiCol++) ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** Return true if any of the first nKey entries of index pIdx exactly
+** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
+** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
+** or may not be the same index as pPk.
+**
+** The first nKey entries of pIdx are guaranteed to be ordinary columns,
+** not a rowid or expression.
+**
+** This routine differs from hasColumn() in that both the column and the
+** collating sequence must match for this routine, but for hasColumn() only
+** the column name must match.
+*/
+static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
+ int i, j;
+ assert( nKey<=pIdx->nColumn );
+ assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
+ assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
+ assert( pPk->pTable->tabFlags & TF_WithoutRowid );
+ assert( pPk->pTable==pIdx->pTable );
+ testcase( pPk==pIdx );
+ j = pPk->aiColumn[iCol];
+ assert( j!=XN_ROWID && j!=XN_EXPR );
+ for(i=0; i<nKey; i++){
+ assert( pIdx->aiColumn[i]>=0 || j>=0 );
+ if( pIdx->aiColumn[i]==j
+ && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
+ ){
+ return 1;
+ }
+ }
return 0;
}
@@ -108659,13 +109150,16 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ) return;
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
+ }
pList->a[0].sortOrder = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
+ pTab->iPKey = -1;
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
SQLITE_IDXTYPE_PRIMARYKEY);
if( db->mallocFailed || pParse->nErr ) return;
pPk = sqlite3PrimaryKeyIndex(pTab);
- pTab->iPKey = -1;
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
@@ -108676,9 +109170,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** code assumes the PRIMARY KEY contains no repeated columns.
*/
for(i=j=1; i<pPk->nKeyCol; i++){
- if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
+ if( isDupColumn(pPk, j, pPk, i) ){
pPk->nColumn--;
}else{
+ testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
pPk->aiColumn[j++] = pPk->aiColumn[i];
}
}
@@ -108708,7 +109203,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
int n;
if( IsPrimaryKeyIndex(pIdx) ) continue;
for(i=n=0; i<nPk; i++){
- if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
+ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
+ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
+ n++;
+ }
}
if( n==0 ){
/* This index is a superset of the primary key */
@@ -108717,9 +109215,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
- if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
+ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
+ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
pIdx->aiColumn[j] = pPk->aiColumn[i];
pIdx->azColl[j] = pPk->azColl[i];
+ if( pPk->aSortOrder[i] ){
+ /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */
+ pIdx->bAscKeyBug = 1;
+ }
j++;
}
}
@@ -109838,10 +110341,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
sqlite3VdbeJumpHere(v, j2);
}else{
+ /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
+ ** abort. The exception is if one of the indexed expressions contains a
+ ** user function that throws an exception when it is evaluated. But the
+ ** overhead of adding a statement journal to a CREATE INDEX statement is
+ ** very small (since most of the pages written do not contain content that
+ ** needs to be restored if the statement aborts), so we call
+ ** sqlite3MayAbort() for all CREATE INDEX statements. */
+ sqlite3MayAbort(pParse);
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
- sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+ if( !pIndex->bAscKeyBug ){
+ /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
+ ** faster by avoiding unnecessary seeks. But the optimization does
+ ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables
+ ** with DESC primary keys, since those indexes have there keys in
+ ** a different order from the main table.
+ ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf
+ */
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+ }
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -110233,9 +110753,10 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
for(j=0; j<pPk->nKeyCol; j++){
int x = pPk->aiColumn[j];
assert( x>=0 );
- if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+ if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
pIndex->nColumn--;
}else{
+ testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
pIndex->aiColumn[i] = x;
pIndex->azColl[i] = pPk->azColl[j];
pIndex->aSortOrder[i] = pPk->aSortOrder[j];
@@ -113006,6 +113527,7 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <assert.h> */
+/* #include <math.h> */
/* #include "vdbeInt.h" */
/*
@@ -113376,10 +113898,10 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** handle the rounding directly,
** otherwise use printf.
*/
- if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
- r = (double)((sqlite_int64)(r+0.5));
- }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
- r = -(double)((sqlite_int64)((-r)+0.5));
+ if( r<-4503599627370496.0 || r>+4503599627370496.0 ){
+ /* The value has no fractional part so there is nothing to round */
+ }else if( n==0 ){
+ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%.*f",n,r);
if( zBuf==0 ){
@@ -113833,8 +114355,6 @@ static void likeFunc(
return;
}
#endif
- zB = sqlite3_value_text(argv[0]);
- zA = sqlite3_value_text(argv[1]);
/* Limit the length of the LIKE or GLOB pattern to avoid problems
** of deep recursion and N*N behavior in patternCompare().
@@ -113846,8 +114366,6 @@ static void likeFunc(
sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
return;
}
- assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
-
if( argc==3 ){
/* The escape character string must consist of a single UTF-8 character.
** Otherwise, return an error.
@@ -113863,6 +114381,8 @@ static void likeFunc(
}else{
escape = pInfo->matchSet;
}
+ zB = sqlite3_value_text(argv[0]);
+ zA = sqlite3_value_text(argv[1]);
if( zA && zB ){
#ifdef SQLITE_TEST
sqlite3_like_count++;
@@ -114788,39 +115308,24 @@ SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
}
/*
-** Set the LIKEOPT flag on the 2-argument function with the given name.
-*/
-static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
- FuncDef *pDef;
- pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
- if( ALWAYS(pDef) ){
- pDef->funcFlags |= flagVal;
- }
- pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
- if( pDef ){
- pDef->funcFlags |= flagVal;
- }
-}
-
-/*
-** Register the built-in LIKE and GLOB functions. The caseSensitive
+** Re-register the built-in LIKE functions. The caseSensitive
** parameter determines whether or not the LIKE operator is case
-** sensitive. GLOB is always case sensitive.
+** sensitive.
*/
SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
struct compareInfo *pInfo;
+ int flags;
if( caseSensitive ){
pInfo = (struct compareInfo*)&likeInfoAlt;
+ flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
+ flags = SQLITE_FUNC_LIKE;
}
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
- sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
- (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
- setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
- setLikeOptFlag(db, "like",
- caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
+ sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
+ sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
}
/*
@@ -115610,7 +116115,7 @@ static void fkScanChildren(
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite3Expr(db, TK_ID, zCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
}
/* If the child table is the same as the parent table, then add terms
@@ -115644,11 +116149,11 @@ static void fkScanChildren(
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
- pAll = sqlite3ExprAnd(db, pAll, pEq);
+ pAll = sqlite3ExprAnd(pParse, pAll, pEq);
}
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
}
- pWhere = sqlite3ExprAnd(db, pWhere, pNe);
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
@@ -116254,7 +116759,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
@@ -116270,7 +116775,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
);
- pWhen = sqlite3ExprAnd(db, pWhen, pEq);
+ pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
@@ -117267,7 +117772,7 @@ SQLITE_PRIVATE void sqlite3Insert(
int nIdx;
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
&iDataCur, &iIdxCur);
- aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
+ aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
if( aRegIdx==0 ){
goto insert_cleanup;
}
@@ -117276,6 +117781,7 @@ SQLITE_PRIVATE void sqlite3Insert(
aRegIdx[i] = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}
+ aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
}
#ifndef SQLITE_OMIT_UPSERT
if( pUpsert ){
@@ -117679,6 +118185,14 @@ SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
** the same as the order of indices on the linked list of indices
** at pTab->pIndex.
**
+** (2019-05-07) The generated code also creates a new record for the
+** main table, if pTab is a rowid table, and stores that record in the
+** register identified by aRegIdx[nIdx] - in other words in the first
+** entry of aRegIdx[] past the last index. It is important that the
+** record be generated during constraint checks to avoid affinity changes
+** to the register content that occur after constraint checks but before
+** the new record is inserted.
+**
** The caller must have already opened writeable cursors on the main
** table and all applicable indices (that is to say, all indices for which
** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
@@ -117869,7 +118383,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}else{
char *zName = pCheck->a[i].zName;
if( zName==0 ) zName = pTab->zName;
- if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
+ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
onError, zName, P4_TRANSIENT,
P5_ConstraintCheck);
@@ -118298,6 +118812,16 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeJumpHere(v, ipkBottom);
}
+ /* Generate the table record */
+ if( HasRowid(pTab) ){
+ int regRec = aRegIdx[ix];
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
+ sqlite3SetMakeRecordP5(v, pTab);
+ if( !bAffinityDone ){
+ sqlite3TableAffinity(v, pTab, 0);
+ }
+ }
+
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
@@ -118347,10 +118871,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
Vdbe *v; /* Prepared statements under construction */
Index *pIdx; /* An index being inserted or updated */
u8 pik_flags; /* flag values passed to the btree insert */
- int regData; /* Content registers (after the rowid) */
- int regRec; /* Register holding assembled record for the table */
int i; /* Loop counter */
- u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
assert( update_flags==0
|| update_flags==OPFLAG_ISUPDATE
@@ -118362,7 +118883,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
- bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
@@ -118390,13 +118910,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
- regData = regNewData + 1;
- regRec = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- sqlite3SetMakeRecordP5(v, pTab);
- if( !bAffinityDone ){
- sqlite3TableAffinity(v, pTab, 0);
- }
if( pParse->nested ){
pik_flags = 0;
}else{
@@ -118409,7 +118922,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
- sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
if( !pParse->nested ){
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
@@ -120595,10 +121108,9 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_WAL_AUTOCHECKPOINT 38
#define PragTyp_WAL_CHECKPOINT 39
#define PragTyp_ACTIVATE_EXTENSIONS 40
-#define PragTyp_HEXKEY 41
-#define PragTyp_KEY 42
-#define PragTyp_LOCK_STATUS 43
-#define PragTyp_STATS 44
+#define PragTyp_KEY 41
+#define PragTyp_LOCK_STATUS 42
+#define PragTyp_STATS 43
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -120727,11 +121239,13 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
{/* zName: */ "case_sensitive_like",
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
/* ePragFlg: */ PragFlg_NoColumns,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#endif
{/* zName: */ "cell_size_check",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -120869,12 +121383,12 @@ static const PragmaName aPragmaName[] = {
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "hexkey",
- /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 2 },
{/* zName: */ "hexrekey",
- /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 3 },
@@ -121835,6 +122349,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
** then do a query */
eMode = PAGER_JOURNALMODE_QUERY;
}
+ if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){
+ /* Do not allow journal-mode "OFF" in defensive since the database
+ ** can become corrupted using ordinary SQL when the journal is off */
+ eMode = PAGER_JOURNALMODE_QUERY;
+ }
}
if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
/* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
@@ -122612,6 +123131,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
+#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
@@ -122621,6 +123141,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
break;
+#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
@@ -123314,28 +123835,30 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_KEY: {
if( zRight ){
- int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
- if( (pPragma->iArg & 1)==0 ){
- sqlite3_key_v2(db, zDb, zRight, n);
+ char zBuf[40];
+ const char *zKey = zRight;
+ int n;
+ if( pPragma->iArg==2 || pPragma->iArg==3 ){
+ u8 iByte;
+ int i;
+ for(i=0, iByte=0; i<sizeof(zBuf)*2 && sqlite3Isxdigit(zRight[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+ if( (i&1)!=0 ) zBuf[i/2] = iByte;
+ }
+ zKey = zBuf;
+ n = i/2;
}else{
- sqlite3_rekey_v2(db, zDb, zRight, n);
- }
- }
- break;
- }
- case PragTyp_HEXKEY: {
- if( zRight ){
- u8 iByte;
- int i;
- char zKey[40];
- for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
- iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
- if( (i&1)!=0 ) zKey[i/2] = iByte;
+ n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
}
if( (pPragma->iArg & 1)==0 ){
- sqlite3_key_v2(db, zDb, zKey, i/2);
+ rc = sqlite3_key_v2(db, zDb, zKey, n);
}else{
- sqlite3_rekey_v2(db, zDb, zKey, i/2);
+ rc = sqlite3_rekey_v2(db, zDb, zKey, n);
+ }
+ if( rc==SQLITE_OK && n!=0 ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
+ returnSingleText(v, "ok");
}
}
break;
@@ -124976,7 +125499,7 @@ static void addWhereTerm(
ExprSetVVAProperty(pEq, EP_NoReduce);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
- *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
+ *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
}
/*
@@ -125110,7 +125633,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
*/
if( pRight->pOn ){
if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
- p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
+ p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
pRight->pOn = 0;
}
@@ -126717,9 +127240,6 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
if( pTab==0 ){
return 0;
}
- /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
- ** is disabled */
- assert( db->lookaside.bDisable );
pTab->nTabRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -127161,6 +127681,7 @@ static int multiSelect(
*/
assert( p && p->pPrior ); /* Calling function guarantees this much */
assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
+ assert( p->selFlags & SF_Compound );
db = pParse->db;
pPrior = p->pPrior;
dest = *pDest;
@@ -128655,7 +129176,7 @@ static int flattenSubquery(
if( isLeftJoin>0 ){
setJoinExpr(pWhere, iNewParent);
}
- pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
+ pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
@@ -128666,10 +129187,10 @@ static int flattenSubquery(
substSelect(&x, pParent, 0);
}
- /* The flattened query is distinct if either the inner or the
- ** outer query is distinct.
- */
- pParent->selFlags |= pSub->selFlags & SF_Distinct;
+ /* The flattened query is a compound if either the inner or the
+ ** outer query is a compound. */
+ pParent->selFlags |= pSub->selFlags & SF_Compound;
+ assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */
/*
** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
@@ -128990,9 +129511,9 @@ static int pushDownWhereTerms(
x.pEList = pSubq->pEList;
pNew = substExpr(&x, pNew);
if( pSubq->selFlags & SF_Aggregate ){
- pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
+ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
}else{
- pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
+ pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
}
pSubq = pSubq->pPrior;
}
@@ -129418,7 +129939,7 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFr
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
- return SQLITE_OK;
+ return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
}
/*
@@ -129464,6 +129985,10 @@ static int selectExpander(Walker *pWalker, Select *p){
if( (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
+ if( pWalker->eCode ){
+ /* Renumber selId because it has been copied from a view */
+ p->selId = ++pParse->nSelect;
+ }
pTabList = p->pSrc;
pEList = p->pEList;
sqlite3WithPush(pParse, p->pWith, 0);
@@ -129513,12 +130038,15 @@ static int selectExpander(Walker *pWalker, Select *p){
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
if( IsVirtual(pTab) || pTab->pSelect ){
i16 nCol;
+ u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
nCol = pTab->nCol;
pTab->nCol = -1;
+ pWalker->eCode = 1; /* Turn on Select.selId renumbering */
sqlite3WalkSelect(pWalker, pFrom->pSelect);
+ pWalker->eCode = eCodeOrig;
pTab->nCol = nCol;
}
#endif
@@ -129768,6 +130296,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
}
w.xSelectCallback = selectExpander;
w.xSelectCallback2 = selectPopWith;
+ w.eCode = 0;
sqlite3WalkSelect(&w, pSelect);
}
@@ -130039,7 +130568,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
if( pNew ){
Expr *pWhere = pS->pWhere;
SWAP(Expr, *pNew, *pExpr);
- pNew = sqlite3ExprAnd(db, pWhere, pNew);
+ pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
pS->pWhere = pNew;
pWalker->eCode = 1;
}
@@ -130094,15 +130623,19 @@ static struct SrcList_item *isSelfJoinView(
if( pItem->pSelect==0 ) continue;
if( pItem->fg.viaCoroutine ) continue;
if( pItem->zName==0 ) continue;
- if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
+ assert( pItem->pTab!=0 );
+ assert( pThis->pTab!=0 );
+ if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
pS1 = pItem->pSelect;
- if( pThis->pSelect->selId!=pS1->selId ){
+ if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
/* The query flattener left two different CTE tables with identical
** names in the same FROM clause. */
continue;
}
- if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
+ if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
+ || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1)
+ ){
/* The view was modified by some other optimization such as
** pushDownWhereTerms() */
continue;
@@ -130127,7 +130660,8 @@ static struct SrcList_item *isSelfJoinView(
** * The subquery is a UNION ALL of two or more terms
** * The subquery does not have a LIMIT clause
** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
-** * The outer query is a simple count(*)
+** * The outer query is a simple count(*) with no WHERE clause or other
+** extraneous syntax.
**
** Return TRUE if the optimization is undertaken.
*/
@@ -130138,6 +130672,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
sqlite3 *db;
if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
+ if( p->pWhere ) return 0;
+ if( p->pGroupBy ) return 0;
pExpr = p->pEList->a[0].pExpr;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
@@ -132788,11 +133324,12 @@ SQLITE_PRIVATE void sqlite3Update(
Index *pIdx; /* For looping over indices */
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
int nIdx; /* Number of indices that need updating */
+ int nAllIdx; /* Total number of indexes */
int iBaseCur; /* Base cursor number */
int iDataCur; /* Cursor for the canonical data btree */
int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
- int *aRegIdx = 0; /* First register in array assigned to each index */
+ int *aRegIdx = 0; /* Registers for to each index and the main table */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
@@ -132906,10 +133443,10 @@ SQLITE_PRIVATE void sqlite3Update(
/* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
** Initialize aXRef[] and aToOpen[] to their default values.
*/
- aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+ aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
if( aXRef==0 ) goto update_cleanup;
aRegIdx = aXRef+pTab->nCol;
- aToOpen = (u8*)(aRegIdx+nIdx);
+ aToOpen = (u8*)(aRegIdx+nIdx+1);
memset(aToOpen, 1, nIdx+1);
aToOpen[nIdx+1] = 0;
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
@@ -132988,7 +133525,7 @@ SQLITE_PRIVATE void sqlite3Update(
** the key for accessing each index.
*/
if( onError==OE_Replace ) bReplace = 1;
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
int reg;
if( chngKey || hasFK>1 || pIdx==pPk
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
@@ -133008,9 +133545,10 @@ SQLITE_PRIVATE void sqlite3Update(
}
}
}
- if( reg==0 ) aToOpen[j+1] = 0;
- aRegIdx[j] = reg;
+ if( reg==0 ) aToOpen[nAllIdx+1] = 0;
+ aRegIdx[nAllIdx] = reg;
}
+ aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
if( bReplace ){
/* If REPLACE conflict resolution might be invoked, open cursors on all
** indexes in case they are needed to delete records. */
@@ -133025,7 +133563,13 @@ SQLITE_PRIVATE void sqlite3Update(
/* Allocate required registers. */
if( !IsVirtual(pTab) ){
- regRowSet = ++pParse->nMem;
+ /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
+ ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
+ ** reallocated. aRegIdx[nAllIdx] is the register in which the main
+ ** table record is written. regRowSet holds the RowSet for the
+ ** two-pass update algorithm. */
+ assert( aRegIdx[nAllIdx]==pParse->nMem );
+ regRowSet = aRegIdx[nAllIdx];
regOldRowid = regNewRowid = ++pParse->nMem;
if( chngPk || pTrigger || hasFK ){
regOld = pParse->nMem + 1;
@@ -133155,6 +133699,8 @@ SQLITE_PRIVATE void sqlite3Update(
** leave it in register regOldRowid. */
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
if( eOnePass==ONEPASS_OFF ){
+ /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
+ aRegIdx[nAllIdx] = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
}
}else{
@@ -133986,6 +134532,7 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
Vdbe *v = sqlite3GetVdbe(pParse);
int iDb = 0;
if( v==0 ) goto build_vacuum_end;
+ if( pParse->nErr ) goto build_vacuum_end;
if( pNm ){
#ifndef SQLITE_BUG_COMPATIBLE_20160819
/* Default behavior: Report an error if the argument to VACUUM is
@@ -135138,6 +135685,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
p = vtabDisconnectAll(db, pTab);
xDestroy = p->pMod->pModule->xDestroy;
assert( xDestroy!=0 ); /* Checked before the virtual table is created */
+ pTab->nTabRef++;
rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
@@ -135146,6 +135694,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
pTab->pVTable = 0;
sqlite3VtabUnlock(p);
}
+ sqlite3DeleteTable(db, pTab);
}
return rc;
@@ -135588,6 +136137,8 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
** planner logic in "where.c". These definitions are broken out into
** a separate source file for easier editing.
*/
+#ifndef SQLITE_WHEREINT_H
+#define SQLITE_WHEREINT_H
/*
** Trace output macros
@@ -136159,6 +136710,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
+#endif /* !defined(SQLITE_WHEREINT_H) */
+
/************** End of whereInt.h ********************************************/
/************** Continuing where we left off in wherecode.c ******************/
@@ -137141,7 +137694,7 @@ static void codeCursorHint(
}
/* If we survive all prior tests, that means this term is worth hinting */
- pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
+ pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
}
if( pExpr!=0 ){
sWalker.xExprCallback = codeCursorHintFixExpr;
@@ -138106,7 +138659,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
pExpr = sqlite3ExprDup(db, pExpr, 0);
- pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
+ pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
}
if( pAndExpr ){
/* The extra 0x10000 bit on the opcode is masked off and does not
@@ -138257,7 +138810,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeGoto(v, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
- if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
+ if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -138690,27 +139243,33 @@ static int isLikeOrGlob(
zNew[iTo++] = zNew[iFrom];
}
zNew[iTo] = 0;
+ assert( iTo>0 );
- /* If the RHS begins with a digit or a minus sign, then the LHS must be
- ** an ordinary column (not a virtual table column) with TEXT affinity.
- ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
- ** even though "lhs LIKE rhs" is true. But if the RHS does not start
- ** with a digit or '-', then "lhs LIKE rhs" will always be false if
- ** the LHS is numeric and so the optimization still works.
+ /* If the LHS is not an ordinary column with TEXT affinity, then the
+ ** pattern prefix boundaries (both the start and end boundaries) must
+ ** not look like a number. Otherwise the pattern might be treated as
+ ** a number, which will invalidate the LIKE optimization.
**
- ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
- ** The RHS pattern must not be '/%' because the termination condition
- ** will then become "x<'0'" and if the affinity is numeric, will then
- ** be converted into "x<0", which is incorrect.
+ ** Getting this right has been a persistent source of bugs in the
+ ** LIKE optimization. See, for example:
+ ** 2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1
+ ** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
+ ** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
+ ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
*/
- if( sqlite3Isdigit(zNew[0])
- || zNew[0]=='-'
- || (zNew[0]+1=='0' && iTo==1)
+ if( pLeft->op!=TK_COLUMN
+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+ || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
){
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
- ){
+ int isNum;
+ double rDummy;
+ isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
+ if( isNum<=0 ){
+ zNew[iTo-1]++;
+ isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
+ zNew[iTo-1]--;
+ }
+ if( isNum>0 ){
sqlite3ExprDelete(db, pPrefix);
sqlite3ValueFree(pVal);
return 0;
@@ -140597,17 +141156,17 @@ static LogEst estLog(LogEst N){
** opcodes into OP_Copy when the table is being accessed via co-routine
** instead of via table lookup.
**
-** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
-** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
-** then each OP_Rowid is transformed into an instruction to increment the
-** value stored in its output register.
+** If the iAutoidxCur is not zero, then any OP_Rowid instructions on
+** cursor iTabCur are transformed into OP_Sequence opcode for the
+** iAutoidxCur cursor, in order to generate unique rowids for the
+** automatic index being generated.
*/
static void translateColumnToCopy(
Parse *pParse, /* Parsing context */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
int iRegister, /* The first column is in this register */
- int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
+ int iAutoidxCur /* If non-zero, cursor of autoindex being generated */
){
Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
@@ -140621,11 +141180,9 @@ static void translateColumnToCopy(
pOp->p2 = pOp->p3;
pOp->p3 = 0;
}else if( pOp->opcode==OP_Rowid ){
- if( bIncrRowid ){
- /* Increment the value stored in the P2 operand of the OP_Rowid. */
- pOp->opcode = OP_AddImm;
- pOp->p1 = pOp->p2;
- pOp->p2 = 1;
+ if( iAutoidxCur ){
+ pOp->opcode = OP_Sequence;
+ pOp->p1 = iAutoidxCur;
}else{
pOp->opcode = OP_Null;
pOp->p1 = 0;
@@ -140772,7 +141329,7 @@ static void constructAutomaticIndex(
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
&& !ExprHasProperty(pExpr, EP_FromJoin)
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
- pPartial = sqlite3ExprAnd(pParse->db, pPartial,
+ pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
@@ -140899,8 +141456,9 @@ static void constructAutomaticIndex(
if( pTabItem->fg.viaCoroutine ){
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
+ assert( pLevel->iIdxCur>0 );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
- pTabItem->regResult, 1);
+ pTabItem->regResult, pLevel->iIdxCur);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
@@ -142704,6 +143262,7 @@ static int whereLoopAddBtreeIndex(
** it to pNew->rRun, which is currently set to the cost of the index
** seek only. Then, if this is a non-covering index, add the cost of
** visiting the rows in the main table. */
+ assert( pSrc->pTab->szTabRow>0 );
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
@@ -146145,6 +146704,7 @@ struct WindowRewrite {
Window *pWin;
SrcList *pSrc;
ExprList *pSub;
+ Table *pTab;
Select *pSubSelect; /* Current sub-select, if any */
};
@@ -146205,6 +146765,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
pExpr->op = TK_COLUMN;
pExpr->iColumn = p->pSub->nExpr-1;
pExpr->iTable = p->pWin->iEphCsr;
+ pExpr->y.pTab = p->pTab;
}
break;
@@ -146248,6 +146809,7 @@ static void selectWindowRewriteEList(
Window *pWin,
SrcList *pSrc,
ExprList *pEList, /* Rewrite expressions in this list */
+ Table *pTab,
ExprList **ppSub /* IN/OUT: Sub-select expression-list */
){
Walker sWalker;
@@ -146259,6 +146821,7 @@ static void selectWindowRewriteEList(
sRewrite.pSub = *ppSub;
sRewrite.pWin = pWin;
sRewrite.pSrc = pSrc;
+ sRewrite.pTab = pTab;
sWalker.pParse = pParse;
sWalker.xExprCallback = selectWindowRewriteExprCb;
@@ -146277,13 +146840,18 @@ static void selectWindowRewriteEList(
static ExprList *exprListAppendList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
- ExprList *pAppend /* List of values to append. Might be NULL */
+ ExprList *pAppend, /* List of values to append. Might be NULL */
+ int bIntToNull
){
if( pAppend ){
int i;
int nInit = pList ? pList->nExpr : 0;
for(i=0; i<pAppend->nExpr; i++){
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
+ if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
+ pDup->op = TK_NULL;
+ pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
+ }
pList = sqlite3ExprListAppend(pParse, pList, pDup);
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
}
@@ -146313,17 +146881,24 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
ExprList *pSublist = 0; /* Expression list for sub-query */
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
+ Table *pTab;
+
+ pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ){
+ return SQLITE_NOMEM;
+ }
p->pSrc = 0;
p->pWhere = 0;
p->pGroupBy = 0;
p->pHaving = 0;
+ p->selFlags &= ~SF_Aggregate;
/* Create the ORDER BY clause for the sub-select. This is the concatenation
** of the window PARTITION and ORDER BY clauses. Then, if this makes it
** redundant, remove the ORDER BY from the parent SELECT. */
pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
- pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
+ pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
if( pSort && p->pOrderBy ){
if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
sqlite3ExprListDelete(db, p->pOrderBy);
@@ -146337,15 +146912,15 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
pMWin->iEphCsr = pParse->nTab++;
pParse->nTab += 3;
- selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
- selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
/* Append the PARTITION BY and ORDER BY expressions to the to the
** sub-select expression list. They are required to figure out where
** boundaries for partitions and sets of peer rows lie. */
- pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
- pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
/* Append the arguments passed to each window function to the
** sub-select expression list. Also allocate two registers for each
@@ -146353,7 +146928,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
- pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
+ pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
if( pWin->pFilter ){
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
@@ -146380,16 +146955,19 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
);
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
+ Table *pTab2;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
- if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
+ pSub->selFlags |= SF_Expanded;
+ pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
+ if( pTab2==0 ){
rc = SQLITE_NOMEM;
}else{
- pSub->selFlags |= SF_Expanded;
- p->selFlags &= ~SF_Aggregate;
- sqlite3SelectPrep(pParse, pSub, 0);
+ memcpy(pTab, pTab2, sizeof(Table));
+ pTab->tabFlags |= TF_Ephemeral;
+ p->pSrc->a[0].pTab = pTab;
+ pTab = pTab2;
}
-
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
@@ -146398,6 +146976,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
+ sqlite3DbFree(db, pTab);
}
return rc;
@@ -148365,28 +148944,28 @@ static void disableLookaside(Parse *pParse){
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
-#define YYNOCODE 301
+#define YYNOCODE 302
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 95
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- With* yy59;
- IdList* yy62;
- struct TrigEvent yy90;
- Upsert* yy136;
- struct FrameBound yy201;
- u8 yy238;
- const char* yy294;
- Window* yy295;
- struct {int value; int mask;} yy355;
- ExprList* yy434;
- TriggerStep* yy455;
- Select* yy457;
- SrcList* yy483;
- int yy494;
- Expr* yy524;
+ TriggerStep* yy11;
+ IdList* yy76;
+ ExprList* yy94;
+ Upsert* yy95;
+ int yy100;
+ Expr* yy102;
+ struct {int value; int mask;} yy199;
+ u8 yy218;
+ With* yy243;
+ struct TrigEvent yy298;
+ Window* yy379;
+ struct FrameBound yy389;
+ Select* yy391;
+ SrcList* yy407;
+ const char* yy528;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -148402,17 +148981,17 @@ typedef union {
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-#define YYNSTATE 541
-#define YYNRULE 375
+#define YYNSTATE 540
+#define YYNRULE 376
#define YYNTOKEN 176
-#define YY_MAX_SHIFT 540
-#define YY_MIN_SHIFTREDUCE 784
+#define YY_MAX_SHIFT 539
+#define YY_MIN_SHIFTREDUCE 783
#define YY_MAX_SHIFTREDUCE 1158
#define YY_ERROR_ACTION 1159
#define YY_ACCEPT_ACTION 1160
#define YY_NO_ACTION 1161
#define YY_MIN_REDUCE 1162
-#define YY_MAX_REDUCE 1536
+#define YY_MAX_REDUCE 1537
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -148481,450 +149060,450 @@ typedef union {
*********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (2142)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 535, 1323, 112, 109, 209, 112, 109, 209, 1160, 1,
- /* 10 */ 1, 540, 2, 1164, 535, 1292, 1228, 1207, 289, 384,
- /* 20 */ 134, 42, 42, 1427, 382, 1228, 9, 1241, 242, 492,
- /* 30 */ 1291, 915, 373, 379, 1026, 70, 70, 427, 1026, 916,
- /* 40 */ 529, 529, 529, 119, 120, 110, 1136, 1136, 981, 984,
- /* 50 */ 974, 974, 117, 117, 118, 118, 118, 118, 380, 264,
- /* 60 */ 264, 264, 264, 1134, 264, 264, 112, 109, 209, 397,
- /* 70 */ 454, 517, 532, 491, 532, 1233, 1233, 532, 239, 206,
- /* 80 */ 493, 112, 109, 209, 464, 219, 118, 118, 118, 118,
- /* 90 */ 111, 393, 440, 444, 16, 16, 116, 116, 116, 116,
- /* 100 */ 115, 115, 114, 114, 114, 113, 415, 971, 971, 982,
- /* 110 */ 985, 235, 1463, 351, 1134, 419, 384, 116, 116, 116,
- /* 120 */ 116, 115, 115, 114, 114, 114, 113, 415, 116, 116,
- /* 130 */ 116, 116, 115, 115, 114, 114, 114, 113, 415, 961,
+ /* 0 */ 112, 109, 209, 112, 109, 209, 1160, 1, 1, 539,
+ /* 10 */ 2, 1164, 490, 1193, 1293, 534, 289, 1196, 134, 383,
+ /* 20 */ 1485, 1428, 1164, 1229, 1208, 1242, 1195, 289, 491, 134,
+ /* 30 */ 373, 915, 1229, 443, 16, 16, 1242, 70, 70, 916,
+ /* 40 */ 242, 1292, 296, 119, 120, 110, 1136, 1136, 981, 984,
+ /* 50 */ 974, 974, 117, 117, 118, 118, 118, 118, 264, 264,
+ /* 60 */ 190, 264, 264, 264, 264, 112, 109, 209, 362, 264,
+ /* 70 */ 264, 531, 376, 497, 531, 1134, 531, 1501, 239, 206,
+ /* 80 */ 338, 9, 531, 242, 219, 1203, 118, 118, 118, 118,
+ /* 90 */ 111, 439, 112, 109, 209, 219, 116, 116, 116, 116,
+ /* 100 */ 115, 115, 114, 114, 114, 113, 414, 115, 115, 114,
+ /* 110 */ 114, 114, 113, 414, 418, 12, 383, 400, 1134, 114,
+ /* 120 */ 114, 114, 113, 414, 1115, 418, 1134, 1392, 116, 116,
+ /* 130 */ 116, 116, 115, 115, 114, 114, 114, 113, 414, 961,
/* 140 */ 119, 120, 110, 1136, 1136, 981, 984, 974, 974, 117,
- /* 150 */ 117, 118, 118, 118, 118, 952, 415, 941, 298, 951,
- /* 160 */ 941, 1480, 540, 2, 1164, 1115, 535, 1458, 160, 289,
- /* 170 */ 6, 134, 1504, 389, 406, 975, 338, 1024, 1241, 337,
- /* 180 */ 1089, 1476, 1089, 118, 118, 118, 118, 42, 42, 329,
+ /* 150 */ 117, 118, 118, 118, 118, 952, 534, 414, 941, 951,
+ /* 160 */ 1481, 539, 2, 1164, 1505, 534, 160, 175, 289, 1134,
+ /* 170 */ 134, 434, 312, 297, 1115, 1116, 1117, 1242, 70, 70,
+ /* 180 */ 1089, 338, 1089, 118, 118, 118, 118, 42, 42, 448,
/* 190 */ 951, 951, 953, 116, 116, 116, 116, 115, 115, 114,
- /* 200 */ 114, 114, 113, 415, 311, 430, 299, 311, 881, 160,
- /* 210 */ 264, 264, 401, 384, 324, 1115, 1116, 1117, 288, 526,
- /* 220 */ 96, 159, 1441, 532, 141, 116, 116, 116, 116, 115,
- /* 230 */ 115, 114, 114, 114, 113, 415, 219, 119, 120, 110,
+ /* 200 */ 114, 114, 113, 414, 1115, 311, 264, 264, 82, 441,
+ /* 210 */ 264, 264, 190, 383, 284, 12, 288, 525, 407, 531,
+ /* 220 */ 96, 159, 458, 531, 371, 116, 116, 116, 116, 115,
+ /* 230 */ 115, 114, 114, 114, 113, 414, 219, 119, 120, 110,
/* 240 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
- /* 250 */ 118, 118, 115, 115, 114, 114, 114, 113, 415, 288,
- /* 260 */ 526, 403, 533, 121, 870, 870, 419, 250, 267, 336,
- /* 270 */ 475, 331, 474, 236, 160, 319, 1084, 322, 1465, 329,
- /* 280 */ 350, 12, 535, 384, 502, 1115, 1084, 435, 312, 1084,
+ /* 250 */ 118, 118, 511, 1477, 1115, 1116, 1117, 113, 414, 534,
+ /* 260 */ 528, 528, 528, 121, 534, 1427, 418, 116, 116, 116,
+ /* 270 */ 116, 115, 115, 114, 114, 114, 113, 414, 1464, 351,
+ /* 280 */ 270, 42, 42, 383, 187, 1115, 70, 70, 533, 433,
/* 290 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
- /* 300 */ 415, 535, 836, 42, 42, 138, 426, 119, 120, 110,
+ /* 300 */ 414, 534, 1339, 405, 159, 411, 410, 119, 120, 110,
/* 310 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
- /* 320 */ 118, 118, 70, 70, 288, 526, 412, 411, 480, 1457,
- /* 330 */ 335, 79, 6, 473, 1140, 1115, 1116, 1117, 501, 1142,
- /* 340 */ 334, 837, 811, 1484, 512, 1164, 534, 1141, 123, 187,
- /* 350 */ 289, 384, 134, 448, 434, 1115, 80, 349, 498, 1241,
+ /* 320 */ 118, 118, 285, 42, 42, 349, 411, 410, 514, 479,
+ /* 330 */ 1458, 79, 1084, 6, 1140, 1115, 1116, 1117, 480, 1142,
+ /* 340 */ 501, 1115, 1084, 123, 238, 1084, 136, 1141, 1234, 1234,
+ /* 350 */ 1143, 383, 1143, 1115, 167, 426, 80, 447, 512, 1451,
/* 360 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
- /* 370 */ 415, 1143, 1115, 1143, 459, 119, 120, 110, 1136, 1136,
+ /* 370 */ 414, 1143, 1466, 1143, 350, 119, 120, 110, 1136, 1136,
/* 380 */ 981, 984, 974, 974, 117, 117, 118, 118, 118, 118,
- /* 390 */ 404, 264, 264, 811, 1463, 506, 368, 1156, 535, 114,
- /* 400 */ 114, 114, 113, 415, 532, 1115, 1116, 1117, 231, 518,
- /* 410 */ 1500, 472, 469, 468, 175, 497, 422, 219, 1202, 70,
- /* 420 */ 70, 467, 1115, 1116, 1117, 176, 201, 200, 116, 116,
- /* 430 */ 116, 116, 115, 115, 114, 114, 114, 113, 415, 535,
- /* 440 */ 1115, 264, 264, 435, 312, 1115, 273, 419, 384, 513,
- /* 450 */ 1450, 1115, 326, 1084, 532, 517, 82, 1084, 167, 388,
- /* 460 */ 69, 69, 1115, 1084, 519, 509, 1084, 1084, 12, 1157,
- /* 470 */ 1084, 420, 119, 120, 110, 1136, 1136, 981, 984, 974,
- /* 480 */ 974, 117, 117, 118, 118, 118, 118, 258, 258, 535,
- /* 490 */ 1115, 1116, 1117, 1045, 535, 1115, 1116, 1117, 1323, 535,
- /* 500 */ 532, 1115, 1116, 1117, 296, 483, 1211, 818, 1046, 448,
- /* 510 */ 70, 70, 1115, 1116, 1117, 50, 50, 448, 356, 500,
- /* 520 */ 70, 70, 207, 1047, 32, 116, 116, 116, 116, 115,
- /* 530 */ 115, 114, 114, 114, 113, 415, 453, 264, 264, 1115,
- /* 540 */ 450, 449, 961, 508, 856, 384, 517, 5, 900, 822,
- /* 550 */ 532, 484, 181, 1115, 857, 516, 517, 818, 952, 507,
- /* 560 */ 3, 1115, 951, 1231, 1231, 482, 398, 1115, 1095, 119,
+ /* 390 */ 402, 1115, 1116, 1117, 500, 534, 250, 267, 336, 474,
+ /* 400 */ 331, 473, 236, 1115, 1116, 1117, 231, 1115, 329, 471,
+ /* 410 */ 468, 467, 509, 1458, 1464, 505, 6, 70, 70, 466,
+ /* 420 */ 181, 380, 379, 534, 971, 971, 982, 985, 116, 116,
+ /* 430 */ 116, 116, 115, 115, 114, 114, 114, 113, 414, 1115,
+ /* 440 */ 412, 412, 412, 496, 1115, 69, 69, 235, 383, 288,
+ /* 450 */ 525, 273, 326, 516, 337, 458, 1084, 1115, 1116, 1117,
+ /* 460 */ 1232, 1232, 492, 160, 508, 441, 1084, 1067, 1531, 1084,
+ /* 470 */ 207, 1531, 119, 120, 110, 1136, 1136, 981, 984, 974,
+ /* 480 */ 974, 117, 117, 118, 118, 118, 118, 881, 534, 1115,
+ /* 490 */ 1116, 1117, 975, 534, 1115, 1116, 1117, 534, 421, 534,
+ /* 500 */ 141, 534, 176, 356, 517, 1119, 32, 511, 482, 388,
+ /* 510 */ 70, 70, 818, 288, 525, 70, 70, 441, 499, 50,
+ /* 520 */ 50, 70, 70, 70, 70, 116, 116, 116, 116, 115,
+ /* 530 */ 115, 114, 114, 114, 113, 414, 274, 264, 264, 1115,
+ /* 540 */ 1065, 264, 264, 1115, 355, 383, 409, 961, 1439, 822,
+ /* 550 */ 531, 516, 190, 419, 531, 483, 1119, 516, 337, 516,
+ /* 560 */ 518, 1115, 818, 952, 382, 458, 515, 951, 481, 119,
/* 570 */ 120, 110, 1136, 1136, 981, 984, 974, 974, 117, 117,
- /* 580 */ 118, 118, 118, 118, 1115, 535, 238, 1115, 1391, 1115,
- /* 590 */ 1116, 1117, 159, 951, 951, 953, 231, 1115, 259, 472,
- /* 600 */ 469, 468, 310, 1115, 1116, 1117, 13, 13, 297, 467,
- /* 610 */ 276, 1115, 1116, 1117, 412, 411, 1095, 1115, 1116, 1117,
- /* 620 */ 395, 355, 116, 116, 116, 116, 115, 115, 114, 114,
- /* 630 */ 114, 113, 415, 208, 1115, 1116, 1117, 1115, 1116, 1117,
- /* 640 */ 264, 264, 384, 337, 902, 393, 815, 1115, 1116, 1117,
- /* 650 */ 413, 413, 413, 532, 112, 109, 209, 309, 900, 1143,
- /* 660 */ 535, 1143, 535, 393, 901, 1210, 119, 120, 110, 1136,
+ /* 580 */ 118, 118, 118, 118, 1338, 278, 1045, 278, 275, 1115,
+ /* 590 */ 1116, 1117, 259, 1115, 1116, 1117, 534, 5, 951, 951,
+ /* 600 */ 953, 1046, 231, 3, 143, 471, 468, 467, 1391, 463,
+ /* 610 */ 1115, 1115, 1116, 1117, 1452, 466, 1047, 836, 70, 70,
+ /* 620 */ 480, 534, 116, 116, 116, 116, 115, 115, 114, 114,
+ /* 630 */ 114, 113, 414, 95, 1115, 287, 235, 856, 902, 420,
+ /* 640 */ 1115, 534, 383, 13, 13, 381, 815, 857, 472, 112,
+ /* 650 */ 109, 209, 1115, 337, 413, 309, 837, 394, 1436, 534,
+ /* 660 */ 1115, 1116, 1117, 54, 54, 291, 119, 120, 110, 1136,
/* 670 */ 1136, 981, 984, 974, 974, 117, 117, 118, 118, 118,
- /* 680 */ 118, 13, 13, 13, 13, 265, 265, 535, 143, 264,
- /* 690 */ 264, 288, 526, 535, 1119, 400, 535, 402, 532, 510,
- /* 700 */ 1457, 512, 532, 6, 113, 415, 1067, 1530, 70, 70,
- /* 710 */ 1530, 535, 271, 535, 70, 70, 535, 13, 13, 116,
- /* 720 */ 116, 116, 116, 115, 115, 114, 114, 114, 113, 415,
- /* 730 */ 272, 277, 13, 13, 13, 13, 535, 13, 13, 384,
- /* 740 */ 535, 304, 425, 1100, 284, 1119, 184, 801, 185, 338,
- /* 750 */ 285, 514, 1532, 369, 1239, 1438, 1182, 70, 70, 425,
- /* 760 */ 424, 70, 70, 119, 120, 110, 1136, 1136, 981, 984,
- /* 770 */ 974, 974, 117, 117, 118, 118, 118, 118, 190, 1065,
- /* 780 */ 1067, 1531, 442, 107, 1531, 408, 264, 264, 264, 264,
- /* 790 */ 383, 1396, 261, 410, 95, 900, 485, 414, 421, 532,
- /* 800 */ 1045, 532, 301, 1133, 303, 488, 433, 1451, 1396, 1398,
- /* 810 */ 278, 535, 278, 520, 1435, 1046, 116, 116, 116, 116,
- /* 820 */ 115, 115, 114, 114, 114, 113, 415, 425, 264, 264,
- /* 830 */ 1047, 190, 54, 54, 535, 291, 384, 264, 264, 362,
- /* 840 */ 962, 532, 1004, 376, 1084, 264, 264, 1029, 1029, 456,
- /* 850 */ 532, 523, 270, 1065, 1084, 55, 55, 1084, 532, 442,
+ /* 680 */ 118, 13, 13, 1084, 1115, 1116, 1117, 901, 264, 264,
+ /* 690 */ 1115, 1116, 1117, 1084, 292, 399, 1084, 800, 388, 140,
+ /* 700 */ 295, 531, 1115, 1116, 1117, 403, 447, 532, 534, 870,
+ /* 710 */ 870, 534, 1240, 534, 329, 534, 1185, 389, 534, 116,
+ /* 720 */ 116, 116, 116, 115, 115, 114, 114, 114, 113, 414,
+ /* 730 */ 13, 13, 1024, 13, 13, 13, 13, 13, 13, 383,
+ /* 740 */ 13, 13, 424, 1100, 401, 264, 264, 277, 160, 184,
+ /* 750 */ 1182, 185, 1533, 369, 513, 484, 432, 487, 531, 424,
+ /* 760 */ 423, 1397, 941, 119, 120, 110, 1136, 1136, 981, 984,
+ /* 770 */ 974, 974, 117, 117, 118, 118, 118, 118, 1397, 1399,
+ /* 780 */ 425, 519, 392, 264, 264, 1029, 1029, 455, 264, 264,
+ /* 790 */ 264, 264, 1004, 304, 261, 1278, 531, 900, 288, 525,
+ /* 800 */ 310, 531, 493, 531, 1067, 1532, 458, 387, 1532, 311,
+ /* 810 */ 429, 299, 534, 107, 264, 264, 116, 116, 116, 116,
+ /* 820 */ 115, 115, 114, 114, 114, 113, 414, 531, 424, 1384,
+ /* 830 */ 507, 258, 258, 1246, 55, 55, 383, 1277, 265, 265,
+ /* 840 */ 962, 324, 434, 312, 531, 531, 506, 1397, 1026, 1241,
+ /* 850 */ 298, 531, 1026, 445, 301, 1095, 303, 534, 368, 1156,
/* 860 */ 119, 120, 110, 1136, 1136, 981, 984, 974, 974, 117,
- /* 870 */ 117, 118, 118, 118, 118, 535, 1396, 190, 302, 1383,
- /* 880 */ 208, 535, 789, 790, 791, 535, 515, 535, 1323, 371,
- /* 890 */ 337, 234, 233, 232, 459, 515, 15, 15, 459, 477,
- /* 900 */ 459, 459, 44, 44, 136, 900, 56, 56, 57, 57,
- /* 910 */ 1185, 390, 197, 116, 116, 116, 116, 115, 115, 114,
- /* 920 */ 114, 114, 113, 415, 535, 876, 535, 442, 535, 274,
- /* 930 */ 875, 1323, 357, 384, 353, 140, 1426, 946, 1455, 1323,
- /* 940 */ 1390, 6, 1240, 1236, 292, 58, 58, 59, 59, 60,
- /* 950 */ 60, 535, 1456, 384, 535, 6, 399, 119, 120, 110,
+ /* 870 */ 117, 118, 118, 118, 118, 1045, 534, 1065, 534, 15,
+ /* 880 */ 15, 1084, 208, 1324, 453, 452, 534, 1324, 534, 449,
+ /* 890 */ 1046, 1084, 494, 458, 1084, 234, 233, 232, 44, 44,
+ /* 900 */ 56, 56, 319, 1095, 322, 1047, 534, 900, 57, 57,
+ /* 910 */ 58, 58, 534, 116, 116, 116, 116, 115, 115, 114,
+ /* 920 */ 114, 114, 113, 414, 534, 514, 522, 534, 59, 59,
+ /* 930 */ 302, 1157, 534, 383, 60, 60, 1237, 946, 788, 789,
+ /* 940 */ 790, 1459, 1456, 446, 6, 6, 61, 61, 1212, 45,
+ /* 950 */ 45, 534, 396, 383, 46, 46, 397, 119, 120, 110,
/* 960 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
- /* 970 */ 118, 118, 61, 61, 535, 45, 45, 119, 120, 110,
+ /* 970 */ 118, 118, 428, 48, 48, 534, 392, 119, 120, 110,
/* 980 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
- /* 990 */ 118, 118, 1477, 479, 202, 46, 46, 275, 95, 455,
- /* 1000 */ 535, 212, 535, 337, 535, 1454, 535, 409, 6, 242,
+ /* 990 */ 118, 118, 1324, 368, 1066, 447, 825, 49, 49, 534,
+ /* 1000 */ 458, 357, 534, 353, 534, 138, 534, 337, 1478, 478,
/* 1010 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
- /* 1020 */ 415, 48, 48, 49, 49, 62, 62, 63, 63, 535,
+ /* 1020 */ 414, 62, 62, 392, 63, 63, 64, 64, 14, 14,
/* 1030 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
- /* 1040 */ 415, 535, 459, 535, 1134, 535, 1151, 535, 142, 535,
- /* 1050 */ 64, 64, 535, 1338, 535, 494, 535, 446, 535, 1264,
- /* 1060 */ 535, 1337, 14, 14, 65, 65, 125, 125, 66, 66,
- /* 1070 */ 51, 51, 535, 67, 67, 68, 68, 52, 52, 147,
- /* 1080 */ 147, 148, 148, 1453, 317, 98, 6, 535, 1245, 481,
- /* 1090 */ 535, 827, 535, 75, 75, 1134, 102, 481, 100, 535,
- /* 1100 */ 532, 535, 368, 1066, 1503, 384, 535, 845, 53, 53,
- /* 1110 */ 93, 71, 71, 126, 126, 295, 528, 390, 288, 526,
- /* 1120 */ 72, 72, 127, 127, 139, 384, 38, 128, 128, 119,
+ /* 1040 */ 414, 534, 810, 317, 271, 534, 1457, 825, 534, 6,
+ /* 1050 */ 534, 1324, 534, 142, 534, 1442, 534, 212, 534, 1324,
+ /* 1060 */ 534, 398, 305, 65, 65, 534, 1157, 125, 125, 476,
+ /* 1070 */ 66, 66, 51, 51, 67, 67, 68, 68, 52, 52,
+ /* 1080 */ 147, 147, 148, 148, 534, 98, 534, 75, 75, 276,
+ /* 1090 */ 534, 272, 534, 810, 534, 876, 534, 527, 389, 534,
+ /* 1100 */ 875, 534, 1151, 202, 534, 383, 53, 53, 71, 71,
+ /* 1110 */ 288, 525, 126, 126, 72, 72, 127, 127, 128, 128,
+ /* 1120 */ 454, 124, 124, 146, 146, 383, 145, 145, 408, 119,
/* 1130 */ 120, 110, 1136, 1136, 981, 984, 974, 974, 117, 117,
- /* 1140 */ 118, 118, 118, 118, 535, 495, 535, 447, 535, 119,
+ /* 1140 */ 118, 118, 118, 118, 534, 900, 534, 95, 534, 119,
/* 1150 */ 120, 110, 1136, 1136, 981, 984, 974, 974, 117, 117,
- /* 1160 */ 118, 118, 118, 118, 235, 124, 124, 146, 146, 145,
- /* 1170 */ 145, 287, 535, 1277, 535, 1157, 535, 391, 161, 263,
- /* 1180 */ 206, 381, 116, 116, 116, 116, 115, 115, 114, 114,
- /* 1190 */ 114, 113, 415, 132, 132, 131, 131, 129, 129, 535,
- /* 1200 */ 30, 535, 116, 116, 116, 116, 115, 115, 114, 114,
- /* 1210 */ 114, 113, 415, 535, 216, 1062, 1276, 535, 370, 535,
- /* 1220 */ 130, 130, 74, 74, 535, 915, 389, 876, 17, 437,
- /* 1230 */ 429, 31, 875, 916, 76, 76, 266, 101, 73, 73,
- /* 1240 */ 43, 43, 835, 834, 308, 47, 47, 95, 825, 943,
- /* 1250 */ 441, 938, 241, 241, 305, 443, 313, 384, 241, 95,
- /* 1260 */ 842, 843, 193, 465, 1209, 327, 237, 436, 95, 1011,
- /* 1270 */ 1007, 909, 873, 237, 241, 107, 1023, 384, 1023, 955,
- /* 1280 */ 1415, 119, 120, 110, 1136, 1136, 981, 984, 974, 974,
- /* 1290 */ 117, 117, 118, 118, 118, 118, 1022, 809, 1022, 825,
+ /* 1160 */ 118, 118, 118, 118, 390, 161, 132, 132, 131, 131,
+ /* 1170 */ 129, 129, 534, 915, 534, 1455, 534, 1454, 6, 1416,
+ /* 1180 */ 6, 916, 116, 116, 116, 116, 115, 115, 114, 114,
+ /* 1190 */ 114, 113, 414, 1415, 130, 130, 74, 74, 76, 76,
+ /* 1200 */ 534, 30, 116, 116, 116, 116, 115, 115, 114, 114,
+ /* 1210 */ 114, 113, 414, 534, 263, 206, 534, 1133, 1504, 93,
+ /* 1220 */ 876, 845, 73, 73, 102, 875, 100, 139, 17, 38,
+ /* 1230 */ 208, 1062, 31, 450, 370, 43, 43, 101, 47, 47,
+ /* 1240 */ 827, 216, 436, 308, 943, 440, 95, 241, 241, 442,
+ /* 1250 */ 313, 464, 241, 95, 237, 900, 327, 383, 266, 95,
+ /* 1260 */ 835, 834, 193, 335, 938, 314, 1011, 435, 842, 843,
+ /* 1270 */ 955, 1007, 909, 334, 237, 241, 873, 383, 1023, 107,
+ /* 1280 */ 1023, 119, 120, 110, 1136, 1136, 981, 984, 974, 974,
+ /* 1290 */ 117, 117, 118, 118, 118, 118, 1022, 808, 1022, 1274,
/* 1300 */ 137, 119, 108, 110, 1136, 1136, 981, 984, 974, 974,
- /* 1310 */ 117, 117, 118, 118, 118, 118, 874, 1414, 451, 107,
- /* 1320 */ 1011, 314, 1273, 318, 218, 321, 323, 325, 1224, 1208,
- /* 1330 */ 955, 330, 339, 340, 116, 116, 116, 116, 115, 115,
- /* 1340 */ 114, 114, 114, 113, 415, 1285, 1322, 1260, 1493, 1470,
- /* 1350 */ 1271, 283, 521, 1328, 116, 116, 116, 116, 115, 115,
- /* 1360 */ 114, 114, 114, 113, 415, 1191, 1184, 1173, 1172, 1174,
- /* 1370 */ 522, 1487, 211, 460, 384, 256, 199, 367, 1257, 342,
- /* 1380 */ 195, 470, 307, 344, 11, 333, 525, 445, 1307, 1315,
- /* 1390 */ 375, 203, 1207, 1151, 384, 346, 1387, 188, 360, 120,
+ /* 1310 */ 117, 117, 118, 118, 118, 118, 874, 1011, 318, 107,
+ /* 1320 */ 321, 955, 323, 325, 1225, 1211, 197, 1210, 1209, 330,
+ /* 1330 */ 339, 1265, 340, 283, 116, 116, 116, 116, 115, 115,
+ /* 1340 */ 114, 114, 114, 113, 414, 1286, 1323, 1261, 1471, 1272,
+ /* 1350 */ 520, 218, 521, 1329, 116, 116, 116, 116, 115, 115,
+ /* 1360 */ 114, 114, 114, 113, 414, 1192, 1184, 1173, 1172, 1174,
+ /* 1370 */ 1494, 1488, 459, 256, 383, 1258, 342, 199, 367, 344,
+ /* 1380 */ 211, 195, 307, 444, 11, 346, 469, 333, 1308, 1316,
+ /* 1390 */ 375, 427, 203, 360, 383, 1388, 188, 1387, 189, 120,
/* 1400 */ 110, 1136, 1136, 981, 984, 974, 974, 117, 117, 118,
- /* 1410 */ 118, 118, 118, 1386, 428, 1490, 245, 300, 348, 1148,
+ /* 1410 */ 118, 118, 118, 1208, 1151, 300, 348, 1491, 245, 1148,
/* 1420 */ 110, 1136, 1136, 981, 984, 974, 974, 117, 117, 118,
- /* 1430 */ 118, 118, 118, 189, 198, 1434, 1432, 78, 81, 163,
- /* 1440 */ 82, 392, 439, 1392, 173, 105, 527, 35, 4, 157,
- /* 1450 */ 1312, 116, 116, 116, 116, 115, 115, 114, 114, 114,
- /* 1460 */ 113, 415, 530, 165, 93, 1304, 431, 432, 168, 463,
- /* 1470 */ 221, 116, 116, 116, 116, 115, 115, 114, 114, 114,
- /* 1480 */ 113, 415, 169, 452, 170, 416, 171, 374, 372, 438,
- /* 1490 */ 36, 1318, 177, 225, 1381, 87, 458, 524, 1403, 316,
- /* 1500 */ 257, 105, 527, 227, 4, 182, 461, 160, 320, 228,
- /* 1510 */ 377, 1175, 476, 229, 1227, 1226, 405, 1225, 530, 1218,
- /* 1520 */ 961, 378, 1199, 1198, 827, 332, 103, 103, 1197, 407,
- /* 1530 */ 8, 1217, 1502, 104, 487, 416, 537, 536, 281, 282,
- /* 1540 */ 951, 416, 490, 1268, 496, 92, 341, 243, 1269, 343,
- /* 1550 */ 244, 1267, 122, 524, 345, 1461, 515, 288, 526, 10,
- /* 1560 */ 354, 1266, 1460, 352, 504, 1250, 99, 1367, 94, 503,
- /* 1570 */ 499, 951, 951, 953, 954, 27, 961, 347, 1249, 194,
- /* 1580 */ 251, 358, 103, 103, 359, 1181, 34, 538, 1110, 104,
- /* 1590 */ 255, 416, 537, 536, 286, 252, 951, 254, 539, 149,
- /* 1600 */ 1170, 1419, 1165, 1420, 1418, 150, 1417, 135, 279, 785,
- /* 1610 */ 151, 417, 1195, 196, 290, 210, 386, 1194, 269, 387,
- /* 1620 */ 162, 1021, 133, 77, 1192, 1019, 935, 951, 951, 953,
- /* 1630 */ 954, 27, 1479, 1104, 418, 164, 153, 268, 217, 166,
- /* 1640 */ 859, 306, 366, 366, 365, 253, 363, 220, 1035, 798,
- /* 1650 */ 172, 939, 105, 527, 155, 4, 394, 174, 396, 156,
- /* 1660 */ 83, 1038, 213, 84, 294, 85, 86, 223, 222, 530,
- /* 1670 */ 1034, 144, 293, 18, 224, 315, 241, 1027, 1145, 178,
- /* 1680 */ 457, 226, 179, 37, 800, 334, 462, 230, 328, 466,
- /* 1690 */ 180, 471, 416, 88, 19, 20, 89, 280, 838, 158,
- /* 1700 */ 191, 90, 215, 478, 524, 1097, 204, 192, 987, 91,
- /* 1710 */ 152, 1070, 39, 154, 1071, 504, 486, 40, 489, 205,
- /* 1720 */ 505, 260, 105, 527, 214, 4, 908, 961, 262, 183,
- /* 1730 */ 240, 21, 903, 103, 103, 107, 22, 1086, 23, 530,
- /* 1740 */ 104, 1088, 416, 537, 536, 24, 1093, 951, 25, 1074,
- /* 1750 */ 1090, 1094, 7, 33, 511, 186, 26, 1002, 385, 95,
- /* 1760 */ 988, 986, 416, 288, 526, 990, 1044, 246, 1043, 247,
- /* 1770 */ 991, 28, 41, 106, 524, 956, 810, 29, 951, 951,
- /* 1780 */ 953, 954, 27, 531, 361, 504, 423, 248, 869, 249,
- /* 1790 */ 503, 1495, 364, 1105, 1161, 1494, 1161, 961, 1161, 1161,
+ /* 1430 */ 118, 118, 118, 198, 1435, 1433, 524, 78, 391, 163,
+ /* 1440 */ 82, 1393, 438, 173, 81, 105, 526, 1313, 4, 35,
+ /* 1450 */ 157, 116, 116, 116, 116, 115, 115, 114, 114, 114,
+ /* 1460 */ 113, 414, 529, 165, 93, 430, 1305, 168, 169, 431,
+ /* 1470 */ 462, 116, 116, 116, 116, 115, 115, 114, 114, 114,
+ /* 1480 */ 113, 414, 170, 171, 221, 415, 372, 437, 1319, 177,
+ /* 1490 */ 374, 36, 451, 225, 1382, 87, 457, 523, 257, 1404,
+ /* 1500 */ 316, 105, 526, 227, 4, 182, 460, 160, 320, 228,
+ /* 1510 */ 377, 1175, 475, 229, 1228, 404, 1227, 1226, 529, 827,
+ /* 1520 */ 961, 1219, 378, 1200, 1199, 406, 103, 103, 1218, 332,
+ /* 1530 */ 8, 281, 1198, 104, 1503, 415, 536, 535, 486, 282,
+ /* 1540 */ 951, 415, 489, 495, 92, 244, 1269, 341, 243, 122,
+ /* 1550 */ 1270, 343, 514, 523, 1268, 1462, 10, 288, 525, 345,
+ /* 1560 */ 1461, 354, 99, 352, 503, 94, 1267, 347, 1251, 502,
+ /* 1570 */ 498, 951, 951, 953, 954, 27, 961, 1250, 194, 358,
+ /* 1580 */ 251, 359, 103, 103, 1181, 34, 537, 1110, 252, 104,
+ /* 1590 */ 254, 415, 536, 535, 255, 1368, 951, 1420, 286, 538,
+ /* 1600 */ 1170, 1165, 1421, 135, 1419, 1418, 149, 150, 279, 784,
+ /* 1610 */ 416, 196, 151, 290, 210, 200, 77, 385, 269, 386,
+ /* 1620 */ 133, 162, 935, 1021, 201, 1019, 153, 951, 951, 953,
+ /* 1630 */ 954, 27, 1480, 1104, 417, 164, 217, 268, 859, 166,
+ /* 1640 */ 306, 1035, 366, 366, 365, 253, 363, 220, 172, 797,
+ /* 1650 */ 939, 155, 105, 526, 393, 4, 395, 174, 156, 83,
+ /* 1660 */ 1038, 84, 213, 85, 294, 222, 86, 223, 1034, 529,
+ /* 1670 */ 144, 18, 293, 224, 315, 456, 241, 1027, 1145, 178,
+ /* 1680 */ 226, 179, 37, 799, 334, 461, 230, 465, 470, 838,
+ /* 1690 */ 180, 88, 415, 19, 280, 328, 20, 89, 90, 158,
+ /* 1700 */ 191, 477, 215, 1097, 523, 204, 192, 987, 91, 1070,
+ /* 1710 */ 152, 39, 485, 154, 1071, 503, 40, 488, 205, 260,
+ /* 1720 */ 504, 262, 105, 526, 214, 4, 908, 961, 183, 240,
+ /* 1730 */ 903, 107, 1086, 103, 103, 21, 22, 1088, 23, 529,
+ /* 1740 */ 104, 24, 415, 536, 535, 1090, 1093, 951, 1094, 25,
+ /* 1750 */ 1074, 33, 7, 26, 510, 1002, 247, 186, 384, 95,
+ /* 1760 */ 988, 986, 415, 288, 525, 990, 1044, 246, 1043, 991,
+ /* 1770 */ 28, 41, 530, 956, 523, 809, 106, 29, 951, 951,
+ /* 1780 */ 953, 954, 27, 869, 361, 503, 422, 248, 364, 1105,
+ /* 1790 */ 502, 249, 1161, 1496, 1495, 1161, 1161, 961, 1161, 1161,
/* 1800 */ 1161, 1161, 1161, 103, 103, 1161, 1161, 1161, 1161, 1161,
- /* 1810 */ 104, 1161, 416, 537, 536, 1104, 418, 951, 1161, 268,
+ /* 1810 */ 104, 1161, 415, 536, 535, 1104, 417, 951, 1161, 268,
/* 1820 */ 1161, 1161, 1161, 1161, 366, 366, 365, 253, 363, 1161,
- /* 1830 */ 1161, 798, 1161, 1161, 1161, 1161, 105, 527, 1161, 4,
+ /* 1830 */ 1161, 797, 1161, 1161, 1161, 1161, 105, 526, 1161, 4,
/* 1840 */ 1161, 1161, 1161, 1161, 213, 1161, 294, 1161, 951, 951,
- /* 1850 */ 953, 954, 27, 530, 293, 1161, 1161, 1161, 1161, 1161,
+ /* 1850 */ 953, 954, 27, 529, 293, 1161, 1161, 1161, 1161, 1161,
/* 1860 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
- /* 1870 */ 1161, 1161, 1161, 1161, 1161, 1161, 416, 1161, 1161, 1161,
- /* 1880 */ 1161, 1161, 1161, 1161, 215, 1161, 1161, 1161, 524, 1161,
- /* 1890 */ 1161, 1161, 152, 1161, 1161, 154, 105, 527, 1161, 4,
+ /* 1870 */ 1161, 1161, 1161, 1161, 1161, 1161, 415, 1161, 1161, 1161,
+ /* 1880 */ 1161, 1161, 1161, 1161, 215, 1161, 1161, 1161, 523, 1161,
+ /* 1890 */ 1161, 1161, 152, 1161, 1161, 154, 105, 526, 1161, 4,
/* 1900 */ 1161, 1161, 1161, 1161, 1161, 1161, 214, 1161, 1161, 1161,
- /* 1910 */ 1161, 961, 1161, 530, 1161, 1161, 1161, 103, 103, 880,
- /* 1920 */ 1161, 1161, 1161, 1161, 104, 1161, 416, 537, 536, 1161,
- /* 1930 */ 1161, 951, 1161, 1161, 1161, 1161, 416, 1161, 1161, 1161,
- /* 1940 */ 385, 1161, 1161, 1161, 1161, 288, 526, 1161, 524, 1161,
- /* 1950 */ 1161, 1161, 1161, 1161, 1161, 1161, 97, 527, 1161, 4,
- /* 1960 */ 1161, 1161, 951, 951, 953, 954, 27, 1161, 423, 1161,
- /* 1970 */ 1161, 961, 1161, 530, 1161, 1161, 1161, 103, 103, 1161,
- /* 1980 */ 1161, 1161, 1161, 1161, 104, 1161, 416, 537, 536, 1161,
- /* 1990 */ 1161, 951, 268, 1161, 1161, 1161, 416, 366, 366, 365,
- /* 2000 */ 253, 363, 1161, 1161, 798, 1161, 1161, 1161, 524, 1161,
+ /* 1910 */ 1161, 961, 1161, 529, 1161, 1161, 1161, 103, 103, 880,
+ /* 1920 */ 1161, 1161, 1161, 1161, 104, 1161, 415, 536, 535, 1161,
+ /* 1930 */ 1161, 951, 1161, 1161, 1161, 1161, 415, 1161, 1161, 1161,
+ /* 1940 */ 384, 1161, 1161, 1161, 1161, 288, 525, 1161, 523, 1161,
+ /* 1950 */ 1161, 1161, 1161, 1161, 1161, 1161, 97, 526, 1161, 4,
+ /* 1960 */ 1161, 1161, 951, 951, 953, 954, 27, 1161, 422, 1161,
+ /* 1970 */ 1161, 961, 1161, 529, 1161, 1161, 1161, 103, 103, 1161,
+ /* 1980 */ 1161, 1161, 1161, 1161, 104, 1161, 415, 536, 535, 1161,
+ /* 1990 */ 1161, 951, 268, 1161, 1161, 1161, 415, 366, 366, 365,
+ /* 2000 */ 253, 363, 1161, 1161, 797, 1161, 1161, 1161, 523, 1161,
/* 2010 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 213, 1161, 294,
/* 2020 */ 1161, 1161, 951, 951, 953, 954, 27, 293, 1161, 1161,
/* 2030 */ 1161, 961, 1161, 1161, 1161, 1161, 1161, 103, 103, 1161,
- /* 2040 */ 1161, 1161, 1161, 1161, 104, 1161, 416, 537, 536, 1161,
+ /* 2040 */ 1161, 1161, 1161, 1161, 104, 1161, 415, 536, 535, 1161,
/* 2050 */ 1161, 951, 1161, 1161, 1161, 1161, 1161, 215, 1161, 1161,
/* 2060 */ 1161, 1161, 1161, 1161, 1161, 152, 1161, 1161, 154, 1161,
/* 2070 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 214,
/* 2080 */ 1161, 1161, 951, 951, 953, 954, 27, 1161, 1161, 1161,
/* 2090 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
/* 2100 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
- /* 2110 */ 1161, 1161, 1161, 385, 1161, 1161, 1161, 1161, 288, 526,
+ /* 2110 */ 1161, 1161, 1161, 384, 1161, 1161, 1161, 1161, 288, 525,
/* 2120 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
/* 2130 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
- /* 2140 */ 1161, 423,
+ /* 2140 */ 1161, 422,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 184, 184, 259, 260, 261, 259, 260, 261, 176, 177,
- /* 10 */ 178, 179, 180, 181, 184, 208, 212, 213, 186, 19,
- /* 20 */ 188, 205, 206, 280, 205, 221, 22, 195, 24, 195,
- /* 30 */ 208, 31, 195, 205, 29, 205, 206, 255, 33, 39,
- /* 40 */ 200, 201, 202, 43, 44, 45, 46, 47, 48, 49,
- /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 205, 227,
- /* 60 */ 228, 227, 228, 59, 227, 228, 259, 260, 261, 252,
- /* 70 */ 65, 241, 240, 184, 240, 223, 224, 240, 244, 245,
- /* 80 */ 250, 259, 260, 261, 19, 253, 54, 55, 56, 57,
- /* 90 */ 58, 184, 255, 184, 205, 206, 96, 97, 98, 99,
- /* 100 */ 100, 101, 102, 103, 104, 105, 106, 46, 47, 48,
- /* 110 */ 49, 46, 296, 297, 110, 283, 19, 96, 97, 98,
- /* 120 */ 99, 100, 101, 102, 103, 104, 105, 106, 96, 97,
+ /* 0 */ 260, 261, 262, 260, 261, 262, 176, 177, 178, 179,
+ /* 10 */ 180, 181, 184, 206, 209, 184, 186, 206, 188, 19,
+ /* 20 */ 179, 281, 181, 213, 214, 195, 206, 186, 195, 188,
+ /* 30 */ 195, 31, 222, 184, 206, 207, 195, 206, 207, 39,
+ /* 40 */ 24, 209, 184, 43, 44, 45, 46, 47, 48, 49,
+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 228, 229,
+ /* 60 */ 184, 228, 229, 228, 229, 260, 261, 262, 192, 228,
+ /* 70 */ 229, 241, 196, 242, 241, 59, 241, 205, 245, 246,
+ /* 80 */ 184, 22, 241, 24, 254, 213, 54, 55, 56, 57,
+ /* 90 */ 58, 256, 260, 261, 262, 254, 96, 97, 98, 99,
+ /* 100 */ 100, 101, 102, 103, 104, 105, 106, 100, 101, 102,
+ /* 110 */ 103, 104, 105, 106, 284, 203, 19, 221, 59, 102,
+ /* 120 */ 103, 104, 105, 106, 59, 284, 110, 269, 96, 97,
/* 130 */ 98, 99, 100, 101, 102, 103, 104, 105, 106, 94,
/* 140 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 150 */ 53, 54, 55, 56, 57, 110, 106, 73, 251, 114,
- /* 160 */ 73, 178, 179, 180, 181, 59, 184, 292, 81, 186,
- /* 170 */ 295, 188, 218, 108, 19, 114, 184, 11, 195, 184,
- /* 180 */ 83, 184, 85, 54, 55, 56, 57, 205, 206, 124,
+ /* 150 */ 53, 54, 55, 56, 57, 110, 184, 106, 73, 114,
+ /* 160 */ 178, 179, 180, 181, 219, 184, 81, 22, 186, 110,
+ /* 170 */ 188, 121, 122, 195, 109, 110, 111, 195, 206, 207,
+ /* 180 */ 83, 184, 85, 54, 55, 56, 57, 206, 207, 277,
/* 190 */ 145, 146, 147, 96, 97, 98, 99, 100, 101, 102,
- /* 200 */ 103, 104, 105, 106, 120, 121, 122, 120, 102, 81,
- /* 210 */ 227, 228, 220, 19, 16, 109, 110, 111, 131, 132,
- /* 220 */ 26, 184, 184, 240, 229, 96, 97, 98, 99, 100,
- /* 230 */ 101, 102, 103, 104, 105, 106, 253, 43, 44, 45,
+ /* 200 */ 103, 104, 105, 106, 59, 120, 228, 229, 143, 184,
+ /* 210 */ 228, 229, 184, 19, 242, 203, 131, 132, 221, 241,
+ /* 220 */ 26, 184, 184, 241, 196, 96, 97, 98, 99, 100,
+ /* 230 */ 101, 102, 103, 104, 105, 106, 254, 43, 44, 45,
/* 240 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 250 */ 56, 57, 100, 101, 102, 103, 104, 105, 106, 131,
- /* 260 */ 132, 106, 127, 69, 129, 130, 283, 112, 113, 114,
- /* 270 */ 115, 116, 117, 118, 81, 77, 76, 79, 296, 124,
- /* 280 */ 298, 203, 184, 19, 84, 59, 86, 121, 122, 89,
+ /* 250 */ 56, 57, 184, 184, 109, 110, 111, 105, 106, 184,
+ /* 260 */ 200, 201, 202, 69, 184, 227, 284, 96, 97, 98,
+ /* 270 */ 99, 100, 101, 102, 103, 104, 105, 106, 297, 298,
+ /* 280 */ 255, 206, 207, 19, 272, 59, 206, 207, 184, 277,
/* 290 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- /* 300 */ 106, 184, 35, 205, 206, 22, 113, 43, 44, 45,
+ /* 300 */ 106, 184, 259, 19, 184, 100, 101, 43, 44, 45,
/* 310 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 320 */ 56, 57, 205, 206, 131, 132, 100, 101, 291, 292,
- /* 330 */ 114, 67, 295, 66, 108, 109, 110, 111, 138, 113,
- /* 340 */ 124, 74, 59, 179, 184, 181, 184, 121, 22, 271,
- /* 350 */ 186, 19, 188, 184, 276, 59, 24, 184, 241, 195,
+ /* 320 */ 56, 57, 242, 206, 207, 184, 100, 101, 138, 292,
+ /* 330 */ 293, 67, 76, 296, 108, 109, 110, 111, 295, 113,
+ /* 340 */ 84, 59, 86, 22, 26, 89, 156, 121, 224, 225,
+ /* 350 */ 145, 19, 147, 59, 72, 256, 24, 184, 290, 291,
/* 360 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- /* 370 */ 106, 145, 59, 147, 184, 43, 44, 45, 46, 47,
+ /* 370 */ 106, 145, 297, 147, 299, 43, 44, 45, 46, 47,
/* 380 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 390 */ 123, 227, 228, 110, 296, 297, 22, 23, 184, 102,
- /* 400 */ 103, 104, 105, 106, 240, 109, 110, 111, 112, 195,
- /* 410 */ 204, 115, 116, 117, 22, 184, 226, 253, 212, 205,
- /* 420 */ 206, 125, 109, 110, 111, 22, 100, 101, 96, 97,
- /* 430 */ 98, 99, 100, 101, 102, 103, 104, 105, 106, 184,
- /* 440 */ 59, 227, 228, 121, 122, 59, 277, 283, 19, 289,
- /* 450 */ 290, 59, 23, 76, 240, 241, 143, 76, 72, 189,
- /* 460 */ 205, 206, 59, 86, 250, 84, 89, 86, 203, 95,
- /* 470 */ 89, 281, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 480 */ 51, 52, 53, 54, 55, 56, 57, 227, 228, 184,
- /* 490 */ 109, 110, 111, 12, 184, 109, 110, 111, 184, 184,
- /* 500 */ 240, 109, 110, 111, 184, 195, 214, 59, 27, 184,
- /* 510 */ 205, 206, 109, 110, 111, 205, 206, 184, 263, 138,
- /* 520 */ 205, 206, 184, 42, 22, 96, 97, 98, 99, 100,
- /* 530 */ 101, 102, 103, 104, 105, 106, 266, 227, 228, 59,
- /* 540 */ 270, 276, 94, 66, 63, 19, 241, 22, 26, 23,
- /* 550 */ 240, 241, 72, 59, 73, 250, 241, 109, 110, 82,
- /* 560 */ 22, 59, 114, 223, 224, 250, 252, 59, 91, 43,
+ /* 390 */ 106, 109, 110, 111, 138, 184, 112, 113, 114, 115,
+ /* 400 */ 116, 117, 118, 109, 110, 111, 112, 59, 124, 115,
+ /* 410 */ 116, 117, 292, 293, 297, 298, 296, 206, 207, 125,
+ /* 420 */ 72, 100, 101, 184, 46, 47, 48, 49, 96, 97,
+ /* 430 */ 98, 99, 100, 101, 102, 103, 104, 105, 106, 59,
+ /* 440 */ 200, 201, 202, 184, 59, 206, 207, 46, 19, 131,
+ /* 450 */ 132, 278, 23, 242, 184, 184, 76, 109, 110, 111,
+ /* 460 */ 224, 225, 251, 81, 84, 184, 86, 22, 23, 89,
+ /* 470 */ 184, 26, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 480 */ 51, 52, 53, 54, 55, 56, 57, 102, 184, 109,
+ /* 490 */ 110, 111, 114, 184, 109, 110, 111, 184, 227, 184,
+ /* 500 */ 230, 184, 22, 264, 195, 59, 22, 184, 195, 108,
+ /* 510 */ 206, 207, 59, 131, 132, 206, 207, 184, 138, 206,
+ /* 520 */ 207, 206, 207, 206, 207, 96, 97, 98, 99, 100,
+ /* 530 */ 101, 102, 103, 104, 105, 106, 255, 228, 229, 59,
+ /* 540 */ 95, 228, 229, 59, 184, 19, 242, 94, 184, 23,
+ /* 550 */ 241, 242, 184, 282, 241, 242, 110, 242, 184, 242,
+ /* 560 */ 251, 59, 109, 110, 196, 184, 251, 114, 251, 43,
/* 570 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 580 */ 54, 55, 56, 57, 59, 184, 26, 59, 268, 109,
- /* 590 */ 110, 111, 184, 145, 146, 147, 112, 59, 203, 115,
- /* 600 */ 116, 117, 277, 109, 110, 111, 205, 206, 195, 125,
- /* 610 */ 277, 109, 110, 111, 100, 101, 139, 109, 110, 111,
- /* 620 */ 219, 184, 96, 97, 98, 99, 100, 101, 102, 103,
- /* 630 */ 104, 105, 106, 111, 109, 110, 111, 109, 110, 111,
- /* 640 */ 227, 228, 19, 184, 136, 184, 23, 109, 110, 111,
- /* 650 */ 200, 201, 202, 240, 259, 260, 261, 195, 136, 145,
- /* 660 */ 184, 147, 184, 184, 136, 214, 43, 44, 45, 46,
+ /* 580 */ 54, 55, 56, 57, 259, 217, 12, 219, 255, 109,
+ /* 590 */ 110, 111, 203, 109, 110, 111, 184, 22, 145, 146,
+ /* 600 */ 147, 27, 112, 22, 230, 115, 116, 117, 227, 19,
+ /* 610 */ 59, 109, 110, 111, 291, 125, 42, 35, 206, 207,
+ /* 620 */ 295, 184, 96, 97, 98, 99, 100, 101, 102, 103,
+ /* 630 */ 104, 105, 106, 26, 59, 233, 46, 63, 136, 184,
+ /* 640 */ 59, 184, 19, 206, 207, 243, 23, 73, 66, 260,
+ /* 650 */ 261, 262, 59, 184, 242, 195, 74, 220, 184, 184,
+ /* 660 */ 109, 110, 111, 206, 207, 184, 43, 44, 45, 46,
/* 670 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 680 */ 57, 205, 206, 205, 206, 227, 228, 184, 229, 227,
- /* 690 */ 228, 131, 132, 184, 59, 219, 184, 219, 240, 291,
- /* 700 */ 292, 184, 240, 295, 105, 106, 22, 23, 205, 206,
- /* 710 */ 26, 184, 251, 184, 205, 206, 184, 205, 206, 96,
+ /* 680 */ 57, 206, 207, 76, 109, 110, 111, 136, 228, 229,
+ /* 690 */ 109, 110, 111, 86, 184, 220, 89, 21, 108, 230,
+ /* 700 */ 184, 241, 109, 110, 111, 123, 184, 127, 184, 129,
+ /* 710 */ 130, 184, 195, 184, 124, 184, 198, 199, 184, 96,
/* 720 */ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
- /* 730 */ 251, 219, 205, 206, 205, 206, 184, 205, 206, 19,
- /* 740 */ 184, 16, 184, 23, 241, 110, 219, 21, 219, 184,
- /* 750 */ 241, 219, 286, 287, 195, 184, 195, 205, 206, 201,
- /* 760 */ 202, 205, 206, 43, 44, 45, 46, 47, 48, 49,
- /* 770 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 95,
- /* 780 */ 22, 23, 184, 26, 26, 220, 227, 228, 227, 228,
- /* 790 */ 196, 184, 23, 241, 26, 26, 195, 241, 184, 240,
- /* 800 */ 12, 240, 77, 26, 79, 195, 80, 290, 201, 202,
- /* 810 */ 216, 184, 218, 195, 184, 27, 96, 97, 98, 99,
- /* 820 */ 100, 101, 102, 103, 104, 105, 106, 269, 227, 228,
- /* 830 */ 42, 184, 205, 206, 184, 184, 19, 227, 228, 192,
- /* 840 */ 23, 240, 116, 196, 76, 227, 228, 120, 121, 122,
- /* 850 */ 240, 63, 254, 95, 86, 205, 206, 89, 240, 184,
+ /* 730 */ 206, 207, 11, 206, 207, 206, 207, 206, 207, 19,
+ /* 740 */ 206, 207, 184, 23, 220, 228, 229, 220, 81, 220,
+ /* 750 */ 195, 220, 287, 288, 220, 195, 80, 195, 241, 201,
+ /* 760 */ 202, 184, 73, 43, 44, 45, 46, 47, 48, 49,
+ /* 770 */ 50, 51, 52, 53, 54, 55, 56, 57, 201, 202,
+ /* 780 */ 113, 195, 184, 228, 229, 120, 121, 122, 228, 229,
+ /* 790 */ 228, 229, 116, 16, 23, 184, 241, 26, 131, 132,
+ /* 800 */ 278, 241, 19, 241, 22, 23, 184, 189, 26, 120,
+ /* 810 */ 121, 122, 184, 26, 228, 229, 96, 97, 98, 99,
+ /* 820 */ 100, 101, 102, 103, 104, 105, 106, 241, 270, 153,
+ /* 830 */ 66, 228, 229, 229, 206, 207, 19, 184, 228, 229,
+ /* 840 */ 23, 16, 121, 122, 241, 241, 82, 270, 29, 227,
+ /* 850 */ 252, 241, 33, 19, 77, 91, 79, 184, 22, 23,
/* 860 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 870 */ 53, 54, 55, 56, 57, 184, 269, 184, 153, 153,
- /* 880 */ 111, 184, 7, 8, 9, 184, 138, 184, 184, 196,
- /* 890 */ 184, 120, 121, 122, 184, 138, 205, 206, 184, 102,
- /* 900 */ 184, 184, 205, 206, 156, 136, 205, 206, 205, 206,
- /* 910 */ 198, 199, 135, 96, 97, 98, 99, 100, 101, 102,
- /* 920 */ 103, 104, 105, 106, 184, 128, 184, 184, 184, 254,
- /* 930 */ 133, 184, 237, 19, 239, 229, 226, 23, 292, 184,
- /* 940 */ 226, 295, 226, 226, 184, 205, 206, 205, 206, 205,
- /* 950 */ 206, 184, 292, 19, 184, 295, 252, 43, 44, 45,
+ /* 870 */ 53, 54, 55, 56, 57, 12, 184, 95, 184, 206,
+ /* 880 */ 207, 76, 111, 184, 65, 267, 184, 184, 184, 271,
+ /* 890 */ 27, 86, 109, 184, 89, 120, 121, 122, 206, 207,
+ /* 900 */ 206, 207, 77, 139, 79, 42, 184, 136, 206, 207,
+ /* 910 */ 206, 207, 184, 96, 97, 98, 99, 100, 101, 102,
+ /* 920 */ 103, 104, 105, 106, 184, 138, 63, 184, 206, 207,
+ /* 930 */ 153, 95, 184, 19, 206, 207, 227, 23, 7, 8,
+ /* 940 */ 9, 293, 293, 109, 296, 296, 206, 207, 215, 206,
+ /* 950 */ 207, 184, 253, 19, 206, 207, 253, 43, 44, 45,
/* 960 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 970 */ 56, 57, 205, 206, 184, 205, 206, 43, 44, 45,
+ /* 970 */ 56, 57, 184, 206, 207, 184, 184, 43, 44, 45,
/* 980 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 990 */ 56, 57, 157, 158, 26, 205, 206, 254, 26, 252,
- /* 1000 */ 184, 15, 184, 184, 184, 292, 184, 252, 295, 24,
+ /* 990 */ 56, 57, 184, 22, 23, 184, 59, 206, 207, 184,
+ /* 1000 */ 184, 238, 184, 240, 184, 22, 184, 184, 157, 158,
/* 1010 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- /* 1020 */ 106, 205, 206, 205, 206, 205, 206, 205, 206, 184,
+ /* 1020 */ 106, 206, 207, 184, 206, 207, 206, 207, 206, 207,
/* 1030 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- /* 1040 */ 106, 184, 184, 184, 59, 184, 60, 184, 229, 184,
- /* 1050 */ 205, 206, 184, 258, 184, 19, 184, 19, 184, 246,
- /* 1060 */ 184, 258, 205, 206, 205, 206, 205, 206, 205, 206,
- /* 1070 */ 205, 206, 184, 205, 206, 205, 206, 205, 206, 205,
- /* 1080 */ 206, 205, 206, 292, 226, 151, 295, 184, 228, 294,
- /* 1090 */ 184, 119, 184, 205, 206, 110, 150, 294, 152, 184,
- /* 1100 */ 240, 184, 22, 23, 23, 19, 184, 26, 205, 206,
- /* 1110 */ 142, 205, 206, 205, 206, 184, 198, 199, 131, 132,
- /* 1120 */ 205, 206, 205, 206, 22, 19, 24, 205, 206, 43,
+ /* 1040 */ 106, 184, 59, 227, 252, 184, 293, 110, 184, 296,
+ /* 1050 */ 184, 184, 184, 230, 184, 184, 184, 15, 184, 184,
+ /* 1060 */ 184, 253, 184, 206, 207, 184, 95, 206, 207, 102,
+ /* 1070 */ 206, 207, 206, 207, 206, 207, 206, 207, 206, 207,
+ /* 1080 */ 206, 207, 206, 207, 184, 151, 184, 206, 207, 278,
+ /* 1090 */ 184, 252, 184, 110, 184, 128, 184, 198, 199, 184,
+ /* 1100 */ 133, 184, 60, 26, 184, 19, 206, 207, 206, 207,
+ /* 1110 */ 131, 132, 206, 207, 206, 207, 206, 207, 206, 207,
+ /* 1120 */ 253, 206, 207, 206, 207, 19, 206, 207, 253, 43,
/* 1130 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1140 */ 54, 55, 56, 57, 184, 109, 184, 109, 184, 43,
+ /* 1140 */ 54, 55, 56, 57, 184, 26, 184, 26, 184, 43,
/* 1150 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1160 */ 54, 55, 56, 57, 46, 205, 206, 205, 206, 205,
- /* 1170 */ 206, 232, 184, 184, 184, 95, 184, 284, 285, 244,
- /* 1180 */ 245, 242, 96, 97, 98, 99, 100, 101, 102, 103,
- /* 1190 */ 104, 105, 106, 205, 206, 205, 206, 205, 206, 184,
- /* 1200 */ 22, 184, 96, 97, 98, 99, 100, 101, 102, 103,
- /* 1210 */ 104, 105, 106, 184, 24, 23, 184, 184, 26, 184,
- /* 1220 */ 205, 206, 205, 206, 184, 31, 108, 128, 22, 122,
- /* 1230 */ 184, 53, 133, 39, 205, 206, 22, 151, 205, 206,
- /* 1240 */ 205, 206, 113, 114, 23, 205, 206, 26, 59, 23,
- /* 1250 */ 23, 144, 26, 26, 184, 23, 23, 19, 26, 26,
- /* 1260 */ 7, 8, 24, 23, 214, 23, 26, 61, 26, 59,
- /* 1270 */ 23, 23, 23, 26, 26, 26, 145, 19, 147, 59,
- /* 1280 */ 184, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 1290 */ 52, 53, 54, 55, 56, 57, 145, 23, 147, 110,
+ /* 1160 */ 54, 55, 56, 57, 285, 286, 206, 207, 206, 207,
+ /* 1170 */ 206, 207, 184, 31, 184, 293, 184, 293, 296, 184,
+ /* 1180 */ 296, 39, 96, 97, 98, 99, 100, 101, 102, 103,
+ /* 1190 */ 104, 105, 106, 184, 206, 207, 206, 207, 206, 207,
+ /* 1200 */ 184, 22, 96, 97, 98, 99, 100, 101, 102, 103,
+ /* 1210 */ 104, 105, 106, 184, 245, 246, 184, 26, 23, 142,
+ /* 1220 */ 128, 26, 206, 207, 150, 133, 152, 22, 22, 24,
+ /* 1230 */ 111, 23, 53, 184, 26, 206, 207, 151, 206, 207,
+ /* 1240 */ 119, 24, 122, 23, 23, 23, 26, 26, 26, 23,
+ /* 1250 */ 23, 23, 26, 26, 26, 136, 23, 19, 22, 26,
+ /* 1260 */ 113, 114, 24, 114, 144, 184, 59, 61, 7, 8,
+ /* 1270 */ 59, 23, 23, 124, 26, 26, 23, 19, 145, 26,
+ /* 1280 */ 147, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 1290 */ 52, 53, 54, 55, 56, 57, 145, 23, 147, 184,
/* 1300 */ 26, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 1310 */ 52, 53, 54, 55, 56, 57, 23, 184, 184, 26,
- /* 1320 */ 110, 184, 184, 184, 134, 184, 184, 184, 184, 184,
- /* 1330 */ 110, 184, 184, 184, 96, 97, 98, 99, 100, 101,
- /* 1340 */ 102, 103, 104, 105, 106, 184, 184, 184, 134, 300,
- /* 1350 */ 184, 243, 184, 184, 96, 97, 98, 99, 100, 101,
+ /* 1310 */ 52, 53, 54, 55, 56, 57, 23, 110, 184, 26,
+ /* 1320 */ 184, 110, 184, 184, 184, 215, 135, 215, 184, 184,
+ /* 1330 */ 184, 247, 184, 244, 96, 97, 98, 99, 100, 101,
+ /* 1340 */ 102, 103, 104, 105, 106, 184, 184, 184, 301, 184,
+ /* 1350 */ 184, 134, 225, 184, 96, 97, 98, 99, 100, 101,
/* 1360 */ 102, 103, 104, 105, 106, 184, 184, 184, 184, 184,
- /* 1370 */ 224, 184, 282, 273, 19, 272, 203, 182, 243, 243,
- /* 1380 */ 230, 209, 278, 243, 231, 208, 265, 278, 234, 234,
- /* 1390 */ 234, 217, 213, 60, 19, 243, 208, 237, 233, 44,
+ /* 1370 */ 134, 184, 274, 273, 19, 244, 244, 204, 182, 244,
+ /* 1380 */ 283, 231, 279, 279, 232, 244, 210, 209, 235, 235,
+ /* 1390 */ 235, 248, 218, 234, 19, 209, 238, 209, 238, 44,
/* 1400 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- /* 1410 */ 55, 56, 57, 208, 247, 187, 134, 247, 247, 38,
+ /* 1410 */ 55, 56, 57, 214, 60, 248, 248, 187, 134, 38,
/* 1420 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- /* 1430 */ 55, 56, 57, 237, 231, 191, 191, 279, 279, 282,
- /* 1440 */ 143, 191, 108, 268, 22, 19, 20, 256, 22, 43,
- /* 1450 */ 257, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- /* 1460 */ 105, 106, 36, 222, 142, 234, 18, 191, 225, 18,
- /* 1470 */ 190, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- /* 1480 */ 105, 106, 225, 191, 225, 59, 225, 257, 234, 234,
- /* 1490 */ 256, 222, 222, 190, 234, 150, 62, 71, 275, 274,
- /* 1500 */ 191, 19, 20, 190, 22, 22, 210, 81, 191, 190,
- /* 1510 */ 210, 191, 108, 190, 207, 207, 64, 207, 36, 215,
- /* 1520 */ 94, 210, 207, 209, 119, 207, 100, 101, 207, 106,
- /* 1530 */ 48, 215, 207, 107, 210, 109, 110, 111, 267, 267,
- /* 1540 */ 114, 59, 210, 249, 137, 108, 248, 191, 249, 248,
- /* 1550 */ 88, 249, 141, 71, 248, 299, 138, 131, 132, 22,
- /* 1560 */ 191, 249, 299, 237, 82, 238, 150, 262, 140, 87,
- /* 1570 */ 139, 145, 146, 147, 148, 149, 94, 248, 238, 236,
- /* 1580 */ 25, 235, 100, 101, 234, 194, 26, 193, 13, 107,
- /* 1590 */ 6, 109, 110, 111, 264, 185, 114, 185, 183, 197,
- /* 1600 */ 183, 203, 183, 203, 203, 197, 203, 211, 211, 4,
- /* 1610 */ 197, 3, 203, 22, 155, 15, 288, 203, 93, 288,
- /* 1620 */ 285, 23, 16, 203, 203, 23, 132, 145, 146, 147,
- /* 1630 */ 148, 149, 0, 1, 2, 143, 123, 5, 24, 135,
- /* 1640 */ 20, 16, 10, 11, 12, 13, 14, 137, 1, 17,
- /* 1650 */ 135, 144, 19, 20, 123, 22, 61, 143, 37, 123,
- /* 1660 */ 53, 109, 30, 53, 32, 53, 53, 134, 34, 36,
- /* 1670 */ 1, 5, 40, 22, 108, 153, 26, 68, 75, 68,
- /* 1680 */ 41, 134, 108, 24, 20, 124, 19, 118, 23, 67,
- /* 1690 */ 22, 67, 59, 22, 22, 22, 22, 67, 28, 37,
- /* 1700 */ 23, 142, 70, 22, 71, 23, 157, 23, 23, 26,
- /* 1710 */ 78, 23, 22, 81, 23, 82, 24, 22, 24, 134,
- /* 1720 */ 87, 23, 19, 20, 92, 22, 109, 94, 23, 22,
- /* 1730 */ 34, 34, 136, 100, 101, 26, 34, 85, 34, 36,
- /* 1740 */ 107, 83, 109, 110, 111, 34, 90, 114, 34, 23,
- /* 1750 */ 75, 75, 44, 22, 24, 26, 34, 23, 126, 26,
- /* 1760 */ 23, 23, 59, 131, 132, 23, 23, 26, 23, 22,
- /* 1770 */ 11, 22, 22, 22, 71, 23, 23, 22, 145, 146,
- /* 1780 */ 147, 148, 149, 26, 23, 82, 154, 134, 128, 134,
- /* 1790 */ 87, 134, 15, 1, 301, 134, 301, 94, 301, 301,
- /* 1800 */ 301, 301, 301, 100, 101, 301, 301, 301, 301, 301,
- /* 1810 */ 107, 301, 109, 110, 111, 1, 2, 114, 301, 5,
- /* 1820 */ 301, 301, 301, 301, 10, 11, 12, 13, 14, 301,
- /* 1830 */ 301, 17, 301, 301, 301, 301, 19, 20, 301, 22,
- /* 1840 */ 301, 301, 301, 301, 30, 301, 32, 301, 145, 146,
- /* 1850 */ 147, 148, 149, 36, 40, 301, 301, 301, 301, 301,
- /* 1860 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 1870 */ 301, 301, 301, 301, 301, 301, 59, 301, 301, 301,
- /* 1880 */ 301, 301, 301, 301, 70, 301, 301, 301, 71, 301,
- /* 1890 */ 301, 301, 78, 301, 301, 81, 19, 20, 301, 22,
- /* 1900 */ 301, 301, 301, 301, 301, 301, 92, 301, 301, 301,
- /* 1910 */ 301, 94, 301, 36, 301, 301, 301, 100, 101, 102,
- /* 1920 */ 301, 301, 301, 301, 107, 301, 109, 110, 111, 301,
- /* 1930 */ 301, 114, 301, 301, 301, 301, 59, 301, 301, 301,
- /* 1940 */ 126, 301, 301, 301, 301, 131, 132, 301, 71, 301,
- /* 1950 */ 301, 301, 301, 301, 301, 301, 19, 20, 301, 22,
- /* 1960 */ 301, 301, 145, 146, 147, 148, 149, 301, 154, 301,
- /* 1970 */ 301, 94, 301, 36, 301, 301, 301, 100, 101, 301,
- /* 1980 */ 301, 301, 301, 301, 107, 301, 109, 110, 111, 301,
- /* 1990 */ 301, 114, 5, 301, 301, 301, 59, 10, 11, 12,
- /* 2000 */ 13, 14, 301, 301, 17, 301, 301, 301, 71, 301,
- /* 2010 */ 301, 301, 301, 301, 301, 301, 301, 30, 301, 32,
- /* 2020 */ 301, 301, 145, 146, 147, 148, 149, 40, 301, 301,
- /* 2030 */ 301, 94, 301, 301, 301, 301, 301, 100, 101, 301,
- /* 2040 */ 301, 301, 301, 301, 107, 301, 109, 110, 111, 301,
- /* 2050 */ 301, 114, 301, 301, 301, 301, 301, 70, 301, 301,
- /* 2060 */ 301, 301, 301, 301, 301, 78, 301, 301, 81, 301,
- /* 2070 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 92,
- /* 2080 */ 301, 301, 145, 146, 147, 148, 149, 301, 301, 301,
- /* 2090 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 2100 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 2110 */ 301, 301, 301, 126, 301, 301, 301, 301, 131, 132,
- /* 2120 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 2130 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 2140 */ 301, 154, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 2150 */ 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
- /* 2160 */ 301, 301, 301, 301, 301, 301, 301, 301, 301,
+ /* 1430 */ 55, 56, 57, 232, 191, 191, 266, 280, 191, 283,
+ /* 1440 */ 143, 269, 108, 22, 280, 19, 20, 258, 22, 257,
+ /* 1450 */ 43, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ /* 1460 */ 105, 106, 36, 223, 142, 18, 235, 226, 226, 191,
+ /* 1470 */ 18, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ /* 1480 */ 105, 106, 226, 226, 190, 59, 235, 235, 223, 223,
+ /* 1490 */ 258, 257, 191, 190, 235, 150, 62, 71, 191, 276,
+ /* 1500 */ 275, 19, 20, 190, 22, 22, 211, 81, 191, 190,
+ /* 1510 */ 211, 191, 108, 190, 208, 64, 208, 208, 36, 119,
+ /* 1520 */ 94, 216, 211, 208, 210, 106, 100, 101, 216, 208,
+ /* 1530 */ 48, 268, 208, 107, 208, 109, 110, 111, 211, 268,
+ /* 1540 */ 114, 59, 211, 137, 108, 88, 250, 249, 191, 141,
+ /* 1550 */ 250, 249, 138, 71, 250, 300, 22, 131, 132, 249,
+ /* 1560 */ 300, 191, 150, 238, 82, 140, 250, 249, 239, 87,
+ /* 1570 */ 139, 145, 146, 147, 148, 149, 94, 239, 237, 236,
+ /* 1580 */ 25, 235, 100, 101, 194, 26, 193, 13, 185, 107,
+ /* 1590 */ 185, 109, 110, 111, 6, 263, 114, 203, 265, 183,
+ /* 1600 */ 183, 183, 203, 212, 203, 203, 197, 197, 212, 4,
+ /* 1610 */ 3, 22, 197, 155, 15, 204, 203, 289, 93, 289,
+ /* 1620 */ 16, 286, 132, 23, 204, 23, 123, 145, 146, 147,
+ /* 1630 */ 148, 149, 0, 1, 2, 143, 24, 5, 20, 135,
+ /* 1640 */ 16, 1, 10, 11, 12, 13, 14, 137, 135, 17,
+ /* 1650 */ 144, 123, 19, 20, 61, 22, 37, 143, 123, 53,
+ /* 1660 */ 109, 53, 30, 53, 32, 34, 53, 134, 1, 36,
+ /* 1670 */ 5, 22, 40, 108, 153, 41, 26, 68, 75, 68,
+ /* 1680 */ 134, 108, 24, 20, 124, 19, 118, 67, 67, 28,
+ /* 1690 */ 22, 22, 59, 22, 67, 23, 22, 22, 142, 37,
+ /* 1700 */ 23, 22, 70, 23, 71, 157, 23, 23, 26, 23,
+ /* 1710 */ 78, 22, 24, 81, 23, 82, 22, 24, 134, 23,
+ /* 1720 */ 87, 23, 19, 20, 92, 22, 109, 94, 22, 34,
+ /* 1730 */ 136, 26, 85, 100, 101, 34, 34, 83, 34, 36,
+ /* 1740 */ 107, 34, 109, 110, 111, 75, 90, 114, 75, 34,
+ /* 1750 */ 23, 22, 44, 34, 24, 23, 22, 26, 126, 26,
+ /* 1760 */ 23, 23, 59, 131, 132, 23, 23, 26, 23, 11,
+ /* 1770 */ 22, 22, 26, 23, 71, 23, 22, 22, 145, 146,
+ /* 1780 */ 147, 148, 149, 128, 23, 82, 154, 134, 15, 1,
+ /* 1790 */ 87, 134, 302, 134, 134, 302, 302, 94, 302, 302,
+ /* 1800 */ 302, 302, 302, 100, 101, 302, 302, 302, 302, 302,
+ /* 1810 */ 107, 302, 109, 110, 111, 1, 2, 114, 302, 5,
+ /* 1820 */ 302, 302, 302, 302, 10, 11, 12, 13, 14, 302,
+ /* 1830 */ 302, 17, 302, 302, 302, 302, 19, 20, 302, 22,
+ /* 1840 */ 302, 302, 302, 302, 30, 302, 32, 302, 145, 146,
+ /* 1850 */ 147, 148, 149, 36, 40, 302, 302, 302, 302, 302,
+ /* 1860 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 1870 */ 302, 302, 302, 302, 302, 302, 59, 302, 302, 302,
+ /* 1880 */ 302, 302, 302, 302, 70, 302, 302, 302, 71, 302,
+ /* 1890 */ 302, 302, 78, 302, 302, 81, 19, 20, 302, 22,
+ /* 1900 */ 302, 302, 302, 302, 302, 302, 92, 302, 302, 302,
+ /* 1910 */ 302, 94, 302, 36, 302, 302, 302, 100, 101, 102,
+ /* 1920 */ 302, 302, 302, 302, 107, 302, 109, 110, 111, 302,
+ /* 1930 */ 302, 114, 302, 302, 302, 302, 59, 302, 302, 302,
+ /* 1940 */ 126, 302, 302, 302, 302, 131, 132, 302, 71, 302,
+ /* 1950 */ 302, 302, 302, 302, 302, 302, 19, 20, 302, 22,
+ /* 1960 */ 302, 302, 145, 146, 147, 148, 149, 302, 154, 302,
+ /* 1970 */ 302, 94, 302, 36, 302, 302, 302, 100, 101, 302,
+ /* 1980 */ 302, 302, 302, 302, 107, 302, 109, 110, 111, 302,
+ /* 1990 */ 302, 114, 5, 302, 302, 302, 59, 10, 11, 12,
+ /* 2000 */ 13, 14, 302, 302, 17, 302, 302, 302, 71, 302,
+ /* 2010 */ 302, 302, 302, 302, 302, 302, 302, 30, 302, 32,
+ /* 2020 */ 302, 302, 145, 146, 147, 148, 149, 40, 302, 302,
+ /* 2030 */ 302, 94, 302, 302, 302, 302, 302, 100, 101, 302,
+ /* 2040 */ 302, 302, 302, 302, 107, 302, 109, 110, 111, 302,
+ /* 2050 */ 302, 114, 302, 302, 302, 302, 302, 70, 302, 302,
+ /* 2060 */ 302, 302, 302, 302, 302, 78, 302, 302, 81, 302,
+ /* 2070 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 92,
+ /* 2080 */ 302, 302, 145, 146, 147, 148, 149, 302, 302, 302,
+ /* 2090 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2100 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2110 */ 302, 302, 302, 126, 302, 302, 302, 302, 131, 132,
+ /* 2120 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2130 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2140 */ 302, 154, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2150 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2160 */ 302, 302, 302, 302, 302, 302, 302, 302, 302,
};
-#define YY_SHIFT_COUNT (540)
+#define YY_SHIFT_COUNT (539)
#define YY_SHIFT_MIN (0)
#define YY_SHIFT_MAX (1987)
static const unsigned short int yy_shift_ofst[] = {
- /* 0 */ 1814, 1632, 1987, 1426, 1426, 128, 1482, 1633, 1703, 1877,
- /* 10 */ 1877, 1877, 87, 0, 0, 264, 1106, 1877, 1877, 1877,
+ /* 0 */ 1814, 1632, 1987, 1426, 1426, 382, 1482, 1633, 1703, 1877,
+ /* 10 */ 1877, 1877, 85, 0, 0, 264, 1106, 1877, 1877, 1877,
/* 20 */ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
- /* 30 */ 226, 226, 381, 381, 296, 193, 128, 128, 128, 128,
- /* 40 */ 128, 128, 97, 194, 332, 429, 526, 623, 720, 817,
+ /* 30 */ 226, 226, 380, 380, 294, 667, 382, 382, 382, 382,
+ /* 40 */ 382, 382, 97, 194, 332, 429, 526, 623, 720, 817,
/* 50 */ 914, 934, 1086, 1238, 1106, 1106, 1106, 1106, 1106, 1106,
/* 60 */ 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106,
/* 70 */ 1106, 1106, 1258, 1106, 1355, 1375, 1375, 1817, 1877, 1877,
@@ -148933,149 +149512,147 @@ static const unsigned short int yy_shift_ofst[] = {
/* 100 */ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
/* 110 */ 1937, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
/* 120 */ 1877, 1877, 1877, 1877, 32, 129, 129, 129, 129, 129,
- /* 130 */ 21, 152, 297, 494, 726, 65, 494, 514, 514, 494,
- /* 140 */ 560, 560, 560, 560, 322, 599, 50, 2142, 2142, 155,
- /* 150 */ 155, 155, 313, 392, 386, 392, 392, 481, 481, 200,
- /* 160 */ 480, 684, 758, 494, 494, 494, 494, 494, 494, 494,
- /* 170 */ 494, 494, 494, 494, 494, 494, 494, 494, 494, 494,
- /* 180 */ 494, 494, 494, 494, 768, 768, 494, 166, 377, 377,
- /* 190 */ 635, 835, 835, 635, 748, 987, 2142, 2142, 2142, 448,
- /* 200 */ 45, 45, 403, 484, 502, 106, 525, 508, 528, 538,
- /* 210 */ 494, 494, 494, 494, 494, 494, 494, 494, 494, 84,
- /* 220 */ 494, 494, 494, 494, 494, 494, 494, 494, 494, 494,
- /* 230 */ 494, 494, 267, 267, 267, 494, 494, 494, 494, 769,
- /* 240 */ 494, 494, 494, 4, 477, 494, 494, 788, 494, 494,
- /* 250 */ 494, 494, 494, 494, 494, 494, 727, 5, 135, 985,
- /* 260 */ 985, 985, 985, 522, 135, 135, 797, 326, 875, 986,
- /* 270 */ 968, 1036, 1036, 1038, 968, 968, 1038, 972, 1081, 1118,
- /* 280 */ 1194, 1194, 1194, 1036, 757, 757, 946, 777, 1099, 1102,
- /* 290 */ 1333, 1282, 1282, 1381, 1381, 1282, 1297, 1334, 1422, 1406,
- /* 300 */ 1322, 1448, 1448, 1448, 1448, 1282, 1451, 1322, 1322, 1334,
- /* 310 */ 1422, 1406, 1406, 1322, 1282, 1451, 1345, 1434, 1282, 1451,
- /* 320 */ 1483, 1282, 1451, 1282, 1451, 1483, 1404, 1404, 1404, 1452,
- /* 330 */ 1483, 1404, 1405, 1404, 1452, 1404, 1404, 1483, 1423, 1423,
- /* 340 */ 1483, 1407, 1437, 1407, 1437, 1407, 1437, 1407, 1437, 1282,
- /* 350 */ 1462, 1462, 1411, 1418, 1537, 1282, 1416, 1411, 1428, 1431,
- /* 360 */ 1322, 1555, 1560, 1575, 1575, 1584, 1584, 1584, 2142, 2142,
+ /* 130 */ 171, 7, 17, 593, 676, 590, 593, 205, 205, 593,
+ /* 140 */ 318, 318, 318, 318, 50, 152, 51, 2142, 2142, 284,
+ /* 150 */ 284, 284, 65, 145, 282, 145, 145, 574, 574, 256,
+ /* 160 */ 348, 445, 782, 593, 593, 593, 593, 593, 593, 593,
+ /* 170 */ 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+ /* 180 */ 593, 593, 593, 593, 607, 607, 593, 721, 805, 805,
+ /* 190 */ 446, 851, 851, 446, 190, 979, 2142, 2142, 2142, 453,
+ /* 200 */ 45, 45, 480, 490, 484, 385, 575, 502, 551, 581,
+ /* 210 */ 593, 593, 593, 593, 593, 593, 593, 593, 593, 689,
+ /* 220 */ 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+ /* 230 */ 593, 593, 582, 582, 582, 593, 593, 593, 593, 771,
+ /* 240 */ 593, 593, 593, 59, 764, 593, 593, 863, 593, 593,
+ /* 250 */ 593, 593, 593, 593, 593, 593, 665, 819, 580, 16,
+ /* 260 */ 16, 16, 16, 1119, 580, 580, 967, 321, 931, 1042,
+ /* 270 */ 1077, 783, 783, 834, 1077, 1077, 834, 1121, 1195, 401,
+ /* 280 */ 1142, 1142, 1142, 783, 787, 787, 1074, 1191, 1092, 1205,
+ /* 290 */ 1354, 1284, 1284, 1381, 1381, 1284, 1297, 1334, 1421, 1407,
+ /* 300 */ 1322, 1447, 1447, 1447, 1447, 1284, 1452, 1322, 1322, 1334,
+ /* 310 */ 1421, 1407, 1407, 1322, 1284, 1452, 1345, 1434, 1284, 1452,
+ /* 320 */ 1483, 1284, 1452, 1284, 1452, 1483, 1404, 1404, 1404, 1451,
+ /* 330 */ 1483, 1404, 1400, 1404, 1451, 1404, 1404, 1483, 1419, 1419,
+ /* 340 */ 1483, 1406, 1436, 1406, 1436, 1406, 1436, 1406, 1436, 1284,
+ /* 350 */ 1457, 1457, 1408, 1414, 1534, 1284, 1412, 1408, 1425, 1431,
+ /* 360 */ 1322, 1555, 1559, 1574, 1574, 1588, 1588, 1588, 2142, 2142,
/* 370 */ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
- /* 380 */ 2142, 2142, 2142, 2142, 61, 725, 374, 1080, 198, 771,
- /* 390 */ 283, 1192, 1178, 1190, 1107, 1221, 1206, 1226, 1227, 1232,
- /* 400 */ 1233, 1240, 1242, 1189, 1129, 1253, 216, 1210, 1247, 1248,
- /* 410 */ 1249, 1131, 1151, 1274, 1293, 1220, 1214, 1605, 1608, 1591,
- /* 420 */ 1459, 1600, 1525, 1606, 1598, 1602, 1494, 1492, 1513, 1614,
- /* 430 */ 1504, 1620, 1510, 1625, 1647, 1515, 1507, 1531, 1595, 1621,
- /* 440 */ 1514, 1607, 1610, 1612, 1613, 1536, 1552, 1634, 1533, 1669,
- /* 450 */ 1666, 1651, 1566, 1522, 1609, 1650, 1611, 1603, 1639, 1547,
- /* 460 */ 1574, 1659, 1664, 1667, 1561, 1569, 1668, 1622, 1671, 1672,
- /* 470 */ 1665, 1673, 1624, 1670, 1674, 1630, 1662, 1677, 1559, 1681,
- /* 480 */ 1682, 1549, 1684, 1685, 1683, 1688, 1690, 1692, 1691, 1695,
- /* 490 */ 1694, 1585, 1698, 1705, 1617, 1696, 1707, 1596, 1709, 1697,
- /* 500 */ 1702, 1704, 1711, 1652, 1675, 1658, 1708, 1676, 1656, 1714,
- /* 510 */ 1726, 1731, 1730, 1729, 1733, 1722, 1734, 1709, 1737, 1738,
- /* 520 */ 1742, 1743, 1741, 1745, 1747, 1759, 1749, 1750, 1752, 1753,
- /* 530 */ 1751, 1755, 1757, 1660, 1653, 1655, 1657, 1661, 1761, 1777,
- /* 540 */ 1792,
+ /* 380 */ 2142, 2142, 2142, 378, 777, 836, 971, 825, 775, 983,
+ /* 390 */ 1208, 1179, 1217, 1120, 1220, 1206, 1221, 1222, 1226, 1227,
+ /* 400 */ 1228, 1233, 937, 1147, 1261, 1149, 1207, 1248, 1249, 1253,
+ /* 410 */ 1133, 1151, 1274, 1293, 1211, 1236, 1605, 1607, 1589, 1458,
+ /* 420 */ 1599, 1525, 1604, 1600, 1602, 1490, 1492, 1503, 1612, 1504,
+ /* 430 */ 1618, 1510, 1624, 1640, 1513, 1506, 1528, 1593, 1619, 1514,
+ /* 440 */ 1606, 1608, 1610, 1613, 1535, 1551, 1631, 1533, 1667, 1665,
+ /* 450 */ 1649, 1565, 1521, 1609, 1650, 1611, 1603, 1634, 1546, 1573,
+ /* 460 */ 1658, 1663, 1666, 1560, 1568, 1668, 1620, 1669, 1671, 1672,
+ /* 470 */ 1674, 1621, 1661, 1675, 1627, 1662, 1677, 1556, 1679, 1680,
+ /* 480 */ 1548, 1683, 1684, 1682, 1686, 1689, 1688, 1691, 1694, 1693,
+ /* 490 */ 1584, 1696, 1698, 1617, 1695, 1706, 1594, 1705, 1701, 1702,
+ /* 500 */ 1704, 1707, 1647, 1670, 1654, 1708, 1673, 1656, 1715, 1727,
+ /* 510 */ 1729, 1730, 1731, 1733, 1719, 1732, 1705, 1737, 1738, 1742,
+ /* 520 */ 1743, 1741, 1745, 1734, 1758, 1748, 1749, 1750, 1752, 1754,
+ /* 530 */ 1755, 1746, 1655, 1653, 1657, 1659, 1660, 1761, 1773, 1788,
};
-#define YY_REDUCE_COUNT (383)
-#define YY_REDUCE_MIN (-257)
-#define YY_REDUCE_MAX (1421)
+#define YY_REDUCE_COUNT (382)
+#define YY_REDUCE_MIN (-260)
+#define YY_REDUCE_MAX (1420)
static const short yy_reduce_ofst[] = {
- /* 0 */ -168, -17, 164, 214, 310, -166, -184, -18, 98, -170,
- /* 10 */ 305, 315, -163, -193, -178, -257, 395, 401, 476, 478,
- /* 20 */ 512, 117, 527, 529, 503, 509, 532, 255, 552, 556,
- /* 30 */ 558, 607, 37, 408, 594, 413, 462, 559, 561, 601,
- /* 40 */ 610, 618, -254, -254, -254, -254, -254, -254, -254, -254,
- /* 50 */ -254, -254, -254, -254, -254, -254, -254, -254, -254, -254,
- /* 60 */ -254, -254, -254, -254, -254, -254, -254, -254, -254, -254,
- /* 70 */ -254, -254, -254, -254, -254, -254, -254, -111, 627, 650,
- /* 80 */ 691, 697, 701, 703, 740, 742, 744, 767, 770, 790,
- /* 90 */ 816, 818, 820, 822, 845, 857, 859, 861, 863, 865,
- /* 100 */ 868, 870, 872, 874, 876, 888, 903, 906, 908, 915,
- /* 110 */ 917, 922, 960, 962, 964, 988, 990, 992, 1015, 1017,
- /* 120 */ 1029, 1033, 1035, 1040, -254, -254, -254, -254, -254, -254,
- /* 130 */ -254, -254, -254, 190, 270, -196, 160, -160, 450, 647,
- /* 140 */ 260, 458, 260, 458, 78, -254, -254, -254, -254, 206,
- /* 150 */ 206, 206, 320, 598, -5, 675, 743, -148, 340, -125,
- /* 160 */ 459, 466, 466, 693, -93, 461, 479, 706, 710, 714,
- /* 170 */ 716, 717, 169, -183, 325, 314, 704, 333, 747, 858,
- /* 180 */ -8, 819, 565, 755, 646, 660, 517, 265, 713, 791,
- /* 190 */ 712, 795, 803, 918, 695, 860, 893, 935, 939, -181,
- /* 200 */ -172, -147, -91, -46, -3, 162, 173, 231, 338, 437,
- /* 210 */ 571, 614, 630, 651, 760, 931, 989, 1032, 1046, -218,
- /* 220 */ 38, 1070, 1096, 1133, 1134, 1137, 1138, 1139, 1141, 1142,
- /* 230 */ 1143, 1144, 292, 451, 1050, 1145, 1147, 1148, 1149, 813,
- /* 240 */ 1161, 1162, 1163, 1108, 1049, 1166, 1168, 1146, 1169, 162,
- /* 250 */ 1181, 1182, 1183, 1184, 1185, 1187, 1100, 1103, 1150, 1135,
- /* 260 */ 1136, 1140, 1152, 813, 1150, 1150, 1153, 1173, 1195, 1090,
- /* 270 */ 1154, 1167, 1170, 1104, 1155, 1156, 1109, 1172, 1174, 1179,
- /* 280 */ 1177, 1188, 1205, 1171, 1160, 1196, 1121, 1165, 1203, 1228,
- /* 290 */ 1157, 1244, 1245, 1158, 1159, 1250, 1175, 1193, 1191, 1241,
- /* 300 */ 1231, 1243, 1257, 1259, 1261, 1276, 1280, 1254, 1255, 1230,
- /* 310 */ 1234, 1269, 1270, 1260, 1292, 1303, 1223, 1225, 1309, 1313,
- /* 320 */ 1296, 1317, 1319, 1320, 1323, 1300, 1307, 1308, 1310, 1304,
- /* 330 */ 1311, 1315, 1314, 1318, 1316, 1321, 1325, 1324, 1271, 1272,
- /* 340 */ 1332, 1294, 1298, 1299, 1301, 1302, 1306, 1312, 1329, 1356,
- /* 350 */ 1256, 1263, 1327, 1326, 1305, 1369, 1330, 1340, 1343, 1346,
- /* 360 */ 1350, 1391, 1394, 1410, 1412, 1415, 1417, 1419, 1328, 1331,
- /* 370 */ 1335, 1402, 1398, 1400, 1401, 1403, 1408, 1396, 1397, 1409,
- /* 380 */ 1414, 1420, 1421, 1413,
+ /* 0 */ -170, -18, -159, 309, 313, -167, -19, 75, 117, 211,
+ /* 10 */ 315, 317, -165, -195, -168, -260, 389, 437, 475, 524,
+ /* 20 */ 527, -169, 529, 531, -28, 80, 534, 239, 304, 412,
+ /* 30 */ 558, 577, 37, 120, 368, -22, 460, 517, 555, 560,
+ /* 40 */ 562, 586, -257, -257, -257, -257, -257, -257, -257, -257,
+ /* 50 */ -257, -257, -257, -257, -257, -257, -257, -257, -257, -257,
+ /* 60 */ -257, -257, -257, -257, -257, -257, -257, -257, -257, -257,
+ /* 70 */ -257, -257, -257, -257, -257, -257, -257, -172, 457, 628,
+ /* 80 */ 673, 692, 694, 702, 704, 722, 728, 740, 743, 748,
+ /* 90 */ 767, 791, 815, 818, 820, 822, 857, 861, 864, 866,
+ /* 100 */ 868, 870, 872, 874, 876, 881, 900, 902, 906, 908,
+ /* 110 */ 910, 912, 915, 917, 920, 960, 962, 964, 988, 990,
+ /* 120 */ 992, 1016, 1029, 1032, -257, -257, -257, -257, -257, -257,
+ /* 130 */ -257, -257, -257, 271, 618, -190, 68, 60, 240, -124,
+ /* 140 */ 603, 610, 603, 610, 12, -257, -257, -257, -257, -128,
+ /* 150 */ -128, -128, -142, 25, 270, 281, 333, 124, 236, 648,
+ /* 160 */ 374, 465, 465, 28, 598, 792, 839, 469, 38, 381,
+ /* 170 */ 622, 709, 173, 699, 522, 703, 808, 811, 867, 816,
+ /* 180 */ -104, 823, -3, 875, 649, 753, 323, -88, 882, 884,
+ /* 190 */ 518, 43, 325, 899, 763, 604, 879, 969, 402, -193,
+ /* 200 */ -189, -180, -151, -55, 69, 104, 141, 259, 286, 360,
+ /* 210 */ 364, 455, 474, 481, 510, 516, 611, 653, 788, 99,
+ /* 220 */ 871, 878, 995, 1009, 1049, 1081, 1115, 1134, 1136, 1138,
+ /* 230 */ 1139, 1140, 733, 1110, 1112, 1144, 1145, 1146, 1148, 1084,
+ /* 240 */ 1161, 1162, 1163, 1089, 1047, 1165, 1166, 1127, 1169, 104,
+ /* 250 */ 1181, 1182, 1183, 1184, 1185, 1187, 1098, 1100, 1150, 1131,
+ /* 260 */ 1132, 1135, 1141, 1084, 1150, 1150, 1152, 1173, 1196, 1097,
+ /* 270 */ 1153, 1143, 1167, 1103, 1154, 1155, 1104, 1176, 1174, 1199,
+ /* 280 */ 1178, 1186, 1188, 1168, 1158, 1160, 1170, 1159, 1201, 1230,
+ /* 290 */ 1156, 1243, 1244, 1157, 1164, 1247, 1172, 1189, 1192, 1240,
+ /* 300 */ 1231, 1241, 1242, 1256, 1257, 1278, 1294, 1251, 1252, 1232,
+ /* 310 */ 1234, 1265, 1266, 1259, 1301, 1303, 1223, 1225, 1307, 1313,
+ /* 320 */ 1295, 1317, 1319, 1320, 1323, 1299, 1306, 1308, 1309, 1305,
+ /* 330 */ 1311, 1315, 1314, 1321, 1312, 1324, 1326, 1327, 1263, 1271,
+ /* 340 */ 1331, 1296, 1298, 1300, 1302, 1304, 1310, 1316, 1318, 1357,
+ /* 350 */ 1255, 1260, 1329, 1325, 1332, 1370, 1333, 1338, 1341, 1343,
+ /* 360 */ 1346, 1390, 1393, 1403, 1405, 1416, 1417, 1418, 1328, 1330,
+ /* 370 */ 1335, 1409, 1394, 1399, 1401, 1402, 1410, 1391, 1396, 1411,
+ /* 380 */ 1420, 1413, 1415,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1536, 1536, 1536, 1376, 1159, 1265, 1159, 1159, 1159, 1376,
- /* 10 */ 1376, 1376, 1159, 1295, 1295, 1429, 1190, 1159, 1159, 1159,
- /* 20 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1375, 1159, 1159,
- /* 30 */ 1159, 1159, 1459, 1459, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 40 */ 1159, 1159, 1159, 1301, 1159, 1159, 1159, 1159, 1159, 1377,
- /* 50 */ 1378, 1159, 1159, 1159, 1428, 1430, 1393, 1311, 1310, 1309,
- /* 60 */ 1308, 1411, 1282, 1306, 1299, 1303, 1371, 1372, 1370, 1374,
- /* 70 */ 1378, 1377, 1159, 1302, 1342, 1356, 1341, 1159, 1159, 1159,
+ /* 0 */ 1537, 1537, 1537, 1377, 1159, 1266, 1159, 1159, 1159, 1377,
+ /* 10 */ 1377, 1377, 1159, 1296, 1296, 1430, 1190, 1159, 1159, 1159,
+ /* 20 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1376, 1159, 1159,
+ /* 30 */ 1159, 1159, 1460, 1460, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 40 */ 1159, 1159, 1159, 1302, 1159, 1159, 1159, 1159, 1159, 1378,
+ /* 50 */ 1379, 1159, 1159, 1159, 1429, 1431, 1394, 1312, 1311, 1310,
+ /* 60 */ 1309, 1412, 1283, 1307, 1300, 1304, 1372, 1373, 1371, 1375,
+ /* 70 */ 1379, 1378, 1159, 1303, 1343, 1357, 1342, 1159, 1159, 1159,
/* 80 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 90 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 100 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 110 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 120 */ 1159, 1159, 1159, 1159, 1350, 1355, 1361, 1354, 1351, 1344,
- /* 130 */ 1343, 1345, 1346, 1159, 1180, 1229, 1159, 1159, 1159, 1159,
- /* 140 */ 1447, 1446, 1159, 1159, 1190, 1347, 1348, 1358, 1357, 1436,
- /* 150 */ 1492, 1491, 1394, 1159, 1159, 1159, 1159, 1159, 1159, 1459,
+ /* 120 */ 1159, 1159, 1159, 1159, 1351, 1356, 1362, 1355, 1352, 1345,
+ /* 130 */ 1344, 1346, 1347, 1159, 1180, 1230, 1159, 1159, 1159, 1159,
+ /* 140 */ 1448, 1447, 1159, 1159, 1190, 1348, 1349, 1359, 1358, 1437,
+ /* 150 */ 1493, 1492, 1395, 1159, 1159, 1159, 1159, 1159, 1159, 1460,
/* 160 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 170 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 180 */ 1159, 1159, 1159, 1159, 1459, 1459, 1159, 1190, 1459, 1459,
- /* 190 */ 1186, 1336, 1335, 1186, 1289, 1159, 1442, 1265, 1256, 1159,
+ /* 180 */ 1159, 1159, 1159, 1159, 1460, 1460, 1159, 1190, 1460, 1460,
+ /* 190 */ 1186, 1337, 1336, 1186, 1290, 1159, 1443, 1266, 1257, 1159,
/* 200 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 210 */ 1159, 1159, 1159, 1433, 1431, 1159, 1159, 1159, 1159, 1159,
+ /* 210 */ 1159, 1159, 1159, 1434, 1432, 1159, 1159, 1159, 1159, 1159,
/* 220 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 230 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 240 */ 1159, 1159, 1159, 1261, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 250 */ 1159, 1159, 1159, 1159, 1159, 1486, 1159, 1406, 1243, 1261,
- /* 260 */ 1261, 1261, 1261, 1263, 1244, 1242, 1255, 1190, 1166, 1528,
- /* 270 */ 1305, 1284, 1284, 1525, 1305, 1305, 1525, 1204, 1506, 1201,
- /* 280 */ 1295, 1295, 1295, 1284, 1289, 1289, 1373, 1262, 1255, 1159,
- /* 290 */ 1528, 1270, 1270, 1527, 1527, 1270, 1394, 1314, 1320, 1232,
- /* 300 */ 1305, 1238, 1238, 1238, 1238, 1270, 1177, 1305, 1305, 1314,
- /* 310 */ 1320, 1232, 1232, 1305, 1270, 1177, 1410, 1522, 1270, 1177,
- /* 320 */ 1384, 1270, 1177, 1270, 1177, 1384, 1230, 1230, 1230, 1219,
- /* 330 */ 1384, 1230, 1204, 1230, 1219, 1230, 1230, 1384, 1388, 1388,
- /* 340 */ 1384, 1288, 1283, 1288, 1283, 1288, 1283, 1288, 1283, 1270,
- /* 350 */ 1469, 1469, 1300, 1289, 1379, 1270, 1159, 1300, 1298, 1296,
- /* 360 */ 1305, 1183, 1222, 1489, 1489, 1485, 1485, 1485, 1533, 1533,
- /* 370 */ 1442, 1501, 1190, 1190, 1190, 1190, 1501, 1206, 1206, 1190,
- /* 380 */ 1190, 1190, 1190, 1501, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 390 */ 1496, 1159, 1395, 1274, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 240 */ 1159, 1159, 1159, 1262, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 250 */ 1159, 1159, 1159, 1159, 1159, 1487, 1159, 1407, 1244, 1262,
+ /* 260 */ 1262, 1262, 1262, 1264, 1245, 1243, 1256, 1191, 1166, 1529,
+ /* 270 */ 1306, 1285, 1285, 1526, 1306, 1306, 1526, 1205, 1507, 1202,
+ /* 280 */ 1296, 1296, 1296, 1285, 1290, 1290, 1374, 1263, 1256, 1159,
+ /* 290 */ 1529, 1271, 1271, 1528, 1528, 1271, 1395, 1315, 1321, 1233,
+ /* 300 */ 1306, 1239, 1239, 1239, 1239, 1271, 1177, 1306, 1306, 1315,
+ /* 310 */ 1321, 1233, 1233, 1306, 1271, 1177, 1411, 1523, 1271, 1177,
+ /* 320 */ 1385, 1271, 1177, 1271, 1177, 1385, 1231, 1231, 1231, 1220,
+ /* 330 */ 1385, 1231, 1205, 1231, 1220, 1231, 1231, 1385, 1389, 1389,
+ /* 340 */ 1385, 1289, 1284, 1289, 1284, 1289, 1284, 1289, 1284, 1271,
+ /* 350 */ 1470, 1470, 1301, 1290, 1380, 1271, 1159, 1301, 1299, 1297,
+ /* 360 */ 1306, 1183, 1223, 1490, 1490, 1486, 1486, 1486, 1534, 1534,
+ /* 370 */ 1443, 1502, 1190, 1190, 1190, 1190, 1502, 1207, 1207, 1191,
+ /* 380 */ 1191, 1190, 1502, 1159, 1159, 1159, 1159, 1159, 1159, 1497,
+ /* 390 */ 1159, 1396, 1275, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 400 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 410 */ 1159, 1159, 1159, 1159, 1159, 1159, 1325, 1159, 1162, 1439,
- /* 420 */ 1159, 1159, 1437, 1159, 1159, 1159, 1159, 1159, 1159, 1275,
+ /* 410 */ 1159, 1159, 1159, 1159, 1159, 1326, 1159, 1162, 1440, 1159,
+ /* 420 */ 1159, 1438, 1159, 1159, 1159, 1159, 1159, 1159, 1276, 1159,
/* 430 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 440 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1524, 1159,
- /* 450 */ 1159, 1159, 1159, 1159, 1159, 1409, 1408, 1159, 1159, 1272,
+ /* 440 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1525, 1159, 1159,
+ /* 450 */ 1159, 1159, 1159, 1159, 1410, 1409, 1159, 1159, 1273, 1159,
/* 460 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 470 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
/* 480 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 490 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1297, 1159,
+ /* 490 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1298, 1159, 1159,
/* 500 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 510 */ 1159, 1159, 1159, 1474, 1290, 1159, 1159, 1515, 1159, 1159,
+ /* 510 */ 1159, 1159, 1475, 1291, 1159, 1159, 1516, 1159, 1159, 1159,
/* 520 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
- /* 530 */ 1159, 1159, 1510, 1246, 1327, 1159, 1326, 1330, 1159, 1171,
- /* 540 */ 1159,
+ /* 530 */ 1159, 1511, 1247, 1328, 1159, 1327, 1331, 1159, 1171, 1159,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -149481,103 +150058,104 @@ static const char *const yyTokenName[] = {
/* 201 */ "plus_num",
/* 202 */ "minus_num",
/* 203 */ "scanpt",
- /* 204 */ "ccons",
- /* 205 */ "term",
- /* 206 */ "expr",
- /* 207 */ "onconf",
- /* 208 */ "sortorder",
- /* 209 */ "autoinc",
- /* 210 */ "eidlist_opt",
- /* 211 */ "refargs",
- /* 212 */ "defer_subclause",
- /* 213 */ "refarg",
- /* 214 */ "refact",
- /* 215 */ "init_deferred_pred_opt",
- /* 216 */ "conslist",
- /* 217 */ "tconscomma",
- /* 218 */ "tcons",
- /* 219 */ "sortlist",
- /* 220 */ "eidlist",
- /* 221 */ "defer_subclause_opt",
- /* 222 */ "orconf",
- /* 223 */ "resolvetype",
- /* 224 */ "raisetype",
- /* 225 */ "ifexists",
- /* 226 */ "fullname",
- /* 227 */ "selectnowith",
- /* 228 */ "oneselect",
- /* 229 */ "wqlist",
- /* 230 */ "multiselect_op",
- /* 231 */ "distinct",
- /* 232 */ "selcollist",
- /* 233 */ "from",
- /* 234 */ "where_opt",
- /* 235 */ "groupby_opt",
- /* 236 */ "having_opt",
- /* 237 */ "orderby_opt",
- /* 238 */ "limit_opt",
- /* 239 */ "window_clause",
- /* 240 */ "values",
- /* 241 */ "nexprlist",
- /* 242 */ "sclp",
- /* 243 */ "as",
- /* 244 */ "seltablist",
- /* 245 */ "stl_prefix",
- /* 246 */ "joinop",
- /* 247 */ "indexed_opt",
- /* 248 */ "on_opt",
- /* 249 */ "using_opt",
- /* 250 */ "exprlist",
- /* 251 */ "xfullname",
- /* 252 */ "idlist",
- /* 253 */ "with",
- /* 254 */ "setlist",
- /* 255 */ "insert_cmd",
- /* 256 */ "idlist_opt",
- /* 257 */ "upsert",
- /* 258 */ "over_clause",
- /* 259 */ "likeop",
- /* 260 */ "between_op",
- /* 261 */ "in_op",
- /* 262 */ "paren_exprlist",
- /* 263 */ "case_operand",
- /* 264 */ "case_exprlist",
- /* 265 */ "case_else",
- /* 266 */ "uniqueflag",
- /* 267 */ "collate",
- /* 268 */ "vinto",
- /* 269 */ "nmnum",
- /* 270 */ "trigger_decl",
- /* 271 */ "trigger_cmd_list",
- /* 272 */ "trigger_time",
- /* 273 */ "trigger_event",
- /* 274 */ "foreach_clause",
- /* 275 */ "when_clause",
- /* 276 */ "trigger_cmd",
- /* 277 */ "trnm",
- /* 278 */ "tridxby",
- /* 279 */ "database_kw_opt",
- /* 280 */ "key_opt",
- /* 281 */ "add_column_fullname",
- /* 282 */ "kwcolumn_opt",
- /* 283 */ "create_vtab",
- /* 284 */ "vtabarglist",
- /* 285 */ "vtabarg",
- /* 286 */ "vtabargtoken",
- /* 287 */ "lp",
- /* 288 */ "anylist",
- /* 289 */ "windowdefn_list",
- /* 290 */ "windowdefn",
- /* 291 */ "window",
- /* 292 */ "frame_opt",
- /* 293 */ "part_opt",
- /* 294 */ "filter_opt",
- /* 295 */ "range_or_rows",
- /* 296 */ "frame_bound",
- /* 297 */ "frame_bound_s",
- /* 298 */ "frame_bound_e",
- /* 299 */ "frame_exclude_opt",
- /* 300 */ "frame_exclude",
+ /* 204 */ "scantok",
+ /* 205 */ "ccons",
+ /* 206 */ "term",
+ /* 207 */ "expr",
+ /* 208 */ "onconf",
+ /* 209 */ "sortorder",
+ /* 210 */ "autoinc",
+ /* 211 */ "eidlist_opt",
+ /* 212 */ "refargs",
+ /* 213 */ "defer_subclause",
+ /* 214 */ "refarg",
+ /* 215 */ "refact",
+ /* 216 */ "init_deferred_pred_opt",
+ /* 217 */ "conslist",
+ /* 218 */ "tconscomma",
+ /* 219 */ "tcons",
+ /* 220 */ "sortlist",
+ /* 221 */ "eidlist",
+ /* 222 */ "defer_subclause_opt",
+ /* 223 */ "orconf",
+ /* 224 */ "resolvetype",
+ /* 225 */ "raisetype",
+ /* 226 */ "ifexists",
+ /* 227 */ "fullname",
+ /* 228 */ "selectnowith",
+ /* 229 */ "oneselect",
+ /* 230 */ "wqlist",
+ /* 231 */ "multiselect_op",
+ /* 232 */ "distinct",
+ /* 233 */ "selcollist",
+ /* 234 */ "from",
+ /* 235 */ "where_opt",
+ /* 236 */ "groupby_opt",
+ /* 237 */ "having_opt",
+ /* 238 */ "orderby_opt",
+ /* 239 */ "limit_opt",
+ /* 240 */ "window_clause",
+ /* 241 */ "values",
+ /* 242 */ "nexprlist",
+ /* 243 */ "sclp",
+ /* 244 */ "as",
+ /* 245 */ "seltablist",
+ /* 246 */ "stl_prefix",
+ /* 247 */ "joinop",
+ /* 248 */ "indexed_opt",
+ /* 249 */ "on_opt",
+ /* 250 */ "using_opt",
+ /* 251 */ "exprlist",
+ /* 252 */ "xfullname",
+ /* 253 */ "idlist",
+ /* 254 */ "with",
+ /* 255 */ "setlist",
+ /* 256 */ "insert_cmd",
+ /* 257 */ "idlist_opt",
+ /* 258 */ "upsert",
+ /* 259 */ "over_clause",
+ /* 260 */ "likeop",
+ /* 261 */ "between_op",
+ /* 262 */ "in_op",
+ /* 263 */ "paren_exprlist",
+ /* 264 */ "case_operand",
+ /* 265 */ "case_exprlist",
+ /* 266 */ "case_else",
+ /* 267 */ "uniqueflag",
+ /* 268 */ "collate",
+ /* 269 */ "vinto",
+ /* 270 */ "nmnum",
+ /* 271 */ "trigger_decl",
+ /* 272 */ "trigger_cmd_list",
+ /* 273 */ "trigger_time",
+ /* 274 */ "trigger_event",
+ /* 275 */ "foreach_clause",
+ /* 276 */ "when_clause",
+ /* 277 */ "trigger_cmd",
+ /* 278 */ "trnm",
+ /* 279 */ "tridxby",
+ /* 280 */ "database_kw_opt",
+ /* 281 */ "key_opt",
+ /* 282 */ "add_column_fullname",
+ /* 283 */ "kwcolumn_opt",
+ /* 284 */ "create_vtab",
+ /* 285 */ "vtabarglist",
+ /* 286 */ "vtabarg",
+ /* 287 */ "vtabargtoken",
+ /* 288 */ "lp",
+ /* 289 */ "anylist",
+ /* 290 */ "windowdefn_list",
+ /* 291 */ "windowdefn",
+ /* 292 */ "window",
+ /* 293 */ "frame_opt",
+ /* 294 */ "part_opt",
+ /* 295 */ "filter_opt",
+ /* 296 */ "range_or_rows",
+ /* 297 */ "frame_bound",
+ /* 298 */ "frame_bound_s",
+ /* 299 */ "frame_bound_e",
+ /* 300 */ "frame_exclude_opt",
+ /* 301 */ "frame_exclude",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -149614,352 +150192,353 @@ static const char *const yyRuleName[] = {
/* 26 */ "typetoken ::= typename LP signed COMMA signed RP",
/* 27 */ "typename ::= typename ID|STRING",
/* 28 */ "scanpt ::=",
- /* 29 */ "ccons ::= CONSTRAINT nm",
- /* 30 */ "ccons ::= DEFAULT scanpt term scanpt",
- /* 31 */ "ccons ::= DEFAULT LP expr RP",
- /* 32 */ "ccons ::= DEFAULT PLUS term scanpt",
- /* 33 */ "ccons ::= DEFAULT MINUS term scanpt",
- /* 34 */ "ccons ::= DEFAULT scanpt ID|INDEXED",
- /* 35 */ "ccons ::= NOT NULL onconf",
- /* 36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 37 */ "ccons ::= UNIQUE onconf",
- /* 38 */ "ccons ::= CHECK LP expr RP",
- /* 39 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
- /* 40 */ "ccons ::= defer_subclause",
- /* 41 */ "ccons ::= COLLATE ID|STRING",
- /* 42 */ "autoinc ::=",
- /* 43 */ "autoinc ::= AUTOINCR",
- /* 44 */ "refargs ::=",
- /* 45 */ "refargs ::= refargs refarg",
- /* 46 */ "refarg ::= MATCH nm",
- /* 47 */ "refarg ::= ON INSERT refact",
- /* 48 */ "refarg ::= ON DELETE refact",
- /* 49 */ "refarg ::= ON UPDATE refact",
- /* 50 */ "refact ::= SET NULL",
- /* 51 */ "refact ::= SET DEFAULT",
- /* 52 */ "refact ::= CASCADE",
- /* 53 */ "refact ::= RESTRICT",
- /* 54 */ "refact ::= NO ACTION",
- /* 55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 57 */ "init_deferred_pred_opt ::=",
- /* 58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 60 */ "conslist_opt ::=",
- /* 61 */ "tconscomma ::= COMMA",
- /* 62 */ "tcons ::= CONSTRAINT nm",
- /* 63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
- /* 64 */ "tcons ::= UNIQUE LP sortlist RP onconf",
- /* 65 */ "tcons ::= CHECK LP expr RP onconf",
- /* 66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
- /* 67 */ "defer_subclause_opt ::=",
- /* 68 */ "onconf ::=",
- /* 69 */ "onconf ::= ON CONFLICT resolvetype",
- /* 70 */ "orconf ::=",
- /* 71 */ "orconf ::= OR resolvetype",
- /* 72 */ "resolvetype ::= IGNORE",
- /* 73 */ "resolvetype ::= REPLACE",
- /* 74 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 75 */ "ifexists ::= IF EXISTS",
- /* 76 */ "ifexists ::=",
- /* 77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
- /* 78 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 79 */ "cmd ::= select",
- /* 80 */ "select ::= WITH wqlist selectnowith",
- /* 81 */ "select ::= WITH RECURSIVE wqlist selectnowith",
- /* 82 */ "select ::= selectnowith",
- /* 83 */ "selectnowith ::= selectnowith multiselect_op oneselect",
- /* 84 */ "multiselect_op ::= UNION",
- /* 85 */ "multiselect_op ::= UNION ALL",
- /* 86 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
- /* 89 */ "values ::= VALUES LP nexprlist RP",
- /* 90 */ "values ::= values COMMA LP nexprlist RP",
- /* 91 */ "distinct ::= DISTINCT",
- /* 92 */ "distinct ::= ALL",
- /* 93 */ "distinct ::=",
- /* 94 */ "sclp ::=",
- /* 95 */ "selcollist ::= sclp scanpt expr scanpt as",
- /* 96 */ "selcollist ::= sclp scanpt STAR",
- /* 97 */ "selcollist ::= sclp scanpt nm DOT STAR",
- /* 98 */ "as ::= AS nm",
- /* 99 */ "as ::=",
- /* 100 */ "from ::=",
- /* 101 */ "from ::= FROM seltablist",
- /* 102 */ "stl_prefix ::= seltablist joinop",
- /* 103 */ "stl_prefix ::=",
- /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
- /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 108 */ "dbnm ::=",
- /* 109 */ "dbnm ::= DOT nm",
- /* 110 */ "fullname ::= nm",
- /* 111 */ "fullname ::= nm DOT nm",
- /* 112 */ "xfullname ::= nm",
- /* 113 */ "xfullname ::= nm DOT nm",
- /* 114 */ "xfullname ::= nm DOT nm AS nm",
- /* 115 */ "xfullname ::= nm AS nm",
- /* 116 */ "joinop ::= COMMA|JOIN",
- /* 117 */ "joinop ::= JOIN_KW JOIN",
- /* 118 */ "joinop ::= JOIN_KW nm JOIN",
- /* 119 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 120 */ "on_opt ::= ON expr",
- /* 121 */ "on_opt ::=",
- /* 122 */ "indexed_opt ::=",
- /* 123 */ "indexed_opt ::= INDEXED BY nm",
- /* 124 */ "indexed_opt ::= NOT INDEXED",
- /* 125 */ "using_opt ::= USING LP idlist RP",
- /* 126 */ "using_opt ::=",
- /* 127 */ "orderby_opt ::=",
- /* 128 */ "orderby_opt ::= ORDER BY sortlist",
- /* 129 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 130 */ "sortlist ::= expr sortorder",
- /* 131 */ "sortorder ::= ASC",
- /* 132 */ "sortorder ::= DESC",
- /* 133 */ "sortorder ::=",
- /* 134 */ "groupby_opt ::=",
- /* 135 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 136 */ "having_opt ::=",
- /* 137 */ "having_opt ::= HAVING expr",
- /* 138 */ "limit_opt ::=",
- /* 139 */ "limit_opt ::= LIMIT expr",
- /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 141 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
- /* 143 */ "where_opt ::=",
- /* 144 */ "where_opt ::= WHERE expr",
- /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
- /* 146 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
- /* 148 */ "setlist ::= nm EQ expr",
- /* 149 */ "setlist ::= LP idlist RP EQ expr",
- /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
- /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
- /* 152 */ "upsert ::=",
- /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
- /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
- /* 155 */ "upsert ::= ON CONFLICT DO NOTHING",
- /* 156 */ "insert_cmd ::= INSERT orconf",
- /* 157 */ "insert_cmd ::= REPLACE",
- /* 158 */ "idlist_opt ::=",
- /* 159 */ "idlist_opt ::= LP idlist RP",
- /* 160 */ "idlist ::= idlist COMMA nm",
- /* 161 */ "idlist ::= nm",
- /* 162 */ "expr ::= LP expr RP",
- /* 163 */ "expr ::= ID|INDEXED",
- /* 164 */ "expr ::= JOIN_KW",
- /* 165 */ "expr ::= nm DOT nm",
- /* 166 */ "expr ::= nm DOT nm DOT nm",
- /* 167 */ "term ::= NULL|FLOAT|BLOB",
- /* 168 */ "term ::= STRING",
- /* 169 */ "term ::= INTEGER",
- /* 170 */ "expr ::= VARIABLE",
- /* 171 */ "expr ::= expr COLLATE ID|STRING",
- /* 172 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 174 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
- /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
- /* 177 */ "term ::= CTIME_KW",
- /* 178 */ "expr ::= LP nexprlist COMMA expr RP",
- /* 179 */ "expr ::= expr AND expr",
- /* 180 */ "expr ::= expr OR expr",
- /* 181 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 182 */ "expr ::= expr EQ|NE expr",
- /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 184 */ "expr ::= expr PLUS|MINUS expr",
- /* 185 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 186 */ "expr ::= expr CONCAT expr",
- /* 187 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 188 */ "expr ::= expr likeop expr",
- /* 189 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 190 */ "expr ::= expr ISNULL|NOTNULL",
- /* 191 */ "expr ::= expr NOT NULL",
- /* 192 */ "expr ::= expr IS expr",
- /* 193 */ "expr ::= expr IS NOT expr",
- /* 194 */ "expr ::= NOT expr",
- /* 195 */ "expr ::= BITNOT expr",
- /* 196 */ "expr ::= PLUS|MINUS expr",
- /* 197 */ "between_op ::= BETWEEN",
- /* 198 */ "between_op ::= NOT BETWEEN",
- /* 199 */ "expr ::= expr between_op expr AND expr",
- /* 200 */ "in_op ::= IN",
- /* 201 */ "in_op ::= NOT IN",
- /* 202 */ "expr ::= expr in_op LP exprlist RP",
- /* 203 */ "expr ::= LP select RP",
- /* 204 */ "expr ::= expr in_op LP select RP",
- /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 206 */ "expr ::= EXISTS LP select RP",
- /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 209 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 210 */ "case_else ::= ELSE expr",
- /* 211 */ "case_else ::=",
- /* 212 */ "case_operand ::= expr",
- /* 213 */ "case_operand ::=",
- /* 214 */ "exprlist ::=",
- /* 215 */ "nexprlist ::= nexprlist COMMA expr",
- /* 216 */ "nexprlist ::= expr",
- /* 217 */ "paren_exprlist ::=",
- /* 218 */ "paren_exprlist ::= LP exprlist RP",
- /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 220 */ "uniqueflag ::= UNIQUE",
- /* 221 */ "uniqueflag ::=",
- /* 222 */ "eidlist_opt ::=",
- /* 223 */ "eidlist_opt ::= LP eidlist RP",
- /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 225 */ "eidlist ::= nm collate sortorder",
- /* 226 */ "collate ::=",
- /* 227 */ "collate ::= COLLATE ID|STRING",
- /* 228 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 229 */ "cmd ::= VACUUM vinto",
- /* 230 */ "cmd ::= VACUUM nm vinto",
- /* 231 */ "vinto ::= INTO expr",
- /* 232 */ "vinto ::=",
- /* 233 */ "cmd ::= PRAGMA nm dbnm",
- /* 234 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 235 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 236 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 237 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 238 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 239 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 240 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 241 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 242 */ "trigger_time ::= BEFORE|AFTER",
- /* 243 */ "trigger_time ::= INSTEAD OF",
- /* 244 */ "trigger_time ::=",
- /* 245 */ "trigger_event ::= DELETE|INSERT",
- /* 246 */ "trigger_event ::= UPDATE",
- /* 247 */ "trigger_event ::= UPDATE OF idlist",
- /* 248 */ "when_clause ::=",
- /* 249 */ "when_clause ::= WHEN expr",
- /* 250 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 251 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 252 */ "trnm ::= nm DOT nm",
- /* 253 */ "tridxby ::= INDEXED BY nm",
- /* 254 */ "tridxby ::= NOT INDEXED",
- /* 255 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
- /* 256 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
- /* 257 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
- /* 258 */ "trigger_cmd ::= scanpt select scanpt",
- /* 259 */ "expr ::= RAISE LP IGNORE RP",
- /* 260 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 261 */ "raisetype ::= ROLLBACK",
- /* 262 */ "raisetype ::= ABORT",
- /* 263 */ "raisetype ::= FAIL",
- /* 264 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 265 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 266 */ "cmd ::= DETACH database_kw_opt expr",
- /* 267 */ "key_opt ::=",
- /* 268 */ "key_opt ::= KEY expr",
- /* 269 */ "cmd ::= REINDEX",
- /* 270 */ "cmd ::= REINDEX nm dbnm",
- /* 271 */ "cmd ::= ANALYZE",
- /* 272 */ "cmd ::= ANALYZE nm dbnm",
- /* 273 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 274 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 275 */ "add_column_fullname ::= fullname",
- /* 276 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
- /* 277 */ "cmd ::= create_vtab",
- /* 278 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 279 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 280 */ "vtabarg ::=",
- /* 281 */ "vtabargtoken ::= ANY",
- /* 282 */ "vtabargtoken ::= lp anylist RP",
- /* 283 */ "lp ::= LP",
- /* 284 */ "with ::= WITH wqlist",
- /* 285 */ "with ::= WITH RECURSIVE wqlist",
- /* 286 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 287 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 288 */ "windowdefn_list ::= windowdefn",
- /* 289 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
- /* 290 */ "windowdefn ::= nm AS LP window RP",
- /* 291 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
- /* 292 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
- /* 293 */ "window ::= ORDER BY sortlist frame_opt",
- /* 294 */ "window ::= nm ORDER BY sortlist frame_opt",
- /* 295 */ "window ::= frame_opt",
- /* 296 */ "window ::= nm frame_opt",
- /* 297 */ "frame_opt ::=",
- /* 298 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
- /* 299 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
- /* 300 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
- /* 301 */ "frame_bound_s ::= frame_bound",
- /* 302 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
- /* 303 */ "frame_bound_e ::= frame_bound",
- /* 304 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
- /* 305 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
- /* 306 */ "frame_bound ::= CURRENT ROW",
- /* 307 */ "frame_exclude_opt ::=",
- /* 308 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
- /* 309 */ "frame_exclude ::= NO OTHERS",
- /* 310 */ "frame_exclude ::= CURRENT ROW",
- /* 311 */ "frame_exclude ::= GROUP|TIES",
- /* 312 */ "window_clause ::= WINDOW windowdefn_list",
- /* 313 */ "over_clause ::= filter_opt OVER LP window RP",
- /* 314 */ "over_clause ::= filter_opt OVER nm",
- /* 315 */ "filter_opt ::=",
- /* 316 */ "filter_opt ::= FILTER LP WHERE expr RP",
- /* 317 */ "input ::= cmdlist",
- /* 318 */ "cmdlist ::= cmdlist ecmd",
- /* 319 */ "cmdlist ::= ecmd",
- /* 320 */ "ecmd ::= SEMI",
- /* 321 */ "ecmd ::= cmdx SEMI",
- /* 322 */ "ecmd ::= explain cmdx",
- /* 323 */ "trans_opt ::=",
- /* 324 */ "trans_opt ::= TRANSACTION",
- /* 325 */ "trans_opt ::= TRANSACTION nm",
- /* 326 */ "savepoint_opt ::= SAVEPOINT",
- /* 327 */ "savepoint_opt ::=",
- /* 328 */ "cmd ::= create_table create_table_args",
- /* 329 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 330 */ "columnlist ::= columnname carglist",
- /* 331 */ "nm ::= ID|INDEXED",
- /* 332 */ "nm ::= STRING",
- /* 333 */ "nm ::= JOIN_KW",
- /* 334 */ "typetoken ::= typename",
- /* 335 */ "typename ::= ID|STRING",
- /* 336 */ "signed ::= plus_num",
- /* 337 */ "signed ::= minus_num",
- /* 338 */ "carglist ::= carglist ccons",
- /* 339 */ "carglist ::=",
- /* 340 */ "ccons ::= NULL onconf",
- /* 341 */ "conslist_opt ::= COMMA conslist",
- /* 342 */ "conslist ::= conslist tconscomma tcons",
- /* 343 */ "conslist ::= tcons",
- /* 344 */ "tconscomma ::=",
- /* 345 */ "defer_subclause_opt ::= defer_subclause",
- /* 346 */ "resolvetype ::= raisetype",
- /* 347 */ "selectnowith ::= oneselect",
- /* 348 */ "oneselect ::= values",
- /* 349 */ "sclp ::= selcollist COMMA",
- /* 350 */ "as ::= ID|STRING",
- /* 351 */ "expr ::= term",
- /* 352 */ "likeop ::= LIKE_KW|MATCH",
- /* 353 */ "exprlist ::= nexprlist",
- /* 354 */ "nmnum ::= plus_num",
- /* 355 */ "nmnum ::= nm",
- /* 356 */ "nmnum ::= ON",
- /* 357 */ "nmnum ::= DELETE",
- /* 358 */ "nmnum ::= DEFAULT",
- /* 359 */ "plus_num ::= INTEGER|FLOAT",
- /* 360 */ "foreach_clause ::=",
- /* 361 */ "foreach_clause ::= FOR EACH ROW",
- /* 362 */ "trnm ::= nm",
- /* 363 */ "tridxby ::=",
- /* 364 */ "database_kw_opt ::= DATABASE",
- /* 365 */ "database_kw_opt ::=",
- /* 366 */ "kwcolumn_opt ::=",
- /* 367 */ "kwcolumn_opt ::= COLUMNKW",
- /* 368 */ "vtabarglist ::= vtabarg",
- /* 369 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 370 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 371 */ "anylist ::=",
- /* 372 */ "anylist ::= anylist LP anylist RP",
- /* 373 */ "anylist ::= anylist ANY",
- /* 374 */ "with ::=",
+ /* 29 */ "scantok ::=",
+ /* 30 */ "ccons ::= CONSTRAINT nm",
+ /* 31 */ "ccons ::= DEFAULT scantok term",
+ /* 32 */ "ccons ::= DEFAULT LP expr RP",
+ /* 33 */ "ccons ::= DEFAULT PLUS scantok term",
+ /* 34 */ "ccons ::= DEFAULT MINUS scantok term",
+ /* 35 */ "ccons ::= DEFAULT scantok ID|INDEXED",
+ /* 36 */ "ccons ::= NOT NULL onconf",
+ /* 37 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 38 */ "ccons ::= UNIQUE onconf",
+ /* 39 */ "ccons ::= CHECK LP expr RP",
+ /* 40 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+ /* 41 */ "ccons ::= defer_subclause",
+ /* 42 */ "ccons ::= COLLATE ID|STRING",
+ /* 43 */ "autoinc ::=",
+ /* 44 */ "autoinc ::= AUTOINCR",
+ /* 45 */ "refargs ::=",
+ /* 46 */ "refargs ::= refargs refarg",
+ /* 47 */ "refarg ::= MATCH nm",
+ /* 48 */ "refarg ::= ON INSERT refact",
+ /* 49 */ "refarg ::= ON DELETE refact",
+ /* 50 */ "refarg ::= ON UPDATE refact",
+ /* 51 */ "refact ::= SET NULL",
+ /* 52 */ "refact ::= SET DEFAULT",
+ /* 53 */ "refact ::= CASCADE",
+ /* 54 */ "refact ::= RESTRICT",
+ /* 55 */ "refact ::= NO ACTION",
+ /* 56 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 57 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 58 */ "init_deferred_pred_opt ::=",
+ /* 59 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 60 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 61 */ "conslist_opt ::=",
+ /* 62 */ "tconscomma ::= COMMA",
+ /* 63 */ "tcons ::= CONSTRAINT nm",
+ /* 64 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /* 65 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+ /* 66 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 67 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+ /* 68 */ "defer_subclause_opt ::=",
+ /* 69 */ "onconf ::=",
+ /* 70 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 71 */ "orconf ::=",
+ /* 72 */ "orconf ::= OR resolvetype",
+ /* 73 */ "resolvetype ::= IGNORE",
+ /* 74 */ "resolvetype ::= REPLACE",
+ /* 75 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 76 */ "ifexists ::= IF EXISTS",
+ /* 77 */ "ifexists ::=",
+ /* 78 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+ /* 79 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 80 */ "cmd ::= select",
+ /* 81 */ "select ::= WITH wqlist selectnowith",
+ /* 82 */ "select ::= WITH RECURSIVE wqlist selectnowith",
+ /* 83 */ "select ::= selectnowith",
+ /* 84 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /* 85 */ "multiselect_op ::= UNION",
+ /* 86 */ "multiselect_op ::= UNION ALL",
+ /* 87 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 89 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
+ /* 90 */ "values ::= VALUES LP nexprlist RP",
+ /* 91 */ "values ::= values COMMA LP nexprlist RP",
+ /* 92 */ "distinct ::= DISTINCT",
+ /* 93 */ "distinct ::= ALL",
+ /* 94 */ "distinct ::=",
+ /* 95 */ "sclp ::=",
+ /* 96 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /* 97 */ "selcollist ::= sclp scanpt STAR",
+ /* 98 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /* 99 */ "as ::= AS nm",
+ /* 100 */ "as ::=",
+ /* 101 */ "from ::=",
+ /* 102 */ "from ::= FROM seltablist",
+ /* 103 */ "stl_prefix ::= seltablist joinop",
+ /* 104 */ "stl_prefix ::=",
+ /* 105 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 106 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 107 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 108 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 109 */ "dbnm ::=",
+ /* 110 */ "dbnm ::= DOT nm",
+ /* 111 */ "fullname ::= nm",
+ /* 112 */ "fullname ::= nm DOT nm",
+ /* 113 */ "xfullname ::= nm",
+ /* 114 */ "xfullname ::= nm DOT nm",
+ /* 115 */ "xfullname ::= nm DOT nm AS nm",
+ /* 116 */ "xfullname ::= nm AS nm",
+ /* 117 */ "joinop ::= COMMA|JOIN",
+ /* 118 */ "joinop ::= JOIN_KW JOIN",
+ /* 119 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 120 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 121 */ "on_opt ::= ON expr",
+ /* 122 */ "on_opt ::=",
+ /* 123 */ "indexed_opt ::=",
+ /* 124 */ "indexed_opt ::= INDEXED BY nm",
+ /* 125 */ "indexed_opt ::= NOT INDEXED",
+ /* 126 */ "using_opt ::= USING LP idlist RP",
+ /* 127 */ "using_opt ::=",
+ /* 128 */ "orderby_opt ::=",
+ /* 129 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 130 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 131 */ "sortlist ::= expr sortorder",
+ /* 132 */ "sortorder ::= ASC",
+ /* 133 */ "sortorder ::= DESC",
+ /* 134 */ "sortorder ::=",
+ /* 135 */ "groupby_opt ::=",
+ /* 136 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 137 */ "having_opt ::=",
+ /* 138 */ "having_opt ::= HAVING expr",
+ /* 139 */ "limit_opt ::=",
+ /* 140 */ "limit_opt ::= LIMIT expr",
+ /* 141 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 142 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 143 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
+ /* 144 */ "where_opt ::=",
+ /* 145 */ "where_opt ::= WHERE expr",
+ /* 146 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
+ /* 147 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 148 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 149 */ "setlist ::= nm EQ expr",
+ /* 150 */ "setlist ::= LP idlist RP EQ expr",
+ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
+ /* 152 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
+ /* 153 */ "upsert ::=",
+ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
+ /* 155 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
+ /* 156 */ "upsert ::= ON CONFLICT DO NOTHING",
+ /* 157 */ "insert_cmd ::= INSERT orconf",
+ /* 158 */ "insert_cmd ::= REPLACE",
+ /* 159 */ "idlist_opt ::=",
+ /* 160 */ "idlist_opt ::= LP idlist RP",
+ /* 161 */ "idlist ::= idlist COMMA nm",
+ /* 162 */ "idlist ::= nm",
+ /* 163 */ "expr ::= LP expr RP",
+ /* 164 */ "expr ::= ID|INDEXED",
+ /* 165 */ "expr ::= JOIN_KW",
+ /* 166 */ "expr ::= nm DOT nm",
+ /* 167 */ "expr ::= nm DOT nm DOT nm",
+ /* 168 */ "term ::= NULL|FLOAT|BLOB",
+ /* 169 */ "term ::= STRING",
+ /* 170 */ "term ::= INTEGER",
+ /* 171 */ "expr ::= VARIABLE",
+ /* 172 */ "expr ::= expr COLLATE ID|STRING",
+ /* 173 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 174 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 175 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 176 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
+ /* 177 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
+ /* 178 */ "term ::= CTIME_KW",
+ /* 179 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 180 */ "expr ::= expr AND expr",
+ /* 181 */ "expr ::= expr OR expr",
+ /* 182 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 183 */ "expr ::= expr EQ|NE expr",
+ /* 184 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 185 */ "expr ::= expr PLUS|MINUS expr",
+ /* 186 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 187 */ "expr ::= expr CONCAT expr",
+ /* 188 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 189 */ "expr ::= expr likeop expr",
+ /* 190 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 191 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 192 */ "expr ::= expr NOT NULL",
+ /* 193 */ "expr ::= expr IS expr",
+ /* 194 */ "expr ::= expr IS NOT expr",
+ /* 195 */ "expr ::= NOT expr",
+ /* 196 */ "expr ::= BITNOT expr",
+ /* 197 */ "expr ::= PLUS|MINUS expr",
+ /* 198 */ "between_op ::= BETWEEN",
+ /* 199 */ "between_op ::= NOT BETWEEN",
+ /* 200 */ "expr ::= expr between_op expr AND expr",
+ /* 201 */ "in_op ::= IN",
+ /* 202 */ "in_op ::= NOT IN",
+ /* 203 */ "expr ::= expr in_op LP exprlist RP",
+ /* 204 */ "expr ::= LP select RP",
+ /* 205 */ "expr ::= expr in_op LP select RP",
+ /* 206 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 207 */ "expr ::= EXISTS LP select RP",
+ /* 208 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 209 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 210 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 211 */ "case_else ::= ELSE expr",
+ /* 212 */ "case_else ::=",
+ /* 213 */ "case_operand ::= expr",
+ /* 214 */ "case_operand ::=",
+ /* 215 */ "exprlist ::=",
+ /* 216 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 217 */ "nexprlist ::= expr",
+ /* 218 */ "paren_exprlist ::=",
+ /* 219 */ "paren_exprlist ::= LP exprlist RP",
+ /* 220 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 221 */ "uniqueflag ::= UNIQUE",
+ /* 222 */ "uniqueflag ::=",
+ /* 223 */ "eidlist_opt ::=",
+ /* 224 */ "eidlist_opt ::= LP eidlist RP",
+ /* 225 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 226 */ "eidlist ::= nm collate sortorder",
+ /* 227 */ "collate ::=",
+ /* 228 */ "collate ::= COLLATE ID|STRING",
+ /* 229 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 230 */ "cmd ::= VACUUM vinto",
+ /* 231 */ "cmd ::= VACUUM nm vinto",
+ /* 232 */ "vinto ::= INTO expr",
+ /* 233 */ "vinto ::=",
+ /* 234 */ "cmd ::= PRAGMA nm dbnm",
+ /* 235 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 236 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 237 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 238 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 239 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 240 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 241 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 242 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 243 */ "trigger_time ::= BEFORE|AFTER",
+ /* 244 */ "trigger_time ::= INSTEAD OF",
+ /* 245 */ "trigger_time ::=",
+ /* 246 */ "trigger_event ::= DELETE|INSERT",
+ /* 247 */ "trigger_event ::= UPDATE",
+ /* 248 */ "trigger_event ::= UPDATE OF idlist",
+ /* 249 */ "when_clause ::=",
+ /* 250 */ "when_clause ::= WHEN expr",
+ /* 251 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 252 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 253 */ "trnm ::= nm DOT nm",
+ /* 254 */ "tridxby ::= INDEXED BY nm",
+ /* 255 */ "tridxby ::= NOT INDEXED",
+ /* 256 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
+ /* 257 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 258 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 259 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 260 */ "expr ::= RAISE LP IGNORE RP",
+ /* 261 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 262 */ "raisetype ::= ROLLBACK",
+ /* 263 */ "raisetype ::= ABORT",
+ /* 264 */ "raisetype ::= FAIL",
+ /* 265 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 266 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 267 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 268 */ "key_opt ::=",
+ /* 269 */ "key_opt ::= KEY expr",
+ /* 270 */ "cmd ::= REINDEX",
+ /* 271 */ "cmd ::= REINDEX nm dbnm",
+ /* 272 */ "cmd ::= ANALYZE",
+ /* 273 */ "cmd ::= ANALYZE nm dbnm",
+ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 275 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 276 */ "add_column_fullname ::= fullname",
+ /* 277 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 278 */ "cmd ::= create_vtab",
+ /* 279 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 280 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 281 */ "vtabarg ::=",
+ /* 282 */ "vtabargtoken ::= ANY",
+ /* 283 */ "vtabargtoken ::= lp anylist RP",
+ /* 284 */ "lp ::= LP",
+ /* 285 */ "with ::= WITH wqlist",
+ /* 286 */ "with ::= WITH RECURSIVE wqlist",
+ /* 287 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 288 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 289 */ "windowdefn_list ::= windowdefn",
+ /* 290 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 291 */ "windowdefn ::= nm AS LP window RP",
+ /* 292 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 293 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 294 */ "window ::= ORDER BY sortlist frame_opt",
+ /* 295 */ "window ::= nm ORDER BY sortlist frame_opt",
+ /* 296 */ "window ::= frame_opt",
+ /* 297 */ "window ::= nm frame_opt",
+ /* 298 */ "frame_opt ::=",
+ /* 299 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
+ /* 300 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
+ /* 301 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
+ /* 302 */ "frame_bound_s ::= frame_bound",
+ /* 303 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 304 */ "frame_bound_e ::= frame_bound",
+ /* 305 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 306 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
+ /* 307 */ "frame_bound ::= CURRENT ROW",
+ /* 308 */ "frame_exclude_opt ::=",
+ /* 309 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
+ /* 310 */ "frame_exclude ::= NO OTHERS",
+ /* 311 */ "frame_exclude ::= CURRENT ROW",
+ /* 312 */ "frame_exclude ::= GROUP|TIES",
+ /* 313 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 314 */ "over_clause ::= filter_opt OVER LP window RP",
+ /* 315 */ "over_clause ::= filter_opt OVER nm",
+ /* 316 */ "filter_opt ::=",
+ /* 317 */ "filter_opt ::= FILTER LP WHERE expr RP",
+ /* 318 */ "input ::= cmdlist",
+ /* 319 */ "cmdlist ::= cmdlist ecmd",
+ /* 320 */ "cmdlist ::= ecmd",
+ /* 321 */ "ecmd ::= SEMI",
+ /* 322 */ "ecmd ::= cmdx SEMI",
+ /* 323 */ "ecmd ::= explain cmdx",
+ /* 324 */ "trans_opt ::=",
+ /* 325 */ "trans_opt ::= TRANSACTION",
+ /* 326 */ "trans_opt ::= TRANSACTION nm",
+ /* 327 */ "savepoint_opt ::= SAVEPOINT",
+ /* 328 */ "savepoint_opt ::=",
+ /* 329 */ "cmd ::= create_table create_table_args",
+ /* 330 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 331 */ "columnlist ::= columnname carglist",
+ /* 332 */ "nm ::= ID|INDEXED",
+ /* 333 */ "nm ::= STRING",
+ /* 334 */ "nm ::= JOIN_KW",
+ /* 335 */ "typetoken ::= typename",
+ /* 336 */ "typename ::= ID|STRING",
+ /* 337 */ "signed ::= plus_num",
+ /* 338 */ "signed ::= minus_num",
+ /* 339 */ "carglist ::= carglist ccons",
+ /* 340 */ "carglist ::=",
+ /* 341 */ "ccons ::= NULL onconf",
+ /* 342 */ "conslist_opt ::= COMMA conslist",
+ /* 343 */ "conslist ::= conslist tconscomma tcons",
+ /* 344 */ "conslist ::= tcons",
+ /* 345 */ "tconscomma ::=",
+ /* 346 */ "defer_subclause_opt ::= defer_subclause",
+ /* 347 */ "resolvetype ::= raisetype",
+ /* 348 */ "selectnowith ::= oneselect",
+ /* 349 */ "oneselect ::= values",
+ /* 350 */ "sclp ::= selcollist COMMA",
+ /* 351 */ "as ::= ID|STRING",
+ /* 352 */ "expr ::= term",
+ /* 353 */ "likeop ::= LIKE_KW|MATCH",
+ /* 354 */ "exprlist ::= nexprlist",
+ /* 355 */ "nmnum ::= plus_num",
+ /* 356 */ "nmnum ::= nm",
+ /* 357 */ "nmnum ::= ON",
+ /* 358 */ "nmnum ::= DELETE",
+ /* 359 */ "nmnum ::= DEFAULT",
+ /* 360 */ "plus_num ::= INTEGER|FLOAT",
+ /* 361 */ "foreach_clause ::=",
+ /* 362 */ "foreach_clause ::= FOR EACH ROW",
+ /* 363 */ "trnm ::= nm",
+ /* 364 */ "tridxby ::=",
+ /* 365 */ "database_kw_opt ::= DATABASE",
+ /* 366 */ "database_kw_opt ::=",
+ /* 367 */ "kwcolumn_opt ::=",
+ /* 368 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 369 */ "vtabarglist ::= vtabarg",
+ /* 370 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 371 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 372 */ "anylist ::=",
+ /* 373 */ "anylist ::= anylist LP anylist RP",
+ /* 374 */ "anylist ::= anylist ANY",
+ /* 375 */ "with ::=",
};
#endif /* NDEBUG */
@@ -150086,96 +150665,96 @@ static void yy_destructor(
*/
/********* Begin destructor definitions ***************************************/
case 195: /* select */
- case 227: /* selectnowith */
- case 228: /* oneselect */
- case 240: /* values */
+ case 228: /* selectnowith */
+ case 229: /* oneselect */
+ case 241: /* values */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy457));
+sqlite3SelectDelete(pParse->db, (yypminor->yy391));
}
break;
- case 205: /* term */
- case 206: /* expr */
- case 234: /* where_opt */
- case 236: /* having_opt */
- case 248: /* on_opt */
- case 263: /* case_operand */
- case 265: /* case_else */
- case 268: /* vinto */
- case 275: /* when_clause */
- case 280: /* key_opt */
- case 294: /* filter_opt */
+ case 206: /* term */
+ case 207: /* expr */
+ case 235: /* where_opt */
+ case 237: /* having_opt */
+ case 249: /* on_opt */
+ case 264: /* case_operand */
+ case 266: /* case_else */
+ case 269: /* vinto */
+ case 276: /* when_clause */
+ case 281: /* key_opt */
+ case 295: /* filter_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy524));
+sqlite3ExprDelete(pParse->db, (yypminor->yy102));
}
break;
- case 210: /* eidlist_opt */
- case 219: /* sortlist */
- case 220: /* eidlist */
- case 232: /* selcollist */
- case 235: /* groupby_opt */
- case 237: /* orderby_opt */
- case 241: /* nexprlist */
- case 242: /* sclp */
- case 250: /* exprlist */
- case 254: /* setlist */
- case 262: /* paren_exprlist */
- case 264: /* case_exprlist */
- case 293: /* part_opt */
+ case 211: /* eidlist_opt */
+ case 220: /* sortlist */
+ case 221: /* eidlist */
+ case 233: /* selcollist */
+ case 236: /* groupby_opt */
+ case 238: /* orderby_opt */
+ case 242: /* nexprlist */
+ case 243: /* sclp */
+ case 251: /* exprlist */
+ case 255: /* setlist */
+ case 263: /* paren_exprlist */
+ case 265: /* case_exprlist */
+ case 294: /* part_opt */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy434));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy94));
}
break;
- case 226: /* fullname */
- case 233: /* from */
- case 244: /* seltablist */
- case 245: /* stl_prefix */
- case 251: /* xfullname */
+ case 227: /* fullname */
+ case 234: /* from */
+ case 245: /* seltablist */
+ case 246: /* stl_prefix */
+ case 252: /* xfullname */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy483));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy407));
}
break;
- case 229: /* wqlist */
+ case 230: /* wqlist */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy59));
+sqlite3WithDelete(pParse->db, (yypminor->yy243));
}
break;
- case 239: /* window_clause */
- case 289: /* windowdefn_list */
+ case 240: /* window_clause */
+ case 290: /* windowdefn_list */
{
-sqlite3WindowListDelete(pParse->db, (yypminor->yy295));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy379));
}
break;
- case 249: /* using_opt */
- case 252: /* idlist */
- case 256: /* idlist_opt */
+ case 250: /* using_opt */
+ case 253: /* idlist */
+ case 257: /* idlist_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy62));
+sqlite3IdListDelete(pParse->db, (yypminor->yy76));
}
break;
- case 258: /* over_clause */
- case 290: /* windowdefn */
- case 291: /* window */
- case 292: /* frame_opt */
+ case 259: /* over_clause */
+ case 291: /* windowdefn */
+ case 292: /* window */
+ case 293: /* frame_opt */
{
-sqlite3WindowDelete(pParse->db, (yypminor->yy295));
+sqlite3WindowDelete(pParse->db, (yypminor->yy379));
}
break;
- case 271: /* trigger_cmd_list */
- case 276: /* trigger_cmd */
+ case 272: /* trigger_cmd_list */
+ case 277: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy455));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy11));
}
break;
- case 273: /* trigger_event */
+ case 274: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy298).b);
}
break;
- case 296: /* frame_bound */
- case 297: /* frame_bound_s */
- case 298: /* frame_bound_e */
+ case 297: /* frame_bound */
+ case 298: /* frame_bound_s */
+ case 299: /* frame_bound_e */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy201).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy389).pExpr);
}
break;
/********* End destructor definitions *****************************************/
@@ -150499,352 +151078,353 @@ static const YYCODETYPE yyRuleInfoLhs[] = {
198, /* (26) typetoken ::= typename LP signed COMMA signed RP */
199, /* (27) typename ::= typename ID|STRING */
203, /* (28) scanpt ::= */
- 204, /* (29) ccons ::= CONSTRAINT nm */
- 204, /* (30) ccons ::= DEFAULT scanpt term scanpt */
- 204, /* (31) ccons ::= DEFAULT LP expr RP */
- 204, /* (32) ccons ::= DEFAULT PLUS term scanpt */
- 204, /* (33) ccons ::= DEFAULT MINUS term scanpt */
- 204, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
- 204, /* (35) ccons ::= NOT NULL onconf */
- 204, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
- 204, /* (37) ccons ::= UNIQUE onconf */
- 204, /* (38) ccons ::= CHECK LP expr RP */
- 204, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
- 204, /* (40) ccons ::= defer_subclause */
- 204, /* (41) ccons ::= COLLATE ID|STRING */
- 209, /* (42) autoinc ::= */
- 209, /* (43) autoinc ::= AUTOINCR */
- 211, /* (44) refargs ::= */
- 211, /* (45) refargs ::= refargs refarg */
- 213, /* (46) refarg ::= MATCH nm */
- 213, /* (47) refarg ::= ON INSERT refact */
- 213, /* (48) refarg ::= ON DELETE refact */
- 213, /* (49) refarg ::= ON UPDATE refact */
- 214, /* (50) refact ::= SET NULL */
- 214, /* (51) refact ::= SET DEFAULT */
- 214, /* (52) refact ::= CASCADE */
- 214, /* (53) refact ::= RESTRICT */
- 214, /* (54) refact ::= NO ACTION */
- 212, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- 212, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- 215, /* (57) init_deferred_pred_opt ::= */
- 215, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
- 215, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- 193, /* (60) conslist_opt ::= */
- 217, /* (61) tconscomma ::= COMMA */
- 218, /* (62) tcons ::= CONSTRAINT nm */
- 218, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
- 218, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
- 218, /* (65) tcons ::= CHECK LP expr RP onconf */
- 218, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
- 221, /* (67) defer_subclause_opt ::= */
- 207, /* (68) onconf ::= */
- 207, /* (69) onconf ::= ON CONFLICT resolvetype */
- 222, /* (70) orconf ::= */
- 222, /* (71) orconf ::= OR resolvetype */
- 223, /* (72) resolvetype ::= IGNORE */
- 223, /* (73) resolvetype ::= REPLACE */
- 181, /* (74) cmd ::= DROP TABLE ifexists fullname */
- 225, /* (75) ifexists ::= IF EXISTS */
- 225, /* (76) ifexists ::= */
- 181, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
- 181, /* (78) cmd ::= DROP VIEW ifexists fullname */
- 181, /* (79) cmd ::= select */
- 195, /* (80) select ::= WITH wqlist selectnowith */
- 195, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
- 195, /* (82) select ::= selectnowith */
- 227, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
- 230, /* (84) multiselect_op ::= UNION */
- 230, /* (85) multiselect_op ::= UNION ALL */
- 230, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
- 228, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
- 228, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
- 240, /* (89) values ::= VALUES LP nexprlist RP */
- 240, /* (90) values ::= values COMMA LP nexprlist RP */
- 231, /* (91) distinct ::= DISTINCT */
- 231, /* (92) distinct ::= ALL */
- 231, /* (93) distinct ::= */
- 242, /* (94) sclp ::= */
- 232, /* (95) selcollist ::= sclp scanpt expr scanpt as */
- 232, /* (96) selcollist ::= sclp scanpt STAR */
- 232, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
- 243, /* (98) as ::= AS nm */
- 243, /* (99) as ::= */
- 233, /* (100) from ::= */
- 233, /* (101) from ::= FROM seltablist */
- 245, /* (102) stl_prefix ::= seltablist joinop */
- 245, /* (103) stl_prefix ::= */
- 244, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
- 244, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
- 244, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
- 244, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
- 191, /* (108) dbnm ::= */
- 191, /* (109) dbnm ::= DOT nm */
- 226, /* (110) fullname ::= nm */
- 226, /* (111) fullname ::= nm DOT nm */
- 251, /* (112) xfullname ::= nm */
- 251, /* (113) xfullname ::= nm DOT nm */
- 251, /* (114) xfullname ::= nm DOT nm AS nm */
- 251, /* (115) xfullname ::= nm AS nm */
- 246, /* (116) joinop ::= COMMA|JOIN */
- 246, /* (117) joinop ::= JOIN_KW JOIN */
- 246, /* (118) joinop ::= JOIN_KW nm JOIN */
- 246, /* (119) joinop ::= JOIN_KW nm nm JOIN */
- 248, /* (120) on_opt ::= ON expr */
- 248, /* (121) on_opt ::= */
- 247, /* (122) indexed_opt ::= */
- 247, /* (123) indexed_opt ::= INDEXED BY nm */
- 247, /* (124) indexed_opt ::= NOT INDEXED */
- 249, /* (125) using_opt ::= USING LP idlist RP */
- 249, /* (126) using_opt ::= */
- 237, /* (127) orderby_opt ::= */
- 237, /* (128) orderby_opt ::= ORDER BY sortlist */
- 219, /* (129) sortlist ::= sortlist COMMA expr sortorder */
- 219, /* (130) sortlist ::= expr sortorder */
- 208, /* (131) sortorder ::= ASC */
- 208, /* (132) sortorder ::= DESC */
- 208, /* (133) sortorder ::= */
- 235, /* (134) groupby_opt ::= */
- 235, /* (135) groupby_opt ::= GROUP BY nexprlist */
- 236, /* (136) having_opt ::= */
- 236, /* (137) having_opt ::= HAVING expr */
- 238, /* (138) limit_opt ::= */
- 238, /* (139) limit_opt ::= LIMIT expr */
- 238, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
- 238, /* (141) limit_opt ::= LIMIT expr COMMA expr */
- 181, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
- 234, /* (143) where_opt ::= */
- 234, /* (144) where_opt ::= WHERE expr */
- 181, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
- 254, /* (146) setlist ::= setlist COMMA nm EQ expr */
- 254, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
- 254, /* (148) setlist ::= nm EQ expr */
- 254, /* (149) setlist ::= LP idlist RP EQ expr */
- 181, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- 181, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
- 257, /* (152) upsert ::= */
- 257, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
- 257, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
- 257, /* (155) upsert ::= ON CONFLICT DO NOTHING */
- 255, /* (156) insert_cmd ::= INSERT orconf */
- 255, /* (157) insert_cmd ::= REPLACE */
- 256, /* (158) idlist_opt ::= */
- 256, /* (159) idlist_opt ::= LP idlist RP */
- 252, /* (160) idlist ::= idlist COMMA nm */
- 252, /* (161) idlist ::= nm */
- 206, /* (162) expr ::= LP expr RP */
- 206, /* (163) expr ::= ID|INDEXED */
- 206, /* (164) expr ::= JOIN_KW */
- 206, /* (165) expr ::= nm DOT nm */
- 206, /* (166) expr ::= nm DOT nm DOT nm */
- 205, /* (167) term ::= NULL|FLOAT|BLOB */
- 205, /* (168) term ::= STRING */
- 205, /* (169) term ::= INTEGER */
- 206, /* (170) expr ::= VARIABLE */
- 206, /* (171) expr ::= expr COLLATE ID|STRING */
- 206, /* (172) expr ::= CAST LP expr AS typetoken RP */
- 206, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
- 206, /* (174) expr ::= ID|INDEXED LP STAR RP */
- 206, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
- 206, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
- 205, /* (177) term ::= CTIME_KW */
- 206, /* (178) expr ::= LP nexprlist COMMA expr RP */
- 206, /* (179) expr ::= expr AND expr */
- 206, /* (180) expr ::= expr OR expr */
- 206, /* (181) expr ::= expr LT|GT|GE|LE expr */
- 206, /* (182) expr ::= expr EQ|NE expr */
- 206, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- 206, /* (184) expr ::= expr PLUS|MINUS expr */
- 206, /* (185) expr ::= expr STAR|SLASH|REM expr */
- 206, /* (186) expr ::= expr CONCAT expr */
- 259, /* (187) likeop ::= NOT LIKE_KW|MATCH */
- 206, /* (188) expr ::= expr likeop expr */
- 206, /* (189) expr ::= expr likeop expr ESCAPE expr */
- 206, /* (190) expr ::= expr ISNULL|NOTNULL */
- 206, /* (191) expr ::= expr NOT NULL */
- 206, /* (192) expr ::= expr IS expr */
- 206, /* (193) expr ::= expr IS NOT expr */
- 206, /* (194) expr ::= NOT expr */
- 206, /* (195) expr ::= BITNOT expr */
- 206, /* (196) expr ::= PLUS|MINUS expr */
- 260, /* (197) between_op ::= BETWEEN */
- 260, /* (198) between_op ::= NOT BETWEEN */
- 206, /* (199) expr ::= expr between_op expr AND expr */
- 261, /* (200) in_op ::= IN */
- 261, /* (201) in_op ::= NOT IN */
- 206, /* (202) expr ::= expr in_op LP exprlist RP */
- 206, /* (203) expr ::= LP select RP */
- 206, /* (204) expr ::= expr in_op LP select RP */
- 206, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
- 206, /* (206) expr ::= EXISTS LP select RP */
- 206, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
- 264, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- 264, /* (209) case_exprlist ::= WHEN expr THEN expr */
- 265, /* (210) case_else ::= ELSE expr */
- 265, /* (211) case_else ::= */
- 263, /* (212) case_operand ::= expr */
- 263, /* (213) case_operand ::= */
- 250, /* (214) exprlist ::= */
- 241, /* (215) nexprlist ::= nexprlist COMMA expr */
- 241, /* (216) nexprlist ::= expr */
- 262, /* (217) paren_exprlist ::= */
- 262, /* (218) paren_exprlist ::= LP exprlist RP */
- 181, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
- 266, /* (220) uniqueflag ::= UNIQUE */
- 266, /* (221) uniqueflag ::= */
- 210, /* (222) eidlist_opt ::= */
- 210, /* (223) eidlist_opt ::= LP eidlist RP */
- 220, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
- 220, /* (225) eidlist ::= nm collate sortorder */
- 267, /* (226) collate ::= */
- 267, /* (227) collate ::= COLLATE ID|STRING */
- 181, /* (228) cmd ::= DROP INDEX ifexists fullname */
- 181, /* (229) cmd ::= VACUUM vinto */
- 181, /* (230) cmd ::= VACUUM nm vinto */
- 268, /* (231) vinto ::= INTO expr */
- 268, /* (232) vinto ::= */
- 181, /* (233) cmd ::= PRAGMA nm dbnm */
- 181, /* (234) cmd ::= PRAGMA nm dbnm EQ nmnum */
- 181, /* (235) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- 181, /* (236) cmd ::= PRAGMA nm dbnm EQ minus_num */
- 181, /* (237) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- 201, /* (238) plus_num ::= PLUS INTEGER|FLOAT */
- 202, /* (239) minus_num ::= MINUS INTEGER|FLOAT */
- 181, /* (240) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- 270, /* (241) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- 272, /* (242) trigger_time ::= BEFORE|AFTER */
- 272, /* (243) trigger_time ::= INSTEAD OF */
- 272, /* (244) trigger_time ::= */
- 273, /* (245) trigger_event ::= DELETE|INSERT */
- 273, /* (246) trigger_event ::= UPDATE */
- 273, /* (247) trigger_event ::= UPDATE OF idlist */
- 275, /* (248) when_clause ::= */
- 275, /* (249) when_clause ::= WHEN expr */
- 271, /* (250) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- 271, /* (251) trigger_cmd_list ::= trigger_cmd SEMI */
- 277, /* (252) trnm ::= nm DOT nm */
- 278, /* (253) tridxby ::= INDEXED BY nm */
- 278, /* (254) tridxby ::= NOT INDEXED */
- 276, /* (255) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
- 276, /* (256) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- 276, /* (257) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- 276, /* (258) trigger_cmd ::= scanpt select scanpt */
- 206, /* (259) expr ::= RAISE LP IGNORE RP */
- 206, /* (260) expr ::= RAISE LP raisetype COMMA nm RP */
- 224, /* (261) raisetype ::= ROLLBACK */
- 224, /* (262) raisetype ::= ABORT */
- 224, /* (263) raisetype ::= FAIL */
- 181, /* (264) cmd ::= DROP TRIGGER ifexists fullname */
- 181, /* (265) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- 181, /* (266) cmd ::= DETACH database_kw_opt expr */
- 280, /* (267) key_opt ::= */
- 280, /* (268) key_opt ::= KEY expr */
- 181, /* (269) cmd ::= REINDEX */
- 181, /* (270) cmd ::= REINDEX nm dbnm */
- 181, /* (271) cmd ::= ANALYZE */
- 181, /* (272) cmd ::= ANALYZE nm dbnm */
- 181, /* (273) cmd ::= ALTER TABLE fullname RENAME TO nm */
- 181, /* (274) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- 281, /* (275) add_column_fullname ::= fullname */
- 181, /* (276) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- 181, /* (277) cmd ::= create_vtab */
- 181, /* (278) cmd ::= create_vtab LP vtabarglist RP */
- 283, /* (279) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- 285, /* (280) vtabarg ::= */
- 286, /* (281) vtabargtoken ::= ANY */
- 286, /* (282) vtabargtoken ::= lp anylist RP */
- 287, /* (283) lp ::= LP */
- 253, /* (284) with ::= WITH wqlist */
- 253, /* (285) with ::= WITH RECURSIVE wqlist */
- 229, /* (286) wqlist ::= nm eidlist_opt AS LP select RP */
- 229, /* (287) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
- 289, /* (288) windowdefn_list ::= windowdefn */
- 289, /* (289) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- 290, /* (290) windowdefn ::= nm AS LP window RP */
- 291, /* (291) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
- 291, /* (292) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
- 291, /* (293) window ::= ORDER BY sortlist frame_opt */
- 291, /* (294) window ::= nm ORDER BY sortlist frame_opt */
- 291, /* (295) window ::= frame_opt */
- 291, /* (296) window ::= nm frame_opt */
- 292, /* (297) frame_opt ::= */
- 292, /* (298) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
- 292, /* (299) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
- 295, /* (300) range_or_rows ::= RANGE|ROWS|GROUPS */
- 297, /* (301) frame_bound_s ::= frame_bound */
- 297, /* (302) frame_bound_s ::= UNBOUNDED PRECEDING */
- 298, /* (303) frame_bound_e ::= frame_bound */
- 298, /* (304) frame_bound_e ::= UNBOUNDED FOLLOWING */
- 296, /* (305) frame_bound ::= expr PRECEDING|FOLLOWING */
- 296, /* (306) frame_bound ::= CURRENT ROW */
- 299, /* (307) frame_exclude_opt ::= */
- 299, /* (308) frame_exclude_opt ::= EXCLUDE frame_exclude */
- 300, /* (309) frame_exclude ::= NO OTHERS */
- 300, /* (310) frame_exclude ::= CURRENT ROW */
- 300, /* (311) frame_exclude ::= GROUP|TIES */
- 239, /* (312) window_clause ::= WINDOW windowdefn_list */
- 258, /* (313) over_clause ::= filter_opt OVER LP window RP */
- 258, /* (314) over_clause ::= filter_opt OVER nm */
- 294, /* (315) filter_opt ::= */
- 294, /* (316) filter_opt ::= FILTER LP WHERE expr RP */
- 176, /* (317) input ::= cmdlist */
- 177, /* (318) cmdlist ::= cmdlist ecmd */
- 177, /* (319) cmdlist ::= ecmd */
- 178, /* (320) ecmd ::= SEMI */
- 178, /* (321) ecmd ::= cmdx SEMI */
- 178, /* (322) ecmd ::= explain cmdx */
- 183, /* (323) trans_opt ::= */
- 183, /* (324) trans_opt ::= TRANSACTION */
- 183, /* (325) trans_opt ::= TRANSACTION nm */
- 185, /* (326) savepoint_opt ::= SAVEPOINT */
- 185, /* (327) savepoint_opt ::= */
- 181, /* (328) cmd ::= create_table create_table_args */
- 192, /* (329) columnlist ::= columnlist COMMA columnname carglist */
- 192, /* (330) columnlist ::= columnname carglist */
- 184, /* (331) nm ::= ID|INDEXED */
- 184, /* (332) nm ::= STRING */
- 184, /* (333) nm ::= JOIN_KW */
- 198, /* (334) typetoken ::= typename */
- 199, /* (335) typename ::= ID|STRING */
- 200, /* (336) signed ::= plus_num */
- 200, /* (337) signed ::= minus_num */
- 197, /* (338) carglist ::= carglist ccons */
- 197, /* (339) carglist ::= */
- 204, /* (340) ccons ::= NULL onconf */
- 193, /* (341) conslist_opt ::= COMMA conslist */
- 216, /* (342) conslist ::= conslist tconscomma tcons */
- 216, /* (343) conslist ::= tcons */
- 217, /* (344) tconscomma ::= */
- 221, /* (345) defer_subclause_opt ::= defer_subclause */
- 223, /* (346) resolvetype ::= raisetype */
- 227, /* (347) selectnowith ::= oneselect */
- 228, /* (348) oneselect ::= values */
- 242, /* (349) sclp ::= selcollist COMMA */
- 243, /* (350) as ::= ID|STRING */
- 206, /* (351) expr ::= term */
- 259, /* (352) likeop ::= LIKE_KW|MATCH */
- 250, /* (353) exprlist ::= nexprlist */
- 269, /* (354) nmnum ::= plus_num */
- 269, /* (355) nmnum ::= nm */
- 269, /* (356) nmnum ::= ON */
- 269, /* (357) nmnum ::= DELETE */
- 269, /* (358) nmnum ::= DEFAULT */
- 201, /* (359) plus_num ::= INTEGER|FLOAT */
- 274, /* (360) foreach_clause ::= */
- 274, /* (361) foreach_clause ::= FOR EACH ROW */
- 277, /* (362) trnm ::= nm */
- 278, /* (363) tridxby ::= */
- 279, /* (364) database_kw_opt ::= DATABASE */
- 279, /* (365) database_kw_opt ::= */
- 282, /* (366) kwcolumn_opt ::= */
- 282, /* (367) kwcolumn_opt ::= COLUMNKW */
- 284, /* (368) vtabarglist ::= vtabarg */
- 284, /* (369) vtabarglist ::= vtabarglist COMMA vtabarg */
- 285, /* (370) vtabarg ::= vtabarg vtabargtoken */
- 288, /* (371) anylist ::= */
- 288, /* (372) anylist ::= anylist LP anylist RP */
- 288, /* (373) anylist ::= anylist ANY */
- 253, /* (374) with ::= */
+ 204, /* (29) scantok ::= */
+ 205, /* (30) ccons ::= CONSTRAINT nm */
+ 205, /* (31) ccons ::= DEFAULT scantok term */
+ 205, /* (32) ccons ::= DEFAULT LP expr RP */
+ 205, /* (33) ccons ::= DEFAULT PLUS scantok term */
+ 205, /* (34) ccons ::= DEFAULT MINUS scantok term */
+ 205, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */
+ 205, /* (36) ccons ::= NOT NULL onconf */
+ 205, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ 205, /* (38) ccons ::= UNIQUE onconf */
+ 205, /* (39) ccons ::= CHECK LP expr RP */
+ 205, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */
+ 205, /* (41) ccons ::= defer_subclause */
+ 205, /* (42) ccons ::= COLLATE ID|STRING */
+ 210, /* (43) autoinc ::= */
+ 210, /* (44) autoinc ::= AUTOINCR */
+ 212, /* (45) refargs ::= */
+ 212, /* (46) refargs ::= refargs refarg */
+ 214, /* (47) refarg ::= MATCH nm */
+ 214, /* (48) refarg ::= ON INSERT refact */
+ 214, /* (49) refarg ::= ON DELETE refact */
+ 214, /* (50) refarg ::= ON UPDATE refact */
+ 215, /* (51) refact ::= SET NULL */
+ 215, /* (52) refact ::= SET DEFAULT */
+ 215, /* (53) refact ::= CASCADE */
+ 215, /* (54) refact ::= RESTRICT */
+ 215, /* (55) refact ::= NO ACTION */
+ 213, /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ 213, /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 216, /* (58) init_deferred_pred_opt ::= */
+ 216, /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ 216, /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 193, /* (61) conslist_opt ::= */
+ 218, /* (62) tconscomma ::= COMMA */
+ 219, /* (63) tcons ::= CONSTRAINT nm */
+ 219, /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ 219, /* (65) tcons ::= UNIQUE LP sortlist RP onconf */
+ 219, /* (66) tcons ::= CHECK LP expr RP onconf */
+ 219, /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 222, /* (68) defer_subclause_opt ::= */
+ 208, /* (69) onconf ::= */
+ 208, /* (70) onconf ::= ON CONFLICT resolvetype */
+ 223, /* (71) orconf ::= */
+ 223, /* (72) orconf ::= OR resolvetype */
+ 224, /* (73) resolvetype ::= IGNORE */
+ 224, /* (74) resolvetype ::= REPLACE */
+ 181, /* (75) cmd ::= DROP TABLE ifexists fullname */
+ 226, /* (76) ifexists ::= IF EXISTS */
+ 226, /* (77) ifexists ::= */
+ 181, /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ 181, /* (79) cmd ::= DROP VIEW ifexists fullname */
+ 181, /* (80) cmd ::= select */
+ 195, /* (81) select ::= WITH wqlist selectnowith */
+ 195, /* (82) select ::= WITH RECURSIVE wqlist selectnowith */
+ 195, /* (83) select ::= selectnowith */
+ 228, /* (84) selectnowith ::= selectnowith multiselect_op oneselect */
+ 231, /* (85) multiselect_op ::= UNION */
+ 231, /* (86) multiselect_op ::= UNION ALL */
+ 231, /* (87) multiselect_op ::= EXCEPT|INTERSECT */
+ 229, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ 229, /* (89) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ 241, /* (90) values ::= VALUES LP nexprlist RP */
+ 241, /* (91) values ::= values COMMA LP nexprlist RP */
+ 232, /* (92) distinct ::= DISTINCT */
+ 232, /* (93) distinct ::= ALL */
+ 232, /* (94) distinct ::= */
+ 243, /* (95) sclp ::= */
+ 233, /* (96) selcollist ::= sclp scanpt expr scanpt as */
+ 233, /* (97) selcollist ::= sclp scanpt STAR */
+ 233, /* (98) selcollist ::= sclp scanpt nm DOT STAR */
+ 244, /* (99) as ::= AS nm */
+ 244, /* (100) as ::= */
+ 234, /* (101) from ::= */
+ 234, /* (102) from ::= FROM seltablist */
+ 246, /* (103) stl_prefix ::= seltablist joinop */
+ 246, /* (104) stl_prefix ::= */
+ 245, /* (105) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ 245, /* (106) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ 245, /* (107) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ 245, /* (108) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ 191, /* (109) dbnm ::= */
+ 191, /* (110) dbnm ::= DOT nm */
+ 227, /* (111) fullname ::= nm */
+ 227, /* (112) fullname ::= nm DOT nm */
+ 252, /* (113) xfullname ::= nm */
+ 252, /* (114) xfullname ::= nm DOT nm */
+ 252, /* (115) xfullname ::= nm DOT nm AS nm */
+ 252, /* (116) xfullname ::= nm AS nm */
+ 247, /* (117) joinop ::= COMMA|JOIN */
+ 247, /* (118) joinop ::= JOIN_KW JOIN */
+ 247, /* (119) joinop ::= JOIN_KW nm JOIN */
+ 247, /* (120) joinop ::= JOIN_KW nm nm JOIN */
+ 249, /* (121) on_opt ::= ON expr */
+ 249, /* (122) on_opt ::= */
+ 248, /* (123) indexed_opt ::= */
+ 248, /* (124) indexed_opt ::= INDEXED BY nm */
+ 248, /* (125) indexed_opt ::= NOT INDEXED */
+ 250, /* (126) using_opt ::= USING LP idlist RP */
+ 250, /* (127) using_opt ::= */
+ 238, /* (128) orderby_opt ::= */
+ 238, /* (129) orderby_opt ::= ORDER BY sortlist */
+ 220, /* (130) sortlist ::= sortlist COMMA expr sortorder */
+ 220, /* (131) sortlist ::= expr sortorder */
+ 209, /* (132) sortorder ::= ASC */
+ 209, /* (133) sortorder ::= DESC */
+ 209, /* (134) sortorder ::= */
+ 236, /* (135) groupby_opt ::= */
+ 236, /* (136) groupby_opt ::= GROUP BY nexprlist */
+ 237, /* (137) having_opt ::= */
+ 237, /* (138) having_opt ::= HAVING expr */
+ 239, /* (139) limit_opt ::= */
+ 239, /* (140) limit_opt ::= LIMIT expr */
+ 239, /* (141) limit_opt ::= LIMIT expr OFFSET expr */
+ 239, /* (142) limit_opt ::= LIMIT expr COMMA expr */
+ 181, /* (143) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ 235, /* (144) where_opt ::= */
+ 235, /* (145) where_opt ::= WHERE expr */
+ 181, /* (146) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ 255, /* (147) setlist ::= setlist COMMA nm EQ expr */
+ 255, /* (148) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ 255, /* (149) setlist ::= nm EQ expr */
+ 255, /* (150) setlist ::= LP idlist RP EQ expr */
+ 181, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ 181, /* (152) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ 258, /* (153) upsert ::= */
+ 258, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ 258, /* (155) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ 258, /* (156) upsert ::= ON CONFLICT DO NOTHING */
+ 256, /* (157) insert_cmd ::= INSERT orconf */
+ 256, /* (158) insert_cmd ::= REPLACE */
+ 257, /* (159) idlist_opt ::= */
+ 257, /* (160) idlist_opt ::= LP idlist RP */
+ 253, /* (161) idlist ::= idlist COMMA nm */
+ 253, /* (162) idlist ::= nm */
+ 207, /* (163) expr ::= LP expr RP */
+ 207, /* (164) expr ::= ID|INDEXED */
+ 207, /* (165) expr ::= JOIN_KW */
+ 207, /* (166) expr ::= nm DOT nm */
+ 207, /* (167) expr ::= nm DOT nm DOT nm */
+ 206, /* (168) term ::= NULL|FLOAT|BLOB */
+ 206, /* (169) term ::= STRING */
+ 206, /* (170) term ::= INTEGER */
+ 207, /* (171) expr ::= VARIABLE */
+ 207, /* (172) expr ::= expr COLLATE ID|STRING */
+ 207, /* (173) expr ::= CAST LP expr AS typetoken RP */
+ 207, /* (174) expr ::= ID|INDEXED LP distinct exprlist RP */
+ 207, /* (175) expr ::= ID|INDEXED LP STAR RP */
+ 207, /* (176) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ 207, /* (177) expr ::= ID|INDEXED LP STAR RP over_clause */
+ 206, /* (178) term ::= CTIME_KW */
+ 207, /* (179) expr ::= LP nexprlist COMMA expr RP */
+ 207, /* (180) expr ::= expr AND expr */
+ 207, /* (181) expr ::= expr OR expr */
+ 207, /* (182) expr ::= expr LT|GT|GE|LE expr */
+ 207, /* (183) expr ::= expr EQ|NE expr */
+ 207, /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ 207, /* (185) expr ::= expr PLUS|MINUS expr */
+ 207, /* (186) expr ::= expr STAR|SLASH|REM expr */
+ 207, /* (187) expr ::= expr CONCAT expr */
+ 260, /* (188) likeop ::= NOT LIKE_KW|MATCH */
+ 207, /* (189) expr ::= expr likeop expr */
+ 207, /* (190) expr ::= expr likeop expr ESCAPE expr */
+ 207, /* (191) expr ::= expr ISNULL|NOTNULL */
+ 207, /* (192) expr ::= expr NOT NULL */
+ 207, /* (193) expr ::= expr IS expr */
+ 207, /* (194) expr ::= expr IS NOT expr */
+ 207, /* (195) expr ::= NOT expr */
+ 207, /* (196) expr ::= BITNOT expr */
+ 207, /* (197) expr ::= PLUS|MINUS expr */
+ 261, /* (198) between_op ::= BETWEEN */
+ 261, /* (199) between_op ::= NOT BETWEEN */
+ 207, /* (200) expr ::= expr between_op expr AND expr */
+ 262, /* (201) in_op ::= IN */
+ 262, /* (202) in_op ::= NOT IN */
+ 207, /* (203) expr ::= expr in_op LP exprlist RP */
+ 207, /* (204) expr ::= LP select RP */
+ 207, /* (205) expr ::= expr in_op LP select RP */
+ 207, /* (206) expr ::= expr in_op nm dbnm paren_exprlist */
+ 207, /* (207) expr ::= EXISTS LP select RP */
+ 207, /* (208) expr ::= CASE case_operand case_exprlist case_else END */
+ 265, /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ 265, /* (210) case_exprlist ::= WHEN expr THEN expr */
+ 266, /* (211) case_else ::= ELSE expr */
+ 266, /* (212) case_else ::= */
+ 264, /* (213) case_operand ::= expr */
+ 264, /* (214) case_operand ::= */
+ 251, /* (215) exprlist ::= */
+ 242, /* (216) nexprlist ::= nexprlist COMMA expr */
+ 242, /* (217) nexprlist ::= expr */
+ 263, /* (218) paren_exprlist ::= */
+ 263, /* (219) paren_exprlist ::= LP exprlist RP */
+ 181, /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ 267, /* (221) uniqueflag ::= UNIQUE */
+ 267, /* (222) uniqueflag ::= */
+ 211, /* (223) eidlist_opt ::= */
+ 211, /* (224) eidlist_opt ::= LP eidlist RP */
+ 221, /* (225) eidlist ::= eidlist COMMA nm collate sortorder */
+ 221, /* (226) eidlist ::= nm collate sortorder */
+ 268, /* (227) collate ::= */
+ 268, /* (228) collate ::= COLLATE ID|STRING */
+ 181, /* (229) cmd ::= DROP INDEX ifexists fullname */
+ 181, /* (230) cmd ::= VACUUM vinto */
+ 181, /* (231) cmd ::= VACUUM nm vinto */
+ 269, /* (232) vinto ::= INTO expr */
+ 269, /* (233) vinto ::= */
+ 181, /* (234) cmd ::= PRAGMA nm dbnm */
+ 181, /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ 181, /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ 181, /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ 181, /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ 201, /* (239) plus_num ::= PLUS INTEGER|FLOAT */
+ 202, /* (240) minus_num ::= MINUS INTEGER|FLOAT */
+ 181, /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ 271, /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ 273, /* (243) trigger_time ::= BEFORE|AFTER */
+ 273, /* (244) trigger_time ::= INSTEAD OF */
+ 273, /* (245) trigger_time ::= */
+ 274, /* (246) trigger_event ::= DELETE|INSERT */
+ 274, /* (247) trigger_event ::= UPDATE */
+ 274, /* (248) trigger_event ::= UPDATE OF idlist */
+ 276, /* (249) when_clause ::= */
+ 276, /* (250) when_clause ::= WHEN expr */
+ 272, /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ 272, /* (252) trigger_cmd_list ::= trigger_cmd SEMI */
+ 278, /* (253) trnm ::= nm DOT nm */
+ 279, /* (254) tridxby ::= INDEXED BY nm */
+ 279, /* (255) tridxby ::= NOT INDEXED */
+ 277, /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ 277, /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ 277, /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ 277, /* (259) trigger_cmd ::= scanpt select scanpt */
+ 207, /* (260) expr ::= RAISE LP IGNORE RP */
+ 207, /* (261) expr ::= RAISE LP raisetype COMMA nm RP */
+ 225, /* (262) raisetype ::= ROLLBACK */
+ 225, /* (263) raisetype ::= ABORT */
+ 225, /* (264) raisetype ::= FAIL */
+ 181, /* (265) cmd ::= DROP TRIGGER ifexists fullname */
+ 181, /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ 181, /* (267) cmd ::= DETACH database_kw_opt expr */
+ 281, /* (268) key_opt ::= */
+ 281, /* (269) key_opt ::= KEY expr */
+ 181, /* (270) cmd ::= REINDEX */
+ 181, /* (271) cmd ::= REINDEX nm dbnm */
+ 181, /* (272) cmd ::= ANALYZE */
+ 181, /* (273) cmd ::= ANALYZE nm dbnm */
+ 181, /* (274) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ 181, /* (275) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ 282, /* (276) add_column_fullname ::= fullname */
+ 181, /* (277) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ 181, /* (278) cmd ::= create_vtab */
+ 181, /* (279) cmd ::= create_vtab LP vtabarglist RP */
+ 284, /* (280) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 286, /* (281) vtabarg ::= */
+ 287, /* (282) vtabargtoken ::= ANY */
+ 287, /* (283) vtabargtoken ::= lp anylist RP */
+ 288, /* (284) lp ::= LP */
+ 254, /* (285) with ::= WITH wqlist */
+ 254, /* (286) with ::= WITH RECURSIVE wqlist */
+ 230, /* (287) wqlist ::= nm eidlist_opt AS LP select RP */
+ 230, /* (288) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ 290, /* (289) windowdefn_list ::= windowdefn */
+ 290, /* (290) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ 291, /* (291) windowdefn ::= nm AS LP window RP */
+ 292, /* (292) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ 292, /* (293) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ 292, /* (294) window ::= ORDER BY sortlist frame_opt */
+ 292, /* (295) window ::= nm ORDER BY sortlist frame_opt */
+ 292, /* (296) window ::= frame_opt */
+ 292, /* (297) window ::= nm frame_opt */
+ 293, /* (298) frame_opt ::= */
+ 293, /* (299) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ 293, /* (300) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ 296, /* (301) range_or_rows ::= RANGE|ROWS|GROUPS */
+ 298, /* (302) frame_bound_s ::= frame_bound */
+ 298, /* (303) frame_bound_s ::= UNBOUNDED PRECEDING */
+ 299, /* (304) frame_bound_e ::= frame_bound */
+ 299, /* (305) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ 297, /* (306) frame_bound ::= expr PRECEDING|FOLLOWING */
+ 297, /* (307) frame_bound ::= CURRENT ROW */
+ 300, /* (308) frame_exclude_opt ::= */
+ 300, /* (309) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ 301, /* (310) frame_exclude ::= NO OTHERS */
+ 301, /* (311) frame_exclude ::= CURRENT ROW */
+ 301, /* (312) frame_exclude ::= GROUP|TIES */
+ 240, /* (313) window_clause ::= WINDOW windowdefn_list */
+ 259, /* (314) over_clause ::= filter_opt OVER LP window RP */
+ 259, /* (315) over_clause ::= filter_opt OVER nm */
+ 295, /* (316) filter_opt ::= */
+ 295, /* (317) filter_opt ::= FILTER LP WHERE expr RP */
+ 176, /* (318) input ::= cmdlist */
+ 177, /* (319) cmdlist ::= cmdlist ecmd */
+ 177, /* (320) cmdlist ::= ecmd */
+ 178, /* (321) ecmd ::= SEMI */
+ 178, /* (322) ecmd ::= cmdx SEMI */
+ 178, /* (323) ecmd ::= explain cmdx */
+ 183, /* (324) trans_opt ::= */
+ 183, /* (325) trans_opt ::= TRANSACTION */
+ 183, /* (326) trans_opt ::= TRANSACTION nm */
+ 185, /* (327) savepoint_opt ::= SAVEPOINT */
+ 185, /* (328) savepoint_opt ::= */
+ 181, /* (329) cmd ::= create_table create_table_args */
+ 192, /* (330) columnlist ::= columnlist COMMA columnname carglist */
+ 192, /* (331) columnlist ::= columnname carglist */
+ 184, /* (332) nm ::= ID|INDEXED */
+ 184, /* (333) nm ::= STRING */
+ 184, /* (334) nm ::= JOIN_KW */
+ 198, /* (335) typetoken ::= typename */
+ 199, /* (336) typename ::= ID|STRING */
+ 200, /* (337) signed ::= plus_num */
+ 200, /* (338) signed ::= minus_num */
+ 197, /* (339) carglist ::= carglist ccons */
+ 197, /* (340) carglist ::= */
+ 205, /* (341) ccons ::= NULL onconf */
+ 193, /* (342) conslist_opt ::= COMMA conslist */
+ 217, /* (343) conslist ::= conslist tconscomma tcons */
+ 217, /* (344) conslist ::= tcons */
+ 218, /* (345) tconscomma ::= */
+ 222, /* (346) defer_subclause_opt ::= defer_subclause */
+ 224, /* (347) resolvetype ::= raisetype */
+ 228, /* (348) selectnowith ::= oneselect */
+ 229, /* (349) oneselect ::= values */
+ 243, /* (350) sclp ::= selcollist COMMA */
+ 244, /* (351) as ::= ID|STRING */
+ 207, /* (352) expr ::= term */
+ 260, /* (353) likeop ::= LIKE_KW|MATCH */
+ 251, /* (354) exprlist ::= nexprlist */
+ 270, /* (355) nmnum ::= plus_num */
+ 270, /* (356) nmnum ::= nm */
+ 270, /* (357) nmnum ::= ON */
+ 270, /* (358) nmnum ::= DELETE */
+ 270, /* (359) nmnum ::= DEFAULT */
+ 201, /* (360) plus_num ::= INTEGER|FLOAT */
+ 275, /* (361) foreach_clause ::= */
+ 275, /* (362) foreach_clause ::= FOR EACH ROW */
+ 278, /* (363) trnm ::= nm */
+ 279, /* (364) tridxby ::= */
+ 280, /* (365) database_kw_opt ::= DATABASE */
+ 280, /* (366) database_kw_opt ::= */
+ 283, /* (367) kwcolumn_opt ::= */
+ 283, /* (368) kwcolumn_opt ::= COLUMNKW */
+ 285, /* (369) vtabarglist ::= vtabarg */
+ 285, /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */
+ 286, /* (371) vtabarg ::= vtabarg vtabargtoken */
+ 289, /* (372) anylist ::= */
+ 289, /* (373) anylist ::= anylist LP anylist RP */
+ 289, /* (374) anylist ::= anylist ANY */
+ 254, /* (375) with ::= */
};
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
@@ -150879,352 +151459,353 @@ static const signed char yyRuleInfoNRhs[] = {
-6, /* (26) typetoken ::= typename LP signed COMMA signed RP */
-2, /* (27) typename ::= typename ID|STRING */
0, /* (28) scanpt ::= */
- -2, /* (29) ccons ::= CONSTRAINT nm */
- -4, /* (30) ccons ::= DEFAULT scanpt term scanpt */
- -4, /* (31) ccons ::= DEFAULT LP expr RP */
- -4, /* (32) ccons ::= DEFAULT PLUS term scanpt */
- -4, /* (33) ccons ::= DEFAULT MINUS term scanpt */
- -3, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
- -3, /* (35) ccons ::= NOT NULL onconf */
- -5, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
- -2, /* (37) ccons ::= UNIQUE onconf */
- -4, /* (38) ccons ::= CHECK LP expr RP */
- -4, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
- -1, /* (40) ccons ::= defer_subclause */
- -2, /* (41) ccons ::= COLLATE ID|STRING */
- 0, /* (42) autoinc ::= */
- -1, /* (43) autoinc ::= AUTOINCR */
- 0, /* (44) refargs ::= */
- -2, /* (45) refargs ::= refargs refarg */
- -2, /* (46) refarg ::= MATCH nm */
- -3, /* (47) refarg ::= ON INSERT refact */
- -3, /* (48) refarg ::= ON DELETE refact */
- -3, /* (49) refarg ::= ON UPDATE refact */
- -2, /* (50) refact ::= SET NULL */
- -2, /* (51) refact ::= SET DEFAULT */
- -1, /* (52) refact ::= CASCADE */
- -1, /* (53) refact ::= RESTRICT */
- -2, /* (54) refact ::= NO ACTION */
- -3, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- -2, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- 0, /* (57) init_deferred_pred_opt ::= */
- -2, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
- -2, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- 0, /* (60) conslist_opt ::= */
- -1, /* (61) tconscomma ::= COMMA */
- -2, /* (62) tcons ::= CONSTRAINT nm */
- -7, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
- -5, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
- -5, /* (65) tcons ::= CHECK LP expr RP onconf */
- -10, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
- 0, /* (67) defer_subclause_opt ::= */
- 0, /* (68) onconf ::= */
- -3, /* (69) onconf ::= ON CONFLICT resolvetype */
- 0, /* (70) orconf ::= */
- -2, /* (71) orconf ::= OR resolvetype */
- -1, /* (72) resolvetype ::= IGNORE */
- -1, /* (73) resolvetype ::= REPLACE */
- -4, /* (74) cmd ::= DROP TABLE ifexists fullname */
- -2, /* (75) ifexists ::= IF EXISTS */
- 0, /* (76) ifexists ::= */
- -9, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
- -4, /* (78) cmd ::= DROP VIEW ifexists fullname */
- -1, /* (79) cmd ::= select */
- -3, /* (80) select ::= WITH wqlist selectnowith */
- -4, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
- -1, /* (82) select ::= selectnowith */
- -3, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
- -1, /* (84) multiselect_op ::= UNION */
- -2, /* (85) multiselect_op ::= UNION ALL */
- -1, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
- -9, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
- -10, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
- -4, /* (89) values ::= VALUES LP nexprlist RP */
- -5, /* (90) values ::= values COMMA LP nexprlist RP */
- -1, /* (91) distinct ::= DISTINCT */
- -1, /* (92) distinct ::= ALL */
- 0, /* (93) distinct ::= */
- 0, /* (94) sclp ::= */
- -5, /* (95) selcollist ::= sclp scanpt expr scanpt as */
- -3, /* (96) selcollist ::= sclp scanpt STAR */
- -5, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
- -2, /* (98) as ::= AS nm */
- 0, /* (99) as ::= */
- 0, /* (100) from ::= */
- -2, /* (101) from ::= FROM seltablist */
- -2, /* (102) stl_prefix ::= seltablist joinop */
- 0, /* (103) stl_prefix ::= */
- -7, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
- -9, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
- -7, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
- -7, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
- 0, /* (108) dbnm ::= */
- -2, /* (109) dbnm ::= DOT nm */
- -1, /* (110) fullname ::= nm */
- -3, /* (111) fullname ::= nm DOT nm */
- -1, /* (112) xfullname ::= nm */
- -3, /* (113) xfullname ::= nm DOT nm */
- -5, /* (114) xfullname ::= nm DOT nm AS nm */
- -3, /* (115) xfullname ::= nm AS nm */
- -1, /* (116) joinop ::= COMMA|JOIN */
- -2, /* (117) joinop ::= JOIN_KW JOIN */
- -3, /* (118) joinop ::= JOIN_KW nm JOIN */
- -4, /* (119) joinop ::= JOIN_KW nm nm JOIN */
- -2, /* (120) on_opt ::= ON expr */
- 0, /* (121) on_opt ::= */
- 0, /* (122) indexed_opt ::= */
- -3, /* (123) indexed_opt ::= INDEXED BY nm */
- -2, /* (124) indexed_opt ::= NOT INDEXED */
- -4, /* (125) using_opt ::= USING LP idlist RP */
- 0, /* (126) using_opt ::= */
- 0, /* (127) orderby_opt ::= */
- -3, /* (128) orderby_opt ::= ORDER BY sortlist */
- -4, /* (129) sortlist ::= sortlist COMMA expr sortorder */
- -2, /* (130) sortlist ::= expr sortorder */
- -1, /* (131) sortorder ::= ASC */
- -1, /* (132) sortorder ::= DESC */
- 0, /* (133) sortorder ::= */
- 0, /* (134) groupby_opt ::= */
- -3, /* (135) groupby_opt ::= GROUP BY nexprlist */
- 0, /* (136) having_opt ::= */
- -2, /* (137) having_opt ::= HAVING expr */
- 0, /* (138) limit_opt ::= */
- -2, /* (139) limit_opt ::= LIMIT expr */
- -4, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
- -4, /* (141) limit_opt ::= LIMIT expr COMMA expr */
- -6, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
- 0, /* (143) where_opt ::= */
- -2, /* (144) where_opt ::= WHERE expr */
- -8, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
- -5, /* (146) setlist ::= setlist COMMA nm EQ expr */
- -7, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
- -3, /* (148) setlist ::= nm EQ expr */
- -5, /* (149) setlist ::= LP idlist RP EQ expr */
- -7, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- -7, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
- 0, /* (152) upsert ::= */
- -11, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
- -8, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
- -4, /* (155) upsert ::= ON CONFLICT DO NOTHING */
- -2, /* (156) insert_cmd ::= INSERT orconf */
- -1, /* (157) insert_cmd ::= REPLACE */
- 0, /* (158) idlist_opt ::= */
- -3, /* (159) idlist_opt ::= LP idlist RP */
- -3, /* (160) idlist ::= idlist COMMA nm */
- -1, /* (161) idlist ::= nm */
- -3, /* (162) expr ::= LP expr RP */
- -1, /* (163) expr ::= ID|INDEXED */
- -1, /* (164) expr ::= JOIN_KW */
- -3, /* (165) expr ::= nm DOT nm */
- -5, /* (166) expr ::= nm DOT nm DOT nm */
- -1, /* (167) term ::= NULL|FLOAT|BLOB */
- -1, /* (168) term ::= STRING */
- -1, /* (169) term ::= INTEGER */
- -1, /* (170) expr ::= VARIABLE */
- -3, /* (171) expr ::= expr COLLATE ID|STRING */
- -6, /* (172) expr ::= CAST LP expr AS typetoken RP */
- -5, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
- -4, /* (174) expr ::= ID|INDEXED LP STAR RP */
- -6, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
- -5, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
- -1, /* (177) term ::= CTIME_KW */
- -5, /* (178) expr ::= LP nexprlist COMMA expr RP */
- -3, /* (179) expr ::= expr AND expr */
- -3, /* (180) expr ::= expr OR expr */
- -3, /* (181) expr ::= expr LT|GT|GE|LE expr */
- -3, /* (182) expr ::= expr EQ|NE expr */
- -3, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- -3, /* (184) expr ::= expr PLUS|MINUS expr */
- -3, /* (185) expr ::= expr STAR|SLASH|REM expr */
- -3, /* (186) expr ::= expr CONCAT expr */
- -2, /* (187) likeop ::= NOT LIKE_KW|MATCH */
- -3, /* (188) expr ::= expr likeop expr */
- -5, /* (189) expr ::= expr likeop expr ESCAPE expr */
- -2, /* (190) expr ::= expr ISNULL|NOTNULL */
- -3, /* (191) expr ::= expr NOT NULL */
- -3, /* (192) expr ::= expr IS expr */
- -4, /* (193) expr ::= expr IS NOT expr */
- -2, /* (194) expr ::= NOT expr */
- -2, /* (195) expr ::= BITNOT expr */
- -2, /* (196) expr ::= PLUS|MINUS expr */
- -1, /* (197) between_op ::= BETWEEN */
- -2, /* (198) between_op ::= NOT BETWEEN */
- -5, /* (199) expr ::= expr between_op expr AND expr */
- -1, /* (200) in_op ::= IN */
- -2, /* (201) in_op ::= NOT IN */
- -5, /* (202) expr ::= expr in_op LP exprlist RP */
- -3, /* (203) expr ::= LP select RP */
- -5, /* (204) expr ::= expr in_op LP select RP */
- -5, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
- -4, /* (206) expr ::= EXISTS LP select RP */
- -5, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
- -5, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- -4, /* (209) case_exprlist ::= WHEN expr THEN expr */
- -2, /* (210) case_else ::= ELSE expr */
- 0, /* (211) case_else ::= */
- -1, /* (212) case_operand ::= expr */
- 0, /* (213) case_operand ::= */
- 0, /* (214) exprlist ::= */
- -3, /* (215) nexprlist ::= nexprlist COMMA expr */
- -1, /* (216) nexprlist ::= expr */
- 0, /* (217) paren_exprlist ::= */
- -3, /* (218) paren_exprlist ::= LP exprlist RP */
- -12, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
- -1, /* (220) uniqueflag ::= UNIQUE */
- 0, /* (221) uniqueflag ::= */
- 0, /* (222) eidlist_opt ::= */
- -3, /* (223) eidlist_opt ::= LP eidlist RP */
- -5, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
- -3, /* (225) eidlist ::= nm collate sortorder */
- 0, /* (226) collate ::= */
- -2, /* (227) collate ::= COLLATE ID|STRING */
- -4, /* (228) cmd ::= DROP INDEX ifexists fullname */
- -2, /* (229) cmd ::= VACUUM vinto */
- -3, /* (230) cmd ::= VACUUM nm vinto */
- -2, /* (231) vinto ::= INTO expr */
- 0, /* (232) vinto ::= */
- -3, /* (233) cmd ::= PRAGMA nm dbnm */
- -5, /* (234) cmd ::= PRAGMA nm dbnm EQ nmnum */
- -6, /* (235) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- -5, /* (236) cmd ::= PRAGMA nm dbnm EQ minus_num */
- -6, /* (237) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- -2, /* (238) plus_num ::= PLUS INTEGER|FLOAT */
- -2, /* (239) minus_num ::= MINUS INTEGER|FLOAT */
- -5, /* (240) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- -11, /* (241) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- -1, /* (242) trigger_time ::= BEFORE|AFTER */
- -2, /* (243) trigger_time ::= INSTEAD OF */
- 0, /* (244) trigger_time ::= */
- -1, /* (245) trigger_event ::= DELETE|INSERT */
- -1, /* (246) trigger_event ::= UPDATE */
- -3, /* (247) trigger_event ::= UPDATE OF idlist */
- 0, /* (248) when_clause ::= */
- -2, /* (249) when_clause ::= WHEN expr */
- -3, /* (250) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- -2, /* (251) trigger_cmd_list ::= trigger_cmd SEMI */
- -3, /* (252) trnm ::= nm DOT nm */
- -3, /* (253) tridxby ::= INDEXED BY nm */
- -2, /* (254) tridxby ::= NOT INDEXED */
- -8, /* (255) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
- -8, /* (256) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- -6, /* (257) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- -3, /* (258) trigger_cmd ::= scanpt select scanpt */
- -4, /* (259) expr ::= RAISE LP IGNORE RP */
- -6, /* (260) expr ::= RAISE LP raisetype COMMA nm RP */
- -1, /* (261) raisetype ::= ROLLBACK */
- -1, /* (262) raisetype ::= ABORT */
- -1, /* (263) raisetype ::= FAIL */
- -4, /* (264) cmd ::= DROP TRIGGER ifexists fullname */
- -6, /* (265) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- -3, /* (266) cmd ::= DETACH database_kw_opt expr */
- 0, /* (267) key_opt ::= */
- -2, /* (268) key_opt ::= KEY expr */
- -1, /* (269) cmd ::= REINDEX */
- -3, /* (270) cmd ::= REINDEX nm dbnm */
- -1, /* (271) cmd ::= ANALYZE */
- -3, /* (272) cmd ::= ANALYZE nm dbnm */
- -6, /* (273) cmd ::= ALTER TABLE fullname RENAME TO nm */
- -7, /* (274) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- -1, /* (275) add_column_fullname ::= fullname */
- -8, /* (276) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- -1, /* (277) cmd ::= create_vtab */
- -4, /* (278) cmd ::= create_vtab LP vtabarglist RP */
- -8, /* (279) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- 0, /* (280) vtabarg ::= */
- -1, /* (281) vtabargtoken ::= ANY */
- -3, /* (282) vtabargtoken ::= lp anylist RP */
- -1, /* (283) lp ::= LP */
- -2, /* (284) with ::= WITH wqlist */
- -3, /* (285) with ::= WITH RECURSIVE wqlist */
- -6, /* (286) wqlist ::= nm eidlist_opt AS LP select RP */
- -8, /* (287) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
- -1, /* (288) windowdefn_list ::= windowdefn */
- -3, /* (289) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- -5, /* (290) windowdefn ::= nm AS LP window RP */
- -5, /* (291) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
- -6, /* (292) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
- -4, /* (293) window ::= ORDER BY sortlist frame_opt */
- -5, /* (294) window ::= nm ORDER BY sortlist frame_opt */
- -1, /* (295) window ::= frame_opt */
- -2, /* (296) window ::= nm frame_opt */
- 0, /* (297) frame_opt ::= */
- -3, /* (298) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
- -6, /* (299) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
- -1, /* (300) range_or_rows ::= RANGE|ROWS|GROUPS */
- -1, /* (301) frame_bound_s ::= frame_bound */
- -2, /* (302) frame_bound_s ::= UNBOUNDED PRECEDING */
- -1, /* (303) frame_bound_e ::= frame_bound */
- -2, /* (304) frame_bound_e ::= UNBOUNDED FOLLOWING */
- -2, /* (305) frame_bound ::= expr PRECEDING|FOLLOWING */
- -2, /* (306) frame_bound ::= CURRENT ROW */
- 0, /* (307) frame_exclude_opt ::= */
- -2, /* (308) frame_exclude_opt ::= EXCLUDE frame_exclude */
- -2, /* (309) frame_exclude ::= NO OTHERS */
- -2, /* (310) frame_exclude ::= CURRENT ROW */
- -1, /* (311) frame_exclude ::= GROUP|TIES */
- -2, /* (312) window_clause ::= WINDOW windowdefn_list */
- -5, /* (313) over_clause ::= filter_opt OVER LP window RP */
- -3, /* (314) over_clause ::= filter_opt OVER nm */
- 0, /* (315) filter_opt ::= */
- -5, /* (316) filter_opt ::= FILTER LP WHERE expr RP */
- -1, /* (317) input ::= cmdlist */
- -2, /* (318) cmdlist ::= cmdlist ecmd */
- -1, /* (319) cmdlist ::= ecmd */
- -1, /* (320) ecmd ::= SEMI */
- -2, /* (321) ecmd ::= cmdx SEMI */
- -2, /* (322) ecmd ::= explain cmdx */
- 0, /* (323) trans_opt ::= */
- -1, /* (324) trans_opt ::= TRANSACTION */
- -2, /* (325) trans_opt ::= TRANSACTION nm */
- -1, /* (326) savepoint_opt ::= SAVEPOINT */
- 0, /* (327) savepoint_opt ::= */
- -2, /* (328) cmd ::= create_table create_table_args */
- -4, /* (329) columnlist ::= columnlist COMMA columnname carglist */
- -2, /* (330) columnlist ::= columnname carglist */
- -1, /* (331) nm ::= ID|INDEXED */
- -1, /* (332) nm ::= STRING */
- -1, /* (333) nm ::= JOIN_KW */
- -1, /* (334) typetoken ::= typename */
- -1, /* (335) typename ::= ID|STRING */
- -1, /* (336) signed ::= plus_num */
- -1, /* (337) signed ::= minus_num */
- -2, /* (338) carglist ::= carglist ccons */
- 0, /* (339) carglist ::= */
- -2, /* (340) ccons ::= NULL onconf */
- -2, /* (341) conslist_opt ::= COMMA conslist */
- -3, /* (342) conslist ::= conslist tconscomma tcons */
- -1, /* (343) conslist ::= tcons */
- 0, /* (344) tconscomma ::= */
- -1, /* (345) defer_subclause_opt ::= defer_subclause */
- -1, /* (346) resolvetype ::= raisetype */
- -1, /* (347) selectnowith ::= oneselect */
- -1, /* (348) oneselect ::= values */
- -2, /* (349) sclp ::= selcollist COMMA */
- -1, /* (350) as ::= ID|STRING */
- -1, /* (351) expr ::= term */
- -1, /* (352) likeop ::= LIKE_KW|MATCH */
- -1, /* (353) exprlist ::= nexprlist */
- -1, /* (354) nmnum ::= plus_num */
- -1, /* (355) nmnum ::= nm */
- -1, /* (356) nmnum ::= ON */
- -1, /* (357) nmnum ::= DELETE */
- -1, /* (358) nmnum ::= DEFAULT */
- -1, /* (359) plus_num ::= INTEGER|FLOAT */
- 0, /* (360) foreach_clause ::= */
- -3, /* (361) foreach_clause ::= FOR EACH ROW */
- -1, /* (362) trnm ::= nm */
- 0, /* (363) tridxby ::= */
- -1, /* (364) database_kw_opt ::= DATABASE */
- 0, /* (365) database_kw_opt ::= */
- 0, /* (366) kwcolumn_opt ::= */
- -1, /* (367) kwcolumn_opt ::= COLUMNKW */
- -1, /* (368) vtabarglist ::= vtabarg */
- -3, /* (369) vtabarglist ::= vtabarglist COMMA vtabarg */
- -2, /* (370) vtabarg ::= vtabarg vtabargtoken */
- 0, /* (371) anylist ::= */
- -4, /* (372) anylist ::= anylist LP anylist RP */
- -2, /* (373) anylist ::= anylist ANY */
- 0, /* (374) with ::= */
+ 0, /* (29) scantok ::= */
+ -2, /* (30) ccons ::= CONSTRAINT nm */
+ -3, /* (31) ccons ::= DEFAULT scantok term */
+ -4, /* (32) ccons ::= DEFAULT LP expr RP */
+ -4, /* (33) ccons ::= DEFAULT PLUS scantok term */
+ -4, /* (34) ccons ::= DEFAULT MINUS scantok term */
+ -3, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */
+ -3, /* (36) ccons ::= NOT NULL onconf */
+ -5, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ -2, /* (38) ccons ::= UNIQUE onconf */
+ -4, /* (39) ccons ::= CHECK LP expr RP */
+ -4, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */
+ -1, /* (41) ccons ::= defer_subclause */
+ -2, /* (42) ccons ::= COLLATE ID|STRING */
+ 0, /* (43) autoinc ::= */
+ -1, /* (44) autoinc ::= AUTOINCR */
+ 0, /* (45) refargs ::= */
+ -2, /* (46) refargs ::= refargs refarg */
+ -2, /* (47) refarg ::= MATCH nm */
+ -3, /* (48) refarg ::= ON INSERT refact */
+ -3, /* (49) refarg ::= ON DELETE refact */
+ -3, /* (50) refarg ::= ON UPDATE refact */
+ -2, /* (51) refact ::= SET NULL */
+ -2, /* (52) refact ::= SET DEFAULT */
+ -1, /* (53) refact ::= CASCADE */
+ -1, /* (54) refact ::= RESTRICT */
+ -2, /* (55) refact ::= NO ACTION */
+ -3, /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ -2, /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 0, /* (58) init_deferred_pred_opt ::= */
+ -2, /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ -2, /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 0, /* (61) conslist_opt ::= */
+ -1, /* (62) tconscomma ::= COMMA */
+ -2, /* (63) tcons ::= CONSTRAINT nm */
+ -7, /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ -5, /* (65) tcons ::= UNIQUE LP sortlist RP onconf */
+ -5, /* (66) tcons ::= CHECK LP expr RP onconf */
+ -10, /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 0, /* (68) defer_subclause_opt ::= */
+ 0, /* (69) onconf ::= */
+ -3, /* (70) onconf ::= ON CONFLICT resolvetype */
+ 0, /* (71) orconf ::= */
+ -2, /* (72) orconf ::= OR resolvetype */
+ -1, /* (73) resolvetype ::= IGNORE */
+ -1, /* (74) resolvetype ::= REPLACE */
+ -4, /* (75) cmd ::= DROP TABLE ifexists fullname */
+ -2, /* (76) ifexists ::= IF EXISTS */
+ 0, /* (77) ifexists ::= */
+ -9, /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ -4, /* (79) cmd ::= DROP VIEW ifexists fullname */
+ -1, /* (80) cmd ::= select */
+ -3, /* (81) select ::= WITH wqlist selectnowith */
+ -4, /* (82) select ::= WITH RECURSIVE wqlist selectnowith */
+ -1, /* (83) select ::= selectnowith */
+ -3, /* (84) selectnowith ::= selectnowith multiselect_op oneselect */
+ -1, /* (85) multiselect_op ::= UNION */
+ -2, /* (86) multiselect_op ::= UNION ALL */
+ -1, /* (87) multiselect_op ::= EXCEPT|INTERSECT */
+ -9, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ -10, /* (89) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ -4, /* (90) values ::= VALUES LP nexprlist RP */
+ -5, /* (91) values ::= values COMMA LP nexprlist RP */
+ -1, /* (92) distinct ::= DISTINCT */
+ -1, /* (93) distinct ::= ALL */
+ 0, /* (94) distinct ::= */
+ 0, /* (95) sclp ::= */
+ -5, /* (96) selcollist ::= sclp scanpt expr scanpt as */
+ -3, /* (97) selcollist ::= sclp scanpt STAR */
+ -5, /* (98) selcollist ::= sclp scanpt nm DOT STAR */
+ -2, /* (99) as ::= AS nm */
+ 0, /* (100) as ::= */
+ 0, /* (101) from ::= */
+ -2, /* (102) from ::= FROM seltablist */
+ -2, /* (103) stl_prefix ::= seltablist joinop */
+ 0, /* (104) stl_prefix ::= */
+ -7, /* (105) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ -9, /* (106) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ -7, /* (107) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ -7, /* (108) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ 0, /* (109) dbnm ::= */
+ -2, /* (110) dbnm ::= DOT nm */
+ -1, /* (111) fullname ::= nm */
+ -3, /* (112) fullname ::= nm DOT nm */
+ -1, /* (113) xfullname ::= nm */
+ -3, /* (114) xfullname ::= nm DOT nm */
+ -5, /* (115) xfullname ::= nm DOT nm AS nm */
+ -3, /* (116) xfullname ::= nm AS nm */
+ -1, /* (117) joinop ::= COMMA|JOIN */
+ -2, /* (118) joinop ::= JOIN_KW JOIN */
+ -3, /* (119) joinop ::= JOIN_KW nm JOIN */
+ -4, /* (120) joinop ::= JOIN_KW nm nm JOIN */
+ -2, /* (121) on_opt ::= ON expr */
+ 0, /* (122) on_opt ::= */
+ 0, /* (123) indexed_opt ::= */
+ -3, /* (124) indexed_opt ::= INDEXED BY nm */
+ -2, /* (125) indexed_opt ::= NOT INDEXED */
+ -4, /* (126) using_opt ::= USING LP idlist RP */
+ 0, /* (127) using_opt ::= */
+ 0, /* (128) orderby_opt ::= */
+ -3, /* (129) orderby_opt ::= ORDER BY sortlist */
+ -4, /* (130) sortlist ::= sortlist COMMA expr sortorder */
+ -2, /* (131) sortlist ::= expr sortorder */
+ -1, /* (132) sortorder ::= ASC */
+ -1, /* (133) sortorder ::= DESC */
+ 0, /* (134) sortorder ::= */
+ 0, /* (135) groupby_opt ::= */
+ -3, /* (136) groupby_opt ::= GROUP BY nexprlist */
+ 0, /* (137) having_opt ::= */
+ -2, /* (138) having_opt ::= HAVING expr */
+ 0, /* (139) limit_opt ::= */
+ -2, /* (140) limit_opt ::= LIMIT expr */
+ -4, /* (141) limit_opt ::= LIMIT expr OFFSET expr */
+ -4, /* (142) limit_opt ::= LIMIT expr COMMA expr */
+ -6, /* (143) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ 0, /* (144) where_opt ::= */
+ -2, /* (145) where_opt ::= WHERE expr */
+ -8, /* (146) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ -5, /* (147) setlist ::= setlist COMMA nm EQ expr */
+ -7, /* (148) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ -3, /* (149) setlist ::= nm EQ expr */
+ -5, /* (150) setlist ::= LP idlist RP EQ expr */
+ -7, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ -7, /* (152) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ 0, /* (153) upsert ::= */
+ -11, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ -8, /* (155) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ -4, /* (156) upsert ::= ON CONFLICT DO NOTHING */
+ -2, /* (157) insert_cmd ::= INSERT orconf */
+ -1, /* (158) insert_cmd ::= REPLACE */
+ 0, /* (159) idlist_opt ::= */
+ -3, /* (160) idlist_opt ::= LP idlist RP */
+ -3, /* (161) idlist ::= idlist COMMA nm */
+ -1, /* (162) idlist ::= nm */
+ -3, /* (163) expr ::= LP expr RP */
+ -1, /* (164) expr ::= ID|INDEXED */
+ -1, /* (165) expr ::= JOIN_KW */
+ -3, /* (166) expr ::= nm DOT nm */
+ -5, /* (167) expr ::= nm DOT nm DOT nm */
+ -1, /* (168) term ::= NULL|FLOAT|BLOB */
+ -1, /* (169) term ::= STRING */
+ -1, /* (170) term ::= INTEGER */
+ -1, /* (171) expr ::= VARIABLE */
+ -3, /* (172) expr ::= expr COLLATE ID|STRING */
+ -6, /* (173) expr ::= CAST LP expr AS typetoken RP */
+ -5, /* (174) expr ::= ID|INDEXED LP distinct exprlist RP */
+ -4, /* (175) expr ::= ID|INDEXED LP STAR RP */
+ -6, /* (176) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ -5, /* (177) expr ::= ID|INDEXED LP STAR RP over_clause */
+ -1, /* (178) term ::= CTIME_KW */
+ -5, /* (179) expr ::= LP nexprlist COMMA expr RP */
+ -3, /* (180) expr ::= expr AND expr */
+ -3, /* (181) expr ::= expr OR expr */
+ -3, /* (182) expr ::= expr LT|GT|GE|LE expr */
+ -3, /* (183) expr ::= expr EQ|NE expr */
+ -3, /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ -3, /* (185) expr ::= expr PLUS|MINUS expr */
+ -3, /* (186) expr ::= expr STAR|SLASH|REM expr */
+ -3, /* (187) expr ::= expr CONCAT expr */
+ -2, /* (188) likeop ::= NOT LIKE_KW|MATCH */
+ -3, /* (189) expr ::= expr likeop expr */
+ -5, /* (190) expr ::= expr likeop expr ESCAPE expr */
+ -2, /* (191) expr ::= expr ISNULL|NOTNULL */
+ -3, /* (192) expr ::= expr NOT NULL */
+ -3, /* (193) expr ::= expr IS expr */
+ -4, /* (194) expr ::= expr IS NOT expr */
+ -2, /* (195) expr ::= NOT expr */
+ -2, /* (196) expr ::= BITNOT expr */
+ -2, /* (197) expr ::= PLUS|MINUS expr */
+ -1, /* (198) between_op ::= BETWEEN */
+ -2, /* (199) between_op ::= NOT BETWEEN */
+ -5, /* (200) expr ::= expr between_op expr AND expr */
+ -1, /* (201) in_op ::= IN */
+ -2, /* (202) in_op ::= NOT IN */
+ -5, /* (203) expr ::= expr in_op LP exprlist RP */
+ -3, /* (204) expr ::= LP select RP */
+ -5, /* (205) expr ::= expr in_op LP select RP */
+ -5, /* (206) expr ::= expr in_op nm dbnm paren_exprlist */
+ -4, /* (207) expr ::= EXISTS LP select RP */
+ -5, /* (208) expr ::= CASE case_operand case_exprlist case_else END */
+ -5, /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ -4, /* (210) case_exprlist ::= WHEN expr THEN expr */
+ -2, /* (211) case_else ::= ELSE expr */
+ 0, /* (212) case_else ::= */
+ -1, /* (213) case_operand ::= expr */
+ 0, /* (214) case_operand ::= */
+ 0, /* (215) exprlist ::= */
+ -3, /* (216) nexprlist ::= nexprlist COMMA expr */
+ -1, /* (217) nexprlist ::= expr */
+ 0, /* (218) paren_exprlist ::= */
+ -3, /* (219) paren_exprlist ::= LP exprlist RP */
+ -12, /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ -1, /* (221) uniqueflag ::= UNIQUE */
+ 0, /* (222) uniqueflag ::= */
+ 0, /* (223) eidlist_opt ::= */
+ -3, /* (224) eidlist_opt ::= LP eidlist RP */
+ -5, /* (225) eidlist ::= eidlist COMMA nm collate sortorder */
+ -3, /* (226) eidlist ::= nm collate sortorder */
+ 0, /* (227) collate ::= */
+ -2, /* (228) collate ::= COLLATE ID|STRING */
+ -4, /* (229) cmd ::= DROP INDEX ifexists fullname */
+ -2, /* (230) cmd ::= VACUUM vinto */
+ -3, /* (231) cmd ::= VACUUM nm vinto */
+ -2, /* (232) vinto ::= INTO expr */
+ 0, /* (233) vinto ::= */
+ -3, /* (234) cmd ::= PRAGMA nm dbnm */
+ -5, /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ -6, /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ -5, /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ -6, /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ -2, /* (239) plus_num ::= PLUS INTEGER|FLOAT */
+ -2, /* (240) minus_num ::= MINUS INTEGER|FLOAT */
+ -5, /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ -11, /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ -1, /* (243) trigger_time ::= BEFORE|AFTER */
+ -2, /* (244) trigger_time ::= INSTEAD OF */
+ 0, /* (245) trigger_time ::= */
+ -1, /* (246) trigger_event ::= DELETE|INSERT */
+ -1, /* (247) trigger_event ::= UPDATE */
+ -3, /* (248) trigger_event ::= UPDATE OF idlist */
+ 0, /* (249) when_clause ::= */
+ -2, /* (250) when_clause ::= WHEN expr */
+ -3, /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ -2, /* (252) trigger_cmd_list ::= trigger_cmd SEMI */
+ -3, /* (253) trnm ::= nm DOT nm */
+ -3, /* (254) tridxby ::= INDEXED BY nm */
+ -2, /* (255) tridxby ::= NOT INDEXED */
+ -8, /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ -8, /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ -6, /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ -3, /* (259) trigger_cmd ::= scanpt select scanpt */
+ -4, /* (260) expr ::= RAISE LP IGNORE RP */
+ -6, /* (261) expr ::= RAISE LP raisetype COMMA nm RP */
+ -1, /* (262) raisetype ::= ROLLBACK */
+ -1, /* (263) raisetype ::= ABORT */
+ -1, /* (264) raisetype ::= FAIL */
+ -4, /* (265) cmd ::= DROP TRIGGER ifexists fullname */
+ -6, /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ -3, /* (267) cmd ::= DETACH database_kw_opt expr */
+ 0, /* (268) key_opt ::= */
+ -2, /* (269) key_opt ::= KEY expr */
+ -1, /* (270) cmd ::= REINDEX */
+ -3, /* (271) cmd ::= REINDEX nm dbnm */
+ -1, /* (272) cmd ::= ANALYZE */
+ -3, /* (273) cmd ::= ANALYZE nm dbnm */
+ -6, /* (274) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ -7, /* (275) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ -1, /* (276) add_column_fullname ::= fullname */
+ -8, /* (277) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ -1, /* (278) cmd ::= create_vtab */
+ -4, /* (279) cmd ::= create_vtab LP vtabarglist RP */
+ -8, /* (280) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 0, /* (281) vtabarg ::= */
+ -1, /* (282) vtabargtoken ::= ANY */
+ -3, /* (283) vtabargtoken ::= lp anylist RP */
+ -1, /* (284) lp ::= LP */
+ -2, /* (285) with ::= WITH wqlist */
+ -3, /* (286) with ::= WITH RECURSIVE wqlist */
+ -6, /* (287) wqlist ::= nm eidlist_opt AS LP select RP */
+ -8, /* (288) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ -1, /* (289) windowdefn_list ::= windowdefn */
+ -3, /* (290) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ -5, /* (291) windowdefn ::= nm AS LP window RP */
+ -5, /* (292) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ -6, /* (293) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ -4, /* (294) window ::= ORDER BY sortlist frame_opt */
+ -5, /* (295) window ::= nm ORDER BY sortlist frame_opt */
+ -1, /* (296) window ::= frame_opt */
+ -2, /* (297) window ::= nm frame_opt */
+ 0, /* (298) frame_opt ::= */
+ -3, /* (299) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ -6, /* (300) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ -1, /* (301) range_or_rows ::= RANGE|ROWS|GROUPS */
+ -1, /* (302) frame_bound_s ::= frame_bound */
+ -2, /* (303) frame_bound_s ::= UNBOUNDED PRECEDING */
+ -1, /* (304) frame_bound_e ::= frame_bound */
+ -2, /* (305) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ -2, /* (306) frame_bound ::= expr PRECEDING|FOLLOWING */
+ -2, /* (307) frame_bound ::= CURRENT ROW */
+ 0, /* (308) frame_exclude_opt ::= */
+ -2, /* (309) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ -2, /* (310) frame_exclude ::= NO OTHERS */
+ -2, /* (311) frame_exclude ::= CURRENT ROW */
+ -1, /* (312) frame_exclude ::= GROUP|TIES */
+ -2, /* (313) window_clause ::= WINDOW windowdefn_list */
+ -5, /* (314) over_clause ::= filter_opt OVER LP window RP */
+ -3, /* (315) over_clause ::= filter_opt OVER nm */
+ 0, /* (316) filter_opt ::= */
+ -5, /* (317) filter_opt ::= FILTER LP WHERE expr RP */
+ -1, /* (318) input ::= cmdlist */
+ -2, /* (319) cmdlist ::= cmdlist ecmd */
+ -1, /* (320) cmdlist ::= ecmd */
+ -1, /* (321) ecmd ::= SEMI */
+ -2, /* (322) ecmd ::= cmdx SEMI */
+ -2, /* (323) ecmd ::= explain cmdx */
+ 0, /* (324) trans_opt ::= */
+ -1, /* (325) trans_opt ::= TRANSACTION */
+ -2, /* (326) trans_opt ::= TRANSACTION nm */
+ -1, /* (327) savepoint_opt ::= SAVEPOINT */
+ 0, /* (328) savepoint_opt ::= */
+ -2, /* (329) cmd ::= create_table create_table_args */
+ -4, /* (330) columnlist ::= columnlist COMMA columnname carglist */
+ -2, /* (331) columnlist ::= columnname carglist */
+ -1, /* (332) nm ::= ID|INDEXED */
+ -1, /* (333) nm ::= STRING */
+ -1, /* (334) nm ::= JOIN_KW */
+ -1, /* (335) typetoken ::= typename */
+ -1, /* (336) typename ::= ID|STRING */
+ -1, /* (337) signed ::= plus_num */
+ -1, /* (338) signed ::= minus_num */
+ -2, /* (339) carglist ::= carglist ccons */
+ 0, /* (340) carglist ::= */
+ -2, /* (341) ccons ::= NULL onconf */
+ -2, /* (342) conslist_opt ::= COMMA conslist */
+ -3, /* (343) conslist ::= conslist tconscomma tcons */
+ -1, /* (344) conslist ::= tcons */
+ 0, /* (345) tconscomma ::= */
+ -1, /* (346) defer_subclause_opt ::= defer_subclause */
+ -1, /* (347) resolvetype ::= raisetype */
+ -1, /* (348) selectnowith ::= oneselect */
+ -1, /* (349) oneselect ::= values */
+ -2, /* (350) sclp ::= selcollist COMMA */
+ -1, /* (351) as ::= ID|STRING */
+ -1, /* (352) expr ::= term */
+ -1, /* (353) likeop ::= LIKE_KW|MATCH */
+ -1, /* (354) exprlist ::= nexprlist */
+ -1, /* (355) nmnum ::= plus_num */
+ -1, /* (356) nmnum ::= nm */
+ -1, /* (357) nmnum ::= ON */
+ -1, /* (358) nmnum ::= DELETE */
+ -1, /* (359) nmnum ::= DEFAULT */
+ -1, /* (360) plus_num ::= INTEGER|FLOAT */
+ 0, /* (361) foreach_clause ::= */
+ -3, /* (362) foreach_clause ::= FOR EACH ROW */
+ -1, /* (363) trnm ::= nm */
+ 0, /* (364) tridxby ::= */
+ -1, /* (365) database_kw_opt ::= DATABASE */
+ 0, /* (366) database_kw_opt ::= */
+ 0, /* (367) kwcolumn_opt ::= */
+ -1, /* (368) kwcolumn_opt ::= COLUMNKW */
+ -1, /* (369) vtabarglist ::= vtabarg */
+ -3, /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */
+ -2, /* (371) vtabarg ::= vtabarg vtabargtoken */
+ 0, /* (372) anylist ::= */
+ -4, /* (373) anylist ::= anylist LP anylist RP */
+ -2, /* (374) anylist ::= anylist ANY */
+ 0, /* (375) with ::= */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -151321,16 +151902,16 @@ static YYACTIONTYPE yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy494);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy100);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy494 = TK_DEFERRED;}
+{yymsp[1].minor.yy100 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
- case 300: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==300);
-{yymsp[0].minor.yy494 = yymsp[0].major; /*A-overwrites-X*/}
+ case 301: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==301);
+{yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -151353,7 +151934,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy494,0,0,yymsp[-2].minor.yy494);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy100,0,0,yymsp[-2].minor.yy100);
}
break;
case 14: /* createkw ::= CREATE */
@@ -151362,38 +151943,38 @@ static YYACTIONTYPE yy_reduce(
case 15: /* ifnotexists ::= */
case 18: /* temp ::= */ yytestcase(yyruleno==18);
case 21: /* table_options ::= */ yytestcase(yyruleno==21);
- case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
- case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
- case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
- case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
- case 93: /* distinct ::= */ yytestcase(yyruleno==93);
- case 226: /* collate ::= */ yytestcase(yyruleno==226);
-{yymsp[1].minor.yy494 = 0;}
+ case 43: /* autoinc ::= */ yytestcase(yyruleno==43);
+ case 58: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==58);
+ case 68: /* defer_subclause_opt ::= */ yytestcase(yyruleno==68);
+ case 77: /* ifexists ::= */ yytestcase(yyruleno==77);
+ case 94: /* distinct ::= */ yytestcase(yyruleno==94);
+ case 227: /* collate ::= */ yytestcase(yyruleno==227);
+{yymsp[1].minor.yy100 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy494 = 1;}
+{yymsp[-2].minor.yy100 = 1;}
break;
case 17: /* temp ::= TEMP */
- case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
-{yymsp[0].minor.yy494 = 1;}
+ case 44: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==44);
+{yymsp[0].minor.yy100 = 1;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy494,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy100,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy457);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy457);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy391);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy391);
}
break;
case 22: /* table_options ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy494 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy100 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy494 = 0;
+ yymsp[-1].minor.yy100 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -151402,8 +151983,8 @@ static YYACTIONTYPE yy_reduce(
{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 24: /* typetoken ::= */
- case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
- case 99: /* as ::= */ yytestcase(yyruleno==99);
+ case 61: /* conslist_opt ::= */ yytestcase(yyruleno==61);
+ case 100: /* as ::= */ yytestcase(yyruleno==100);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
break;
case 25: /* typetoken ::= typename LP signed RP */
@@ -151422,29 +152003,35 @@ static YYACTIONTYPE yy_reduce(
case 28: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
- yymsp[1].minor.yy294 = yyLookaheadToken.z;
+ yymsp[1].minor.yy528 = yyLookaheadToken.z;
}
break;
- case 29: /* ccons ::= CONSTRAINT nm */
- case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
+ case 29: /* scantok ::= */
+{
+ assert( yyLookahead!=YYNOCODE );
+ yymsp[1].minor.yy0 = yyLookaheadToken;
+}
+ break;
+ case 30: /* ccons ::= CONSTRAINT nm */
+ case 63: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==63);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 30: /* ccons ::= DEFAULT scanpt term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy524,yymsp[-2].minor.yy294,yymsp[0].minor.yy294);}
+ case 31: /* ccons ::= DEFAULT scantok term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy102,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
- case 31: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy524,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+ case 32: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy102,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
- case 32: /* ccons ::= DEFAULT PLUS term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy524,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy294);}
+ case 33: /* ccons ::= DEFAULT PLUS scantok term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy102,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
- case 33: /* ccons ::= DEFAULT MINUS term scanpt */
+ case 34: /* ccons ::= DEFAULT MINUS scantok term */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy524, 0);
- sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy294);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy102, 0);
+ sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
}
break;
- case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
+ case 35: /* ccons ::= DEFAULT scantok ID|INDEXED */
{
Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
if( p ){
@@ -151454,171 +152041,171 @@ static YYACTIONTYPE yy_reduce(
sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
}
break;
- case 35: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy494);}
+ case 36: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy100);}
break;
- case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy494,yymsp[0].minor.yy494,yymsp[-2].minor.yy494);}
+ case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy100,yymsp[0].minor.yy100,yymsp[-2].minor.yy100);}
break;
- case 37: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy494,0,0,0,0,
+ case 38: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy100,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 38: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy524);}
+ case 39: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy102);}
break;
- case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy434,yymsp[0].minor.yy494);}
+ case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy94,yymsp[0].minor.yy100);}
break;
- case 40: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy494);}
+ case 41: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy100);}
break;
- case 41: /* ccons ::= COLLATE ID|STRING */
+ case 42: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 44: /* refargs ::= */
-{ yymsp[1].minor.yy494 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 45: /* refargs ::= */
+{ yymsp[1].minor.yy100 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
- case 45: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy494 = (yymsp[-1].minor.yy494 & ~yymsp[0].minor.yy355.mask) | yymsp[0].minor.yy355.value; }
+ case 46: /* refargs ::= refargs refarg */
+{ yymsp[-1].minor.yy100 = (yymsp[-1].minor.yy100 & ~yymsp[0].minor.yy199.mask) | yymsp[0].minor.yy199.value; }
break;
- case 46: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy355.value = 0; yymsp[-1].minor.yy355.mask = 0x000000; }
+ case 47: /* refarg ::= MATCH nm */
+{ yymsp[-1].minor.yy199.value = 0; yymsp[-1].minor.yy199.mask = 0x000000; }
break;
- case 47: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy355.value = 0; yymsp[-2].minor.yy355.mask = 0x000000; }
+ case 48: /* refarg ::= ON INSERT refact */
+{ yymsp[-2].minor.yy199.value = 0; yymsp[-2].minor.yy199.mask = 0x000000; }
break;
- case 48: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy355.value = yymsp[0].minor.yy494; yymsp[-2].minor.yy355.mask = 0x0000ff; }
+ case 49: /* refarg ::= ON DELETE refact */
+{ yymsp[-2].minor.yy199.value = yymsp[0].minor.yy100; yymsp[-2].minor.yy199.mask = 0x0000ff; }
break;
- case 49: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy355.value = yymsp[0].minor.yy494<<8; yymsp[-2].minor.yy355.mask = 0x00ff00; }
+ case 50: /* refarg ::= ON UPDATE refact */
+{ yymsp[-2].minor.yy199.value = yymsp[0].minor.yy100<<8; yymsp[-2].minor.yy199.mask = 0x00ff00; }
break;
- case 50: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy494 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 51: /* refact ::= SET NULL */
+{ yymsp[-1].minor.yy100 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 51: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy494 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 52: /* refact ::= SET DEFAULT */
+{ yymsp[-1].minor.yy100 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 52: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy494 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 53: /* refact ::= CASCADE */
+{ yymsp[0].minor.yy100 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 53: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy494 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 54: /* refact ::= RESTRICT */
+{ yymsp[0].minor.yy100 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 54: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy494 = OE_None; /* EV: R-33326-45252 */}
+ case 55: /* refact ::= NO ACTION */
+{ yymsp[-1].minor.yy100 = OE_None; /* EV: R-33326-45252 */}
break;
- case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy494 = 0;}
+ case 56: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+{yymsp[-2].minor.yy100 = 0;}
break;
- case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
- case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156);
-{yymsp[-1].minor.yy494 = yymsp[0].minor.yy494;}
+ case 57: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 72: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==72);
+ case 157: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==157);
+{yymsp[-1].minor.yy100 = yymsp[0].minor.yy100;}
break;
- case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
- case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
- case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198);
- case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201);
- case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227);
-{yymsp[-1].minor.yy494 = 1;}
+ case 59: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ case 76: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==76);
+ case 199: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==199);
+ case 202: /* in_op ::= NOT IN */ yytestcase(yyruleno==202);
+ case 228: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==228);
+{yymsp[-1].minor.yy100 = 1;}
break;
- case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy494 = 0;}
+ case 60: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+{yymsp[-1].minor.yy100 = 0;}
break;
- case 61: /* tconscomma ::= COMMA */
+ case 62: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy434,yymsp[0].minor.yy494,yymsp[-2].minor.yy494,0);}
+ case 64: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy94,yymsp[0].minor.yy100,yymsp[-2].minor.yy100,0);}
break;
- case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy434,yymsp[0].minor.yy494,0,0,0,0,
+ case 65: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy94,yymsp[0].minor.yy100,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 65: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy524);}
+ case 66: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy102);}
break;
- case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ case 67: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy434, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy434, yymsp[-1].minor.yy494);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy494);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy94, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy94, yymsp[-1].minor.yy100);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy100);
}
break;
- case 68: /* onconf ::= */
- case 70: /* orconf ::= */ yytestcase(yyruleno==70);
-{yymsp[1].minor.yy494 = OE_Default;}
+ case 69: /* onconf ::= */
+ case 71: /* orconf ::= */ yytestcase(yyruleno==71);
+{yymsp[1].minor.yy100 = OE_Default;}
break;
- case 69: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy494 = yymsp[0].minor.yy494;}
+ case 70: /* onconf ::= ON CONFLICT resolvetype */
+{yymsp[-2].minor.yy100 = yymsp[0].minor.yy100;}
break;
- case 72: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy494 = OE_Ignore;}
+ case 73: /* resolvetype ::= IGNORE */
+{yymsp[0].minor.yy100 = OE_Ignore;}
break;
- case 73: /* resolvetype ::= REPLACE */
- case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
-{yymsp[0].minor.yy494 = OE_Replace;}
+ case 74: /* resolvetype ::= REPLACE */
+ case 158: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==158);
+{yymsp[0].minor.yy100 = OE_Replace;}
break;
- case 74: /* cmd ::= DROP TABLE ifexists fullname */
+ case 75: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy494);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy407, 0, yymsp[-1].minor.yy100);
}
break;
- case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ case 78: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
- sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy434, yymsp[0].minor.yy457, yymsp[-7].minor.yy494, yymsp[-5].minor.yy494);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy94, yymsp[0].minor.yy391, yymsp[-7].minor.yy100, yymsp[-5].minor.yy100);
}
break;
- case 78: /* cmd ::= DROP VIEW ifexists fullname */
+ case 79: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy483, 1, yymsp[-1].minor.yy494);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy407, 1, yymsp[-1].minor.yy100);
}
break;
- case 79: /* cmd ::= select */
+ case 80: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy457, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy457);
+ sqlite3Select(pParse, yymsp[0].minor.yy391, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy391);
}
break;
- case 80: /* select ::= WITH wqlist selectnowith */
+ case 81: /* select ::= WITH wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy457;
+ Select *p = yymsp[0].minor.yy391;
if( p ){
- p->pWith = yymsp[-1].minor.yy59;
+ p->pWith = yymsp[-1].minor.yy243;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy243);
}
- yymsp[-2].minor.yy457 = p;
+ yymsp[-2].minor.yy391 = p;
}
break;
- case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
+ case 82: /* select ::= WITH RECURSIVE wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy457;
+ Select *p = yymsp[0].minor.yy391;
if( p ){
- p->pWith = yymsp[-1].minor.yy59;
+ p->pWith = yymsp[-1].minor.yy243;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy243);
}
- yymsp[-3].minor.yy457 = p;
+ yymsp[-3].minor.yy391 = p;
}
break;
- case 82: /* select ::= selectnowith */
+ case 83: /* select ::= selectnowith */
{
- Select *p = yymsp[0].minor.yy457;
+ Select *p = yymsp[0].minor.yy391;
if( p ){
parserDoubleLinkSelect(pParse, p);
}
- yymsp[0].minor.yy457 = p; /*A-overwrites-X*/
+ yymsp[0].minor.yy391 = p; /*A-overwrites-X*/
}
break;
- case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
+ case 84: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy457;
- Select *pLhs = yymsp[-2].minor.yy457;
+ Select *pRhs = yymsp[0].minor.yy391;
+ Select *pLhs = yymsp[-2].minor.yy391;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -151628,142 +152215,142 @@ static YYACTIONTYPE yy_reduce(
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy494;
+ pRhs->op = (u8)yymsp[-1].minor.yy100;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy494!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy100!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy457 = pRhs;
+ yymsp[-2].minor.yy391 = pRhs;
}
break;
- case 84: /* multiselect_op ::= UNION */
- case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
-{yymsp[0].minor.yy494 = yymsp[0].major; /*A-overwrites-OP*/}
+ case 85: /* multiselect_op ::= UNION */
+ case 87: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==87);
+{yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-OP*/}
break;
- case 85: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy494 = TK_ALL;}
+ case 86: /* multiselect_op ::= UNION ALL */
+{yymsp[-1].minor.yy100 = TK_ALL;}
break;
- case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yymsp[-8].minor.yy457 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy434,yymsp[-5].minor.yy483,yymsp[-4].minor.yy524,yymsp[-3].minor.yy434,yymsp[-2].minor.yy524,yymsp[-1].minor.yy434,yymsp[-7].minor.yy494,yymsp[0].minor.yy524);
+ yymsp[-8].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy94,yymsp[-5].minor.yy407,yymsp[-4].minor.yy102,yymsp[-3].minor.yy94,yymsp[-2].minor.yy102,yymsp[-1].minor.yy94,yymsp[-7].minor.yy100,yymsp[0].minor.yy102);
}
break;
- case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ case 89: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
- yymsp[-9].minor.yy457 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy434,yymsp[-6].minor.yy483,yymsp[-5].minor.yy524,yymsp[-4].minor.yy434,yymsp[-3].minor.yy524,yymsp[-1].minor.yy434,yymsp[-8].minor.yy494,yymsp[0].minor.yy524);
- if( yymsp[-9].minor.yy457 ){
- yymsp[-9].minor.yy457->pWinDefn = yymsp[-2].minor.yy295;
+ yymsp[-9].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy94,yymsp[-6].minor.yy407,yymsp[-5].minor.yy102,yymsp[-4].minor.yy94,yymsp[-3].minor.yy102,yymsp[-1].minor.yy94,yymsp[-8].minor.yy100,yymsp[0].minor.yy102);
+ if( yymsp[-9].minor.yy391 ){
+ yymsp[-9].minor.yy391->pWinDefn = yymsp[-2].minor.yy379;
}else{
- sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy295);
+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy379);
}
}
break;
- case 89: /* values ::= VALUES LP nexprlist RP */
+ case 90: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy457 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy434,0,0,0,0,0,SF_Values,0);
+ yymsp[-3].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy94,0,0,0,0,0,SF_Values,0);
}
break;
- case 90: /* values ::= values COMMA LP nexprlist RP */
+ case 91: /* values ::= values COMMA LP nexprlist RP */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy457;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy434,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+ Select *pRight, *pLeft = yymsp[-4].minor.yy391;
+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy94,0,0,0,0,0,SF_Values|SF_MultiValue,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
pRight->pPrior = pLeft;
- yymsp[-4].minor.yy457 = pRight;
+ yymsp[-4].minor.yy391 = pRight;
}else{
- yymsp[-4].minor.yy457 = pLeft;
+ yymsp[-4].minor.yy391 = pLeft;
}
}
break;
- case 91: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy494 = SF_Distinct;}
+ case 92: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy100 = SF_Distinct;}
break;
- case 92: /* distinct ::= ALL */
-{yymsp[0].minor.yy494 = SF_All;}
+ case 93: /* distinct ::= ALL */
+{yymsp[0].minor.yy100 = SF_All;}
break;
- case 94: /* sclp ::= */
- case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127);
- case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134);
- case 214: /* exprlist ::= */ yytestcase(yyruleno==214);
- case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217);
- case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222);
-{yymsp[1].minor.yy434 = 0;}
+ case 95: /* sclp ::= */
+ case 128: /* orderby_opt ::= */ yytestcase(yyruleno==128);
+ case 135: /* groupby_opt ::= */ yytestcase(yyruleno==135);
+ case 215: /* exprlist ::= */ yytestcase(yyruleno==215);
+ case 218: /* paren_exprlist ::= */ yytestcase(yyruleno==218);
+ case 223: /* eidlist_opt ::= */ yytestcase(yyruleno==223);
+{yymsp[1].minor.yy94 = 0;}
break;
- case 95: /* selcollist ::= sclp scanpt expr scanpt as */
+ case 96: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-4].minor.yy434 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy434, yymsp[-2].minor.yy524);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy434, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy434,yymsp[-3].minor.yy294,yymsp[-1].minor.yy294);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy94, yymsp[-2].minor.yy102);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy94, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy94,yymsp[-3].minor.yy528,yymsp[-1].minor.yy528);
}
break;
- case 96: /* selcollist ::= sclp scanpt STAR */
+ case 97: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- yymsp[-2].minor.yy434 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy434, p);
+ yymsp[-2].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy94, p);
}
break;
- case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
+ case 98: /* selcollist ::= sclp scanpt nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
- yymsp[-4].minor.yy434 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy434, pDot);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, pDot);
}
break;
- case 98: /* as ::= AS nm */
- case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109);
- case 238: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==238);
- case 239: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==239);
+ case 99: /* as ::= AS nm */
+ case 110: /* dbnm ::= DOT nm */ yytestcase(yyruleno==110);
+ case 239: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==239);
+ case 240: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==240);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 100: /* from ::= */
-{yymsp[1].minor.yy483 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy483));}
+ case 101: /* from ::= */
+{yymsp[1].minor.yy407 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy407));}
break;
- case 101: /* from ::= FROM seltablist */
+ case 102: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy483 = yymsp[0].minor.yy483;
- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy483);
+ yymsp[-1].minor.yy407 = yymsp[0].minor.yy407;
+ sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy407);
}
break;
- case 102: /* stl_prefix ::= seltablist joinop */
+ case 103: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy483 && yymsp[-1].minor.yy483->nSrc>0) ) yymsp[-1].minor.yy483->a[yymsp[-1].minor.yy483->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy494;
+ if( ALWAYS(yymsp[-1].minor.yy407 && yymsp[-1].minor.yy407->nSrc>0) ) yymsp[-1].minor.yy407->a[yymsp[-1].minor.yy407->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy100;
}
break;
- case 103: /* stl_prefix ::= */
-{yymsp[1].minor.yy483 = 0;}
+ case 104: /* stl_prefix ::= */
+{yymsp[1].minor.yy407 = 0;}
break;
- case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 105: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yymsp[-6].minor.yy483 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy483,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy524,yymsp[0].minor.yy62);
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy483, &yymsp[-2].minor.yy0);
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy407, &yymsp[-2].minor.yy0);
}
break;
- case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ case 106: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
{
- yymsp[-8].minor.yy483 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy483,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy524,yymsp[0].minor.yy62);
- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy483, yymsp[-4].minor.yy434);
+ yymsp[-8].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy407,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy407, yymsp[-4].minor.yy94);
}
break;
- case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 107: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yymsp[-6].minor.yy483 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy483,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy457,yymsp[-1].minor.yy524,yymsp[0].minor.yy62);
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy391,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
}
break;
- case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 108: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy483==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy524==0 && yymsp[0].minor.yy62==0 ){
- yymsp[-6].minor.yy483 = yymsp[-4].minor.yy483;
- }else if( yymsp[-4].minor.yy483->nSrc==1 ){
- yymsp[-6].minor.yy483 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy483,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy524,yymsp[0].minor.yy62);
- if( yymsp[-6].minor.yy483 ){
- struct SrcList_item *pNew = &yymsp[-6].minor.yy483->a[yymsp[-6].minor.yy483->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy483->a;
+ if( yymsp[-6].minor.yy407==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy102==0 && yymsp[0].minor.yy76==0 ){
+ yymsp[-6].minor.yy407 = yymsp[-4].minor.yy407;
+ }else if( yymsp[-4].minor.yy407->nSrc==1 ){
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+ if( yymsp[-6].minor.yy407 ){
+ struct SrcList_item *pNew = &yymsp[-6].minor.yy407->a[yymsp[-6].minor.yy407->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy407->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
@@ -151776,201 +152363,201 @@ static YYACTIONTYPE yy_reduce(
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy483);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy407);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy483);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy483,0,0,0,0,SF_NestedFrom,0);
- yymsp[-6].minor.yy483 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy483,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy524,yymsp[0].minor.yy62);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy407);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy407,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
}
}
break;
- case 108: /* dbnm ::= */
- case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122);
+ case 109: /* dbnm ::= */
+ case 123: /* indexed_opt ::= */ yytestcase(yyruleno==123);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
- case 110: /* fullname ::= nm */
+ case 111: /* fullname ::= nm */
{
- yylhsminor.yy483 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
- if( IN_RENAME_OBJECT && yylhsminor.yy483 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy483->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy407 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy407->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[0].minor.yy483 = yylhsminor.yy483;
+ yymsp[0].minor.yy407 = yylhsminor.yy407;
break;
- case 111: /* fullname ::= nm DOT nm */
+ case 112: /* fullname ::= nm DOT nm */
{
- yylhsminor.yy483 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
- if( IN_RENAME_OBJECT && yylhsminor.yy483 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy483->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy407 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy407->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[-2].minor.yy483 = yylhsminor.yy483;
+ yymsp[-2].minor.yy407 = yylhsminor.yy407;
break;
- case 112: /* xfullname ::= nm */
-{yymsp[0].minor.yy483 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+ case 113: /* xfullname ::= nm */
+{yymsp[0].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
break;
- case 113: /* xfullname ::= nm DOT nm */
-{yymsp[-2].minor.yy483 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 114: /* xfullname ::= nm DOT nm */
+{yymsp[-2].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 114: /* xfullname ::= nm DOT nm AS nm */
+ case 115: /* xfullname ::= nm DOT nm AS nm */
{
- yymsp[-4].minor.yy483 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
- if( yymsp[-4].minor.yy483 ) yymsp[-4].minor.yy483->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-4].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+ if( yymsp[-4].minor.yy407 ) yymsp[-4].minor.yy407->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 115: /* xfullname ::= nm AS nm */
+ case 116: /* xfullname ::= nm AS nm */
{
- yymsp[-2].minor.yy483 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
- if( yymsp[-2].minor.yy483 ) yymsp[-2].minor.yy483->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-2].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+ if( yymsp[-2].minor.yy407 ) yymsp[-2].minor.yy407->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 116: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy494 = JT_INNER; }
+ case 117: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy100 = JT_INNER; }
break;
- case 117: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy494 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+ case 118: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy100 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
- case 118: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy494 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+ case 119: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy100 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
- case 119: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy494 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ case 120: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy100 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
- case 120: /* on_opt ::= ON expr */
- case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137);
- case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144);
- case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210);
- case 231: /* vinto ::= INTO expr */ yytestcase(yyruleno==231);
-{yymsp[-1].minor.yy524 = yymsp[0].minor.yy524;}
+ case 121: /* on_opt ::= ON expr */
+ case 138: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==138);
+ case 145: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==145);
+ case 211: /* case_else ::= ELSE expr */ yytestcase(yyruleno==211);
+ case 232: /* vinto ::= INTO expr */ yytestcase(yyruleno==232);
+{yymsp[-1].minor.yy102 = yymsp[0].minor.yy102;}
break;
- case 121: /* on_opt ::= */
- case 136: /* having_opt ::= */ yytestcase(yyruleno==136);
- case 138: /* limit_opt ::= */ yytestcase(yyruleno==138);
- case 143: /* where_opt ::= */ yytestcase(yyruleno==143);
- case 211: /* case_else ::= */ yytestcase(yyruleno==211);
- case 213: /* case_operand ::= */ yytestcase(yyruleno==213);
- case 232: /* vinto ::= */ yytestcase(yyruleno==232);
-{yymsp[1].minor.yy524 = 0;}
+ case 122: /* on_opt ::= */
+ case 137: /* having_opt ::= */ yytestcase(yyruleno==137);
+ case 139: /* limit_opt ::= */ yytestcase(yyruleno==139);
+ case 144: /* where_opt ::= */ yytestcase(yyruleno==144);
+ case 212: /* case_else ::= */ yytestcase(yyruleno==212);
+ case 214: /* case_operand ::= */ yytestcase(yyruleno==214);
+ case 233: /* vinto ::= */ yytestcase(yyruleno==233);
+{yymsp[1].minor.yy102 = 0;}
break;
- case 123: /* indexed_opt ::= INDEXED BY nm */
+ case 124: /* indexed_opt ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 124: /* indexed_opt ::= NOT INDEXED */
+ case 125: /* indexed_opt ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
- case 125: /* using_opt ::= USING LP idlist RP */
-{yymsp[-3].minor.yy62 = yymsp[-1].minor.yy62;}
+ case 126: /* using_opt ::= USING LP idlist RP */
+{yymsp[-3].minor.yy76 = yymsp[-1].minor.yy76;}
break;
- case 126: /* using_opt ::= */
- case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
-{yymsp[1].minor.yy62 = 0;}
+ case 127: /* using_opt ::= */
+ case 159: /* idlist_opt ::= */ yytestcase(yyruleno==159);
+{yymsp[1].minor.yy76 = 0;}
break;
- case 128: /* orderby_opt ::= ORDER BY sortlist */
- case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135);
-{yymsp[-2].minor.yy434 = yymsp[0].minor.yy434;}
+ case 129: /* orderby_opt ::= ORDER BY sortlist */
+ case 136: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==136);
+{yymsp[-2].minor.yy94 = yymsp[0].minor.yy94;}
break;
- case 129: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 130: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yymsp[-3].minor.yy434 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy434,yymsp[-1].minor.yy524);
- sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy434,yymsp[0].minor.yy494);
+ yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy94,yymsp[-1].minor.yy102);
+ sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy94,yymsp[0].minor.yy100);
}
break;
- case 130: /* sortlist ::= expr sortorder */
+ case 131: /* sortlist ::= expr sortorder */
{
- yymsp[-1].minor.yy434 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy524); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy434,yymsp[0].minor.yy494);
+ yymsp[-1].minor.yy94 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy102); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy94,yymsp[0].minor.yy100);
}
break;
- case 131: /* sortorder ::= ASC */
-{yymsp[0].minor.yy494 = SQLITE_SO_ASC;}
+ case 132: /* sortorder ::= ASC */
+{yymsp[0].minor.yy100 = SQLITE_SO_ASC;}
break;
- case 132: /* sortorder ::= DESC */
-{yymsp[0].minor.yy494 = SQLITE_SO_DESC;}
+ case 133: /* sortorder ::= DESC */
+{yymsp[0].minor.yy100 = SQLITE_SO_DESC;}
break;
- case 133: /* sortorder ::= */
-{yymsp[1].minor.yy494 = SQLITE_SO_UNDEFINED;}
+ case 134: /* sortorder ::= */
+{yymsp[1].minor.yy100 = SQLITE_SO_UNDEFINED;}
break;
- case 139: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy524 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy524,0);}
+ case 140: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy102,0);}
break;
- case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy524 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy524,yymsp[0].minor.yy524);}
+ case 141: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
break;
- case 141: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy524 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy524,yymsp[-2].minor.yy524);}
+ case 142: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy102,yymsp[-2].minor.yy102);}
break;
- case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ case 143: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy483, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy483,yymsp[0].minor.yy524,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy407, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy407,yymsp[0].minor.yy102,0,0);
}
break;
- case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ case 146: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy483, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy434,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy483,yymsp[-1].minor.yy434,yymsp[0].minor.yy524,yymsp[-5].minor.yy494,0,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy407, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy94,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy407,yymsp[-1].minor.yy94,yymsp[0].minor.yy102,yymsp[-5].minor.yy100,0,0,0);
}
break;
- case 146: /* setlist ::= setlist COMMA nm EQ expr */
+ case 147: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy434 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy434, yymsp[0].minor.yy524);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy434, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy94, yymsp[0].minor.yy102);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy94, &yymsp[-2].minor.yy0, 1);
}
break;
- case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ case 148: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
- yymsp[-6].minor.yy434 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy434, yymsp[-3].minor.yy62, yymsp[0].minor.yy524);
+ yymsp[-6].minor.yy94 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy94, yymsp[-3].minor.yy76, yymsp[0].minor.yy102);
}
break;
- case 148: /* setlist ::= nm EQ expr */
+ case 149: /* setlist ::= nm EQ expr */
{
- yylhsminor.yy434 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy524);
- sqlite3ExprListSetName(pParse, yylhsminor.yy434, &yymsp[-2].minor.yy0, 1);
+ yylhsminor.yy94 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy102);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy94, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy434 = yylhsminor.yy434;
+ yymsp[-2].minor.yy94 = yylhsminor.yy94;
break;
- case 149: /* setlist ::= LP idlist RP EQ expr */
+ case 150: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy434 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy62, yymsp[0].minor.yy524);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy76, yymsp[0].minor.yy102);
}
break;
- case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy483, yymsp[-1].minor.yy457, yymsp[-2].minor.yy62, yymsp[-5].minor.yy494, yymsp[0].minor.yy136);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy407, yymsp[-1].minor.yy391, yymsp[-2].minor.yy76, yymsp[-5].minor.yy100, yymsp[0].minor.yy95);
}
break;
- case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ case 152: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy483, 0, yymsp[-2].minor.yy62, yymsp[-5].minor.yy494, 0);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy407, 0, yymsp[-2].minor.yy76, yymsp[-5].minor.yy100, 0);
}
break;
- case 152: /* upsert ::= */
-{ yymsp[1].minor.yy136 = 0; }
+ case 153: /* upsert ::= */
+{ yymsp[1].minor.yy95 = 0; }
break;
- case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
-{ yymsp[-10].minor.yy136 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy434,yymsp[-5].minor.yy524,yymsp[-1].minor.yy434,yymsp[0].minor.yy524);}
+ case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+{ yymsp[-10].minor.yy95 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy94,yymsp[-5].minor.yy102,yymsp[-1].minor.yy94,yymsp[0].minor.yy102);}
break;
- case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
-{ yymsp[-7].minor.yy136 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy434,yymsp[-2].minor.yy524,0,0); }
+ case 155: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+{ yymsp[-7].minor.yy95 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy94,yymsp[-2].minor.yy102,0,0); }
break;
- case 155: /* upsert ::= ON CONFLICT DO NOTHING */
-{ yymsp[-3].minor.yy136 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
+ case 156: /* upsert ::= ON CONFLICT DO NOTHING */
+{ yymsp[-3].minor.yy95 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
break;
- case 159: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy62 = yymsp[-1].minor.yy62;}
+ case 160: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy76 = yymsp[-1].minor.yy76;}
break;
- case 160: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy62 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy62,&yymsp[0].minor.yy0);}
+ case 161: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy76 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy76,&yymsp[0].minor.yy0);}
break;
- case 161: /* idlist ::= nm */
-{yymsp[0].minor.yy62 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+ case 162: /* idlist ::= nm */
+{yymsp[0].minor.yy76 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 162: /* expr ::= LP expr RP */
-{yymsp[-2].minor.yy524 = yymsp[-1].minor.yy524;}
+ case 163: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy102 = yymsp[-1].minor.yy102;}
break;
- case 163: /* expr ::= ID|INDEXED */
- case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164);
-{yymsp[0].minor.yy524=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 164: /* expr ::= ID|INDEXED */
+ case 165: /* expr ::= JOIN_KW */ yytestcase(yyruleno==165);
+{yymsp[0].minor.yy102=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 165: /* expr ::= nm DOT nm */
+ case 166: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
@@ -151978,11 +152565,11 @@ static YYACTIONTYPE yy_reduce(
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
}
- yylhsminor.yy524 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ yylhsminor.yy102 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
- yymsp[-2].minor.yy524 = yylhsminor.yy524;
+ yymsp[-2].minor.yy102 = yylhsminor.yy102;
break;
- case 166: /* expr ::= nm DOT nm DOT nm */
+ case 167: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
@@ -151992,26 +152579,26 @@ static YYACTIONTYPE yy_reduce(
sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
}
- yylhsminor.yy524 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ yylhsminor.yy102 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
- yymsp[-4].minor.yy524 = yylhsminor.yy524;
+ yymsp[-4].minor.yy102 = yylhsminor.yy102;
break;
- case 167: /* term ::= NULL|FLOAT|BLOB */
- case 168: /* term ::= STRING */ yytestcase(yyruleno==168);
-{yymsp[0].minor.yy524=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 168: /* term ::= NULL|FLOAT|BLOB */
+ case 169: /* term ::= STRING */ yytestcase(yyruleno==169);
+{yymsp[0].minor.yy102=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 169: /* term ::= INTEGER */
+ case 170: /* term ::= INTEGER */
{
- yylhsminor.yy524 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ yylhsminor.yy102 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
}
- yymsp[0].minor.yy524 = yylhsminor.yy524;
+ yymsp[0].minor.yy102 = yylhsminor.yy102;
break;
- case 170: /* expr ::= VARIABLE */
+ case 171: /* expr ::= VARIABLE */
{
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
u32 n = yymsp[0].minor.yy0.n;
- yymsp[0].minor.yy524 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy524, n);
+ yymsp[0].minor.yy102 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy102, n);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
@@ -152020,154 +152607,156 @@ static YYACTIONTYPE yy_reduce(
assert( t.n>=2 );
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy524 = 0;
+ yymsp[0].minor.yy102 = 0;
}else{
- yymsp[0].minor.yy524 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( yymsp[0].minor.yy524 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy524->iTable);
+ yymsp[0].minor.yy102 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy102 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy102->iTable);
}
}
}
break;
- case 171: /* expr ::= expr COLLATE ID|STRING */
+ case 172: /* expr ::= expr COLLATE ID|STRING */
{
- yymsp[-2].minor.yy524 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy524, &yymsp[0].minor.yy0, 1);
+ yymsp[-2].minor.yy102 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy102, &yymsp[0].minor.yy0, 1);
}
break;
- case 172: /* expr ::= CAST LP expr AS typetoken RP */
+ case 173: /* expr ::= CAST LP expr AS typetoken RP */
{
- yymsp[-5].minor.yy524 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy524, yymsp[-3].minor.yy524, 0);
+ yymsp[-5].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy102, yymsp[-3].minor.yy102, 0);
}
break;
- case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ case 174: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- yylhsminor.yy524 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy434, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy494);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy94, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy100);
}
- yymsp[-4].minor.yy524 = yylhsminor.yy524;
+ yymsp[-4].minor.yy102 = yylhsminor.yy102;
break;
- case 174: /* expr ::= ID|INDEXED LP STAR RP */
+ case 175: /* expr ::= ID|INDEXED LP STAR RP */
{
- yylhsminor.yy524 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
- yymsp[-3].minor.yy524 = yylhsminor.yy524;
+ yymsp[-3].minor.yy102 = yylhsminor.yy102;
break;
- case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ case 176: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
{
- yylhsminor.yy524 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy434, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy494);
- sqlite3WindowAttach(pParse, yylhsminor.yy524, yymsp[0].minor.yy295);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy94, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy100);
+ sqlite3WindowAttach(pParse, yylhsminor.yy102, yymsp[0].minor.yy379);
}
- yymsp[-5].minor.yy524 = yylhsminor.yy524;
+ yymsp[-5].minor.yy102 = yylhsminor.yy102;
break;
- case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
+ case 177: /* expr ::= ID|INDEXED LP STAR RP over_clause */
{
- yylhsminor.yy524 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
- sqlite3WindowAttach(pParse, yylhsminor.yy524, yymsp[0].minor.yy295);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+ sqlite3WindowAttach(pParse, yylhsminor.yy102, yymsp[0].minor.yy379);
}
- yymsp[-4].minor.yy524 = yylhsminor.yy524;
+ yymsp[-4].minor.yy102 = yylhsminor.yy102;
break;
- case 177: /* term ::= CTIME_KW */
+ case 178: /* term ::= CTIME_KW */
{
- yylhsminor.yy524 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
- yymsp[0].minor.yy524 = yylhsminor.yy524;
+ yymsp[0].minor.yy102 = yylhsminor.yy102;
break;
- case 178: /* expr ::= LP nexprlist COMMA expr RP */
+ case 179: /* expr ::= LP nexprlist COMMA expr RP */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy434, yymsp[-1].minor.yy524);
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( yymsp[-4].minor.yy524 ){
- yymsp[-4].minor.yy524->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy94, yymsp[-1].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
break;
- case 179: /* expr ::= expr AND expr */
- case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
- case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
- case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
- case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
- case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
- case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
- case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186);
-{yymsp[-2].minor.yy524=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy524,yymsp[0].minor.yy524);}
+ case 180: /* expr ::= expr AND expr */
+{yymsp[-2].minor.yy102=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
+ break;
+ case 181: /* expr ::= expr OR expr */
+ case 182: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==182);
+ case 183: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==183);
+ case 184: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==184);
+ case 185: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==185);
+ case 186: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==186);
+ case 187: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==187);
+{yymsp[-2].minor.yy102=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
break;
- case 187: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 188: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
- case 188: /* expr ::= expr likeop expr */
+ case 189: /* expr ::= expr likeop expr */
{
ExprList *pList;
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
yymsp[-1].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy524);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy524);
- yymsp[-2].minor.yy524 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
- if( bNot ) yymsp[-2].minor.yy524 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy524, 0);
- if( yymsp[-2].minor.yy524 ) yymsp[-2].minor.yy524->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy102);
+ yymsp[-2].minor.yy102 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ if( bNot ) yymsp[-2].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy102, 0);
+ if( yymsp[-2].minor.yy102 ) yymsp[-2].minor.yy102->flags |= EP_InfixFunc;
}
break;
- case 189: /* expr ::= expr likeop expr ESCAPE expr */
+ case 190: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
yymsp[-3].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy524);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy524);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy524);
- yymsp[-4].minor.yy524 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
- if( bNot ) yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy524, 0);
- if( yymsp[-4].minor.yy524 ) yymsp[-4].minor.yy524->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+ if( bNot ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ) yymsp[-4].minor.yy102->flags |= EP_InfixFunc;
}
break;
- case 190: /* expr ::= expr ISNULL|NOTNULL */
-{yymsp[-1].minor.yy524 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy524,0);}
+ case 191: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy102,0);}
break;
- case 191: /* expr ::= expr NOT NULL */
-{yymsp[-2].minor.yy524 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy524,0);}
+ case 192: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy102 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy102,0);}
break;
- case 192: /* expr ::= expr IS expr */
+ case 193: /* expr ::= expr IS expr */
{
- yymsp[-2].minor.yy524 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy524,yymsp[0].minor.yy524);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy524, yymsp[-2].minor.yy524, TK_ISNULL);
+ yymsp[-2].minor.yy102 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy102, yymsp[-2].minor.yy102, TK_ISNULL);
}
break;
- case 193: /* expr ::= expr IS NOT expr */
+ case 194: /* expr ::= expr IS NOT expr */
{
- yymsp[-3].minor.yy524 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy524,yymsp[0].minor.yy524);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy524, yymsp[-3].minor.yy524, TK_NOTNULL);
+ yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy102,yymsp[0].minor.yy102);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy102, yymsp[-3].minor.yy102, TK_NOTNULL);
}
break;
- case 194: /* expr ::= NOT expr */
- case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195);
-{yymsp[-1].minor.yy524 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy524, 0);/*A-overwrites-B*/}
+ case 195: /* expr ::= NOT expr */
+ case 196: /* expr ::= BITNOT expr */ yytestcase(yyruleno==196);
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy102, 0);/*A-overwrites-B*/}
break;
- case 196: /* expr ::= PLUS|MINUS expr */
+ case 197: /* expr ::= PLUS|MINUS expr */
{
- yymsp[-1].minor.yy524 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy524, 0);
+ yymsp[-1].minor.yy102 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy102, 0);
/*A-overwrites-B*/
}
break;
- case 197: /* between_op ::= BETWEEN */
- case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
-{yymsp[0].minor.yy494 = 0;}
+ case 198: /* between_op ::= BETWEEN */
+ case 201: /* in_op ::= IN */ yytestcase(yyruleno==201);
+{yymsp[0].minor.yy100 = 0;}
break;
- case 199: /* expr ::= expr between_op expr AND expr */
+ case 200: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy524);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy524);
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy524, 0);
- if( yymsp[-4].minor.yy524 ){
- yymsp[-4].minor.yy524->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy494 ) yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy524, 0);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
break;
- case 202: /* expr ::= expr in_op LP exprlist RP */
+ case 203: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy434==0 ){
+ if( yymsp[-1].minor.yy94==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -152176,11 +152765,9 @@ static YYACTIONTYPE yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- if( IN_RENAME_OBJECT==0 ){
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy524);
- yymsp[-4].minor.yy524 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy494],1);
- }
- }else if( yymsp[-1].minor.yy434->nExpr==1 ){
+ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy100],1);
+ }else if( yymsp[-1].minor.yy94->nExpr==1 ){
/* Expressions of the form:
**
** expr1 IN (?1)
@@ -152197,199 +152784,199 @@ static YYACTIONTYPE yy_reduce(
** affinity or the collating sequence to use for comparison. Otherwise,
** the semantics would be subtly different from IN or NOT IN.
*/
- Expr *pRHS = yymsp[-1].minor.yy434->a[0].pExpr;
- yymsp[-1].minor.yy434->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy434);
+ Expr *pRHS = yymsp[-1].minor.yy94->a[0].pExpr;
+ yymsp[-1].minor.yy94->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy94);
/* pRHS cannot be NULL because a malloc error would have been detected
** before now and control would have never reached this point */
if( ALWAYS(pRHS) ){
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, yymsp[-3].minor.yy494 ? TK_NE : TK_EQ, yymsp[-4].minor.yy524, pRHS);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, yymsp[-3].minor.yy100 ? TK_NE : TK_EQ, yymsp[-4].minor.yy102, pRHS);
}else{
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy524, 0);
- if( yymsp[-4].minor.yy524 ){
- yymsp[-4].minor.yy524->x.pList = yymsp[-1].minor.yy434;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy524);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = yymsp[-1].minor.yy94;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy102);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy434);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy94);
}
- if( yymsp[-3].minor.yy494 ) yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy524, 0);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
}
break;
- case 203: /* expr ::= LP select RP */
+ case 204: /* expr ::= LP select RP */
{
- yymsp[-2].minor.yy524 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy524, yymsp[-1].minor.yy457);
+ yymsp[-2].minor.yy102 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy102, yymsp[-1].minor.yy391);
}
break;
- case 204: /* expr ::= expr in_op LP select RP */
+ case 205: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy524, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy524, yymsp[-1].minor.yy457);
- if( yymsp[-3].minor.yy494 ) yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy524, 0);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy102, yymsp[-1].minor.yy391);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
break;
- case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 206: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
- if( yymsp[0].minor.yy434 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy434);
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy524, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy524, pSelect);
- if( yymsp[-3].minor.yy494 ) yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy524, 0);
+ if( yymsp[0].minor.yy94 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy94);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy102, pSelect);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
break;
- case 206: /* expr ::= EXISTS LP select RP */
+ case 207: /* expr ::= EXISTS LP select RP */
{
Expr *p;
- p = yymsp[-3].minor.yy524 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy457);
+ p = yymsp[-3].minor.yy102 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy391);
}
break;
- case 207: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 208: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yymsp[-4].minor.yy524 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy524, 0);
- if( yymsp[-4].minor.yy524 ){
- yymsp[-4].minor.yy524->x.pList = yymsp[-1].minor.yy524 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy434,yymsp[-1].minor.yy524) : yymsp[-2].minor.yy434;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy524);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = yymsp[-1].minor.yy102 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy94,yymsp[-1].minor.yy102) : yymsp[-2].minor.yy94;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy102);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy434);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy524);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy94);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy102);
}
}
break;
- case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 209: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yymsp[-4].minor.yy434 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy434, yymsp[-2].minor.yy524);
- yymsp[-4].minor.yy434 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy434, yymsp[0].minor.yy524);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, yymsp[-2].minor.yy102);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, yymsp[0].minor.yy102);
}
break;
- case 209: /* case_exprlist ::= WHEN expr THEN expr */
+ case 210: /* case_exprlist ::= WHEN expr THEN expr */
{
- yymsp[-3].minor.yy434 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy524);
- yymsp[-3].minor.yy434 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy434, yymsp[0].minor.yy524);
+ yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+ yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy94, yymsp[0].minor.yy102);
}
break;
- case 212: /* case_operand ::= expr */
-{yymsp[0].minor.yy524 = yymsp[0].minor.yy524; /*A-overwrites-X*/}
+ case 213: /* case_operand ::= expr */
+{yymsp[0].minor.yy102 = yymsp[0].minor.yy102; /*A-overwrites-X*/}
break;
- case 215: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy434 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy434,yymsp[0].minor.yy524);}
+ case 216: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy94,yymsp[0].minor.yy102);}
break;
- case 216: /* nexprlist ::= expr */
-{yymsp[0].minor.yy434 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy524); /*A-overwrites-Y*/}
+ case 217: /* nexprlist ::= expr */
+{yymsp[0].minor.yy94 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy102); /*A-overwrites-Y*/}
break;
- case 218: /* paren_exprlist ::= LP exprlist RP */
- case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223);
-{yymsp[-2].minor.yy434 = yymsp[-1].minor.yy434;}
+ case 219: /* paren_exprlist ::= LP exprlist RP */
+ case 224: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==224);
+{yymsp[-2].minor.yy94 = yymsp[-1].minor.yy94;}
break;
- case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 220: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
- sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy434, yymsp[-10].minor.yy494,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy524, SQLITE_SO_ASC, yymsp[-8].minor.yy494, SQLITE_IDXTYPE_APPDEF);
+ sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy94, yymsp[-10].minor.yy100,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy102, SQLITE_SO_ASC, yymsp[-8].minor.yy100, SQLITE_IDXTYPE_APPDEF);
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
}
}
break;
- case 220: /* uniqueflag ::= UNIQUE */
- case 262: /* raisetype ::= ABORT */ yytestcase(yyruleno==262);
-{yymsp[0].minor.yy494 = OE_Abort;}
+ case 221: /* uniqueflag ::= UNIQUE */
+ case 263: /* raisetype ::= ABORT */ yytestcase(yyruleno==263);
+{yymsp[0].minor.yy100 = OE_Abort;}
break;
- case 221: /* uniqueflag ::= */
-{yymsp[1].minor.yy494 = OE_None;}
+ case 222: /* uniqueflag ::= */
+{yymsp[1].minor.yy100 = OE_None;}
break;
- case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 225: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
- yymsp[-4].minor.yy434 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy434, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy494, yymsp[0].minor.yy494);
+ yymsp[-4].minor.yy94 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy94, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy100, yymsp[0].minor.yy100);
}
break;
- case 225: /* eidlist ::= nm collate sortorder */
+ case 226: /* eidlist ::= nm collate sortorder */
{
- yymsp[-2].minor.yy434 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy494, yymsp[0].minor.yy494); /*A-overwrites-Y*/
+ yymsp[-2].minor.yy94 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy100, yymsp[0].minor.yy100); /*A-overwrites-Y*/
}
break;
- case 228: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy483, yymsp[-1].minor.yy494);}
+ case 229: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy407, yymsp[-1].minor.yy100);}
break;
- case 229: /* cmd ::= VACUUM vinto */
-{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy524);}
+ case 230: /* cmd ::= VACUUM vinto */
+{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy102);}
break;
- case 230: /* cmd ::= VACUUM nm vinto */
-{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy524);}
+ case 231: /* cmd ::= VACUUM nm vinto */
+{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy102);}
break;
- case 233: /* cmd ::= PRAGMA nm dbnm */
+ case 234: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 234: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 235: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 235: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 236: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 236: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 237: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 237: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 238: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 240: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 241: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy455, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy11, &all);
}
break;
- case 241: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 242: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy494, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy483, yymsp[0].minor.yy524, yymsp[-10].minor.yy494, yymsp[-8].minor.yy494);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy100, yymsp[-4].minor.yy298.a, yymsp[-4].minor.yy298.b, yymsp[-2].minor.yy407, yymsp[0].minor.yy102, yymsp[-10].minor.yy100, yymsp[-8].minor.yy100);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 242: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy494 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 243: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 243: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy494 = TK_INSTEAD;}
+ case 244: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy100 = TK_INSTEAD;}
break;
- case 244: /* trigger_time ::= */
-{ yymsp[1].minor.yy494 = TK_BEFORE; }
+ case 245: /* trigger_time ::= */
+{ yymsp[1].minor.yy100 = TK_BEFORE; }
break;
- case 245: /* trigger_event ::= DELETE|INSERT */
- case 246: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==246);
-{yymsp[0].minor.yy90.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy90.b = 0;}
+ case 246: /* trigger_event ::= DELETE|INSERT */
+ case 247: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==247);
+{yymsp[0].minor.yy298.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy298.b = 0;}
break;
- case 247: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy90.a = TK_UPDATE; yymsp[-2].minor.yy90.b = yymsp[0].minor.yy62;}
+ case 248: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy298.a = TK_UPDATE; yymsp[-2].minor.yy298.b = yymsp[0].minor.yy76;}
break;
- case 248: /* when_clause ::= */
- case 267: /* key_opt ::= */ yytestcase(yyruleno==267);
- case 315: /* filter_opt ::= */ yytestcase(yyruleno==315);
-{ yymsp[1].minor.yy524 = 0; }
+ case 249: /* when_clause ::= */
+ case 268: /* key_opt ::= */ yytestcase(yyruleno==268);
+ case 316: /* filter_opt ::= */ yytestcase(yyruleno==316);
+{ yymsp[1].minor.yy102 = 0; }
break;
- case 249: /* when_clause ::= WHEN expr */
- case 268: /* key_opt ::= KEY expr */ yytestcase(yyruleno==268);
-{ yymsp[-1].minor.yy524 = yymsp[0].minor.yy524; }
+ case 250: /* when_clause ::= WHEN expr */
+ case 269: /* key_opt ::= KEY expr */ yytestcase(yyruleno==269);
+{ yymsp[-1].minor.yy102 = yymsp[0].minor.yy102; }
break;
- case 250: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 251: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy455!=0 );
- yymsp[-2].minor.yy455->pLast->pNext = yymsp[-1].minor.yy455;
- yymsp[-2].minor.yy455->pLast = yymsp[-1].minor.yy455;
+ assert( yymsp[-2].minor.yy11!=0 );
+ yymsp[-2].minor.yy11->pLast->pNext = yymsp[-1].minor.yy11;
+ yymsp[-2].minor.yy11->pLast = yymsp[-1].minor.yy11;
}
break;
- case 251: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 252: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy455!=0 );
- yymsp[-1].minor.yy455->pLast = yymsp[-1].minor.yy455;
+ assert( yymsp[-1].minor.yy11!=0 );
+ yymsp[-1].minor.yy11->pLast = yymsp[-1].minor.yy11;
}
break;
- case 252: /* trnm ::= nm DOT nm */
+ case 253: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -152397,328 +152984,328 @@ static YYACTIONTYPE yy_reduce(
"statements within triggers");
}
break;
- case 253: /* tridxby ::= INDEXED BY nm */
+ case 254: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 254: /* tridxby ::= NOT INDEXED */
+ case 255: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 255: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
-{yylhsminor.yy455 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy434, yymsp[-1].minor.yy524, yymsp[-6].minor.yy494, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy294);}
- yymsp[-7].minor.yy455 = yylhsminor.yy455;
+ case 256: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+{yylhsminor.yy11 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy94, yymsp[-1].minor.yy102, yymsp[-6].minor.yy100, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy528);}
+ yymsp[-7].minor.yy11 = yylhsminor.yy11;
break;
- case 256: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ case 257: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
- yylhsminor.yy455 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy62,yymsp[-2].minor.yy457,yymsp[-6].minor.yy494,yymsp[-1].minor.yy136,yymsp[-7].minor.yy294,yymsp[0].minor.yy294);/*yylhsminor.yy455-overwrites-yymsp[-6].minor.yy494*/
+ yylhsminor.yy11 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy76,yymsp[-2].minor.yy391,yymsp[-6].minor.yy100,yymsp[-1].minor.yy95,yymsp[-7].minor.yy528,yymsp[0].minor.yy528);/*yylhsminor.yy11-overwrites-yymsp[-6].minor.yy100*/
}
- yymsp[-7].minor.yy455 = yylhsminor.yy455;
+ yymsp[-7].minor.yy11 = yylhsminor.yy11;
break;
- case 257: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-{yylhsminor.yy455 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy524, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy294);}
- yymsp[-5].minor.yy455 = yylhsminor.yy455;
+ case 258: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy11 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy102, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy528);}
+ yymsp[-5].minor.yy11 = yylhsminor.yy11;
break;
- case 258: /* trigger_cmd ::= scanpt select scanpt */
-{yylhsminor.yy455 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy457, yymsp[-2].minor.yy294, yymsp[0].minor.yy294); /*yylhsminor.yy455-overwrites-yymsp[-1].minor.yy457*/}
- yymsp[-2].minor.yy455 = yylhsminor.yy455;
+ case 259: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy11 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy391, yymsp[-2].minor.yy528, yymsp[0].minor.yy528); /*yylhsminor.yy11-overwrites-yymsp[-1].minor.yy391*/}
+ yymsp[-2].minor.yy11 = yylhsminor.yy11;
break;
- case 259: /* expr ::= RAISE LP IGNORE RP */
+ case 260: /* expr ::= RAISE LP IGNORE RP */
{
- yymsp[-3].minor.yy524 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( yymsp[-3].minor.yy524 ){
- yymsp[-3].minor.yy524->affinity = OE_Ignore;
+ yymsp[-3].minor.yy102 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy102 ){
+ yymsp[-3].minor.yy102->affinity = OE_Ignore;
}
}
break;
- case 260: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 261: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yymsp[-5].minor.yy524 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
- if( yymsp[-5].minor.yy524 ) {
- yymsp[-5].minor.yy524->affinity = (char)yymsp[-3].minor.yy494;
+ yymsp[-5].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
+ if( yymsp[-5].minor.yy102 ) {
+ yymsp[-5].minor.yy102->affinity = (char)yymsp[-3].minor.yy100;
}
}
break;
- case 261: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy494 = OE_Rollback;}
+ case 262: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy100 = OE_Rollback;}
break;
- case 263: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy494 = OE_Fail;}
+ case 264: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy100 = OE_Fail;}
break;
- case 264: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 265: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy483,yymsp[-1].minor.yy494);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy407,yymsp[-1].minor.yy100);
}
break;
- case 265: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 266: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy524, yymsp[-1].minor.yy524, yymsp[0].minor.yy524);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy102, yymsp[-1].minor.yy102, yymsp[0].minor.yy102);
}
break;
- case 266: /* cmd ::= DETACH database_kw_opt expr */
+ case 267: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy524);
+ sqlite3Detach(pParse, yymsp[0].minor.yy102);
}
break;
- case 269: /* cmd ::= REINDEX */
+ case 270: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 270: /* cmd ::= REINDEX nm dbnm */
+ case 271: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 271: /* cmd ::= ANALYZE */
+ case 272: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 272: /* cmd ::= ANALYZE nm dbnm */
+ case 273: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 273: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 274: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy483,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy407,&yymsp[0].minor.yy0);
}
break;
- case 274: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 275: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
- case 275: /* add_column_fullname ::= fullname */
+ case 276: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy483);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy407);
}
break;
- case 276: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ case 277: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
- sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy483, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy407, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 277: /* cmd ::= create_vtab */
+ case 278: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 278: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 279: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 279: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 280: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy494);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy100);
}
break;
- case 280: /* vtabarg ::= */
+ case 281: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 281: /* vtabargtoken ::= ANY */
- case 282: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==282);
- case 283: /* lp ::= LP */ yytestcase(yyruleno==283);
+ case 282: /* vtabargtoken ::= ANY */
+ case 283: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==283);
+ case 284: /* lp ::= LP */ yytestcase(yyruleno==284);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 284: /* with ::= WITH wqlist */
- case 285: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==285);
-{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); }
+ case 285: /* with ::= WITH wqlist */
+ case 286: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==286);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy243, 1); }
break;
- case 286: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 287: /* wqlist ::= nm eidlist_opt AS LP select RP */
{
- yymsp[-5].minor.yy59 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy434, yymsp[-1].minor.yy457); /*A-overwrites-X*/
+ yymsp[-5].minor.yy243 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy94, yymsp[-1].minor.yy391); /*A-overwrites-X*/
}
break;
- case 287: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 288: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
{
- yymsp[-7].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy59, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy434, yymsp[-1].minor.yy457);
+ yymsp[-7].minor.yy243 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy243, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy94, yymsp[-1].minor.yy391);
}
break;
- case 288: /* windowdefn_list ::= windowdefn */
-{ yylhsminor.yy295 = yymsp[0].minor.yy295; }
- yymsp[0].minor.yy295 = yylhsminor.yy295;
+ case 289: /* windowdefn_list ::= windowdefn */
+{ yylhsminor.yy379 = yymsp[0].minor.yy379; }
+ yymsp[0].minor.yy379 = yylhsminor.yy379;
break;
- case 289: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ case 290: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
- assert( yymsp[0].minor.yy295!=0 );
- sqlite3WindowChain(pParse, yymsp[0].minor.yy295, yymsp[-2].minor.yy295);
- yymsp[0].minor.yy295->pNextWin = yymsp[-2].minor.yy295;
- yylhsminor.yy295 = yymsp[0].minor.yy295;
+ assert( yymsp[0].minor.yy379!=0 );
+ sqlite3WindowChain(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy379);
+ yymsp[0].minor.yy379->pNextWin = yymsp[-2].minor.yy379;
+ yylhsminor.yy379 = yymsp[0].minor.yy379;
}
- yymsp[-2].minor.yy295 = yylhsminor.yy295;
+ yymsp[-2].minor.yy379 = yylhsminor.yy379;
break;
- case 290: /* windowdefn ::= nm AS LP window RP */
+ case 291: /* windowdefn ::= nm AS LP window RP */
{
- if( ALWAYS(yymsp[-1].minor.yy295) ){
- yymsp[-1].minor.yy295->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
+ if( ALWAYS(yymsp[-1].minor.yy379) ){
+ yymsp[-1].minor.yy379->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
}
- yylhsminor.yy295 = yymsp[-1].minor.yy295;
+ yylhsminor.yy379 = yymsp[-1].minor.yy379;
}
- yymsp[-4].minor.yy295 = yylhsminor.yy295;
+ yymsp[-4].minor.yy379 = yylhsminor.yy379;
break;
- case 291: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ case 292: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
- yymsp[-4].minor.yy295 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy295, yymsp[-2].minor.yy434, yymsp[-1].minor.yy434, 0);
+ yymsp[-4].minor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy94, yymsp[-1].minor.yy94, 0);
}
break;
- case 292: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ case 293: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
- yylhsminor.yy295 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy295, yymsp[-2].minor.yy434, yymsp[-1].minor.yy434, &yymsp[-5].minor.yy0);
+ yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy94, yymsp[-1].minor.yy94, &yymsp[-5].minor.yy0);
}
- yymsp[-5].minor.yy295 = yylhsminor.yy295;
+ yymsp[-5].minor.yy379 = yylhsminor.yy379;
break;
- case 293: /* window ::= ORDER BY sortlist frame_opt */
+ case 294: /* window ::= ORDER BY sortlist frame_opt */
{
- yymsp[-3].minor.yy295 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy295, 0, yymsp[-1].minor.yy434, 0);
+ yymsp[-3].minor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, yymsp[-1].minor.yy94, 0);
}
break;
- case 294: /* window ::= nm ORDER BY sortlist frame_opt */
+ case 295: /* window ::= nm ORDER BY sortlist frame_opt */
{
- yylhsminor.yy295 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy295, 0, yymsp[-1].minor.yy434, &yymsp[-4].minor.yy0);
+ yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, yymsp[-1].minor.yy94, &yymsp[-4].minor.yy0);
}
- yymsp[-4].minor.yy295 = yylhsminor.yy295;
+ yymsp[-4].minor.yy379 = yylhsminor.yy379;
break;
- case 295: /* window ::= frame_opt */
+ case 296: /* window ::= frame_opt */
{
- yylhsminor.yy295 = yymsp[0].minor.yy295;
+ yylhsminor.yy379 = yymsp[0].minor.yy379;
}
- yymsp[0].minor.yy295 = yylhsminor.yy295;
+ yymsp[0].minor.yy379 = yylhsminor.yy379;
break;
- case 296: /* window ::= nm frame_opt */
+ case 297: /* window ::= nm frame_opt */
{
- yylhsminor.yy295 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy295, 0, 0, &yymsp[-1].minor.yy0);
+ yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, 0, &yymsp[-1].minor.yy0);
}
- yymsp[-1].minor.yy295 = yylhsminor.yy295;
+ yymsp[-1].minor.yy379 = yylhsminor.yy379;
break;
- case 297: /* frame_opt ::= */
+ case 298: /* frame_opt ::= */
{
- yymsp[1].minor.yy295 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
+ yymsp[1].minor.yy379 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
break;
- case 298: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ case 299: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
- yylhsminor.yy295 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy494, yymsp[-1].minor.yy201.eType, yymsp[-1].minor.yy201.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy238);
+ yylhsminor.yy379 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy100, yymsp[-1].minor.yy389.eType, yymsp[-1].minor.yy389.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy218);
}
- yymsp[-2].minor.yy295 = yylhsminor.yy295;
+ yymsp[-2].minor.yy379 = yylhsminor.yy379;
break;
- case 299: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ case 300: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
- yylhsminor.yy295 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy494, yymsp[-3].minor.yy201.eType, yymsp[-3].minor.yy201.pExpr, yymsp[-1].minor.yy201.eType, yymsp[-1].minor.yy201.pExpr, yymsp[0].minor.yy238);
+ yylhsminor.yy379 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy100, yymsp[-3].minor.yy389.eType, yymsp[-3].minor.yy389.pExpr, yymsp[-1].minor.yy389.eType, yymsp[-1].minor.yy389.pExpr, yymsp[0].minor.yy218);
}
- yymsp[-5].minor.yy295 = yylhsminor.yy295;
+ yymsp[-5].minor.yy379 = yylhsminor.yy379;
break;
- case 301: /* frame_bound_s ::= frame_bound */
- case 303: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==303);
-{yylhsminor.yy201 = yymsp[0].minor.yy201;}
- yymsp[0].minor.yy201 = yylhsminor.yy201;
+ case 302: /* frame_bound_s ::= frame_bound */
+ case 304: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==304);
+{yylhsminor.yy389 = yymsp[0].minor.yy389;}
+ yymsp[0].minor.yy389 = yylhsminor.yy389;
break;
- case 302: /* frame_bound_s ::= UNBOUNDED PRECEDING */
- case 304: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==304);
- case 306: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==306);
-{yylhsminor.yy201.eType = yymsp[-1].major; yylhsminor.yy201.pExpr = 0;}
- yymsp[-1].minor.yy201 = yylhsminor.yy201;
+ case 303: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+ case 305: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==305);
+ case 307: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==307);
+{yylhsminor.yy389.eType = yymsp[-1].major; yylhsminor.yy389.pExpr = 0;}
+ yymsp[-1].minor.yy389 = yylhsminor.yy389;
break;
- case 305: /* frame_bound ::= expr PRECEDING|FOLLOWING */
-{yylhsminor.yy201.eType = yymsp[0].major; yylhsminor.yy201.pExpr = yymsp[-1].minor.yy524;}
- yymsp[-1].minor.yy201 = yylhsminor.yy201;
+ case 306: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+{yylhsminor.yy389.eType = yymsp[0].major; yylhsminor.yy389.pExpr = yymsp[-1].minor.yy102;}
+ yymsp[-1].minor.yy389 = yylhsminor.yy389;
break;
- case 307: /* frame_exclude_opt ::= */
-{yymsp[1].minor.yy238 = 0;}
+ case 308: /* frame_exclude_opt ::= */
+{yymsp[1].minor.yy218 = 0;}
break;
- case 308: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
-{yymsp[-1].minor.yy238 = yymsp[0].minor.yy238;}
+ case 309: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+{yymsp[-1].minor.yy218 = yymsp[0].minor.yy218;}
break;
- case 309: /* frame_exclude ::= NO OTHERS */
- case 310: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==310);
-{yymsp[-1].minor.yy238 = yymsp[-1].major; /*A-overwrites-X*/}
+ case 310: /* frame_exclude ::= NO OTHERS */
+ case 311: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==311);
+{yymsp[-1].minor.yy218 = yymsp[-1].major; /*A-overwrites-X*/}
break;
- case 311: /* frame_exclude ::= GROUP|TIES */
-{yymsp[0].minor.yy238 = yymsp[0].major; /*A-overwrites-X*/}
+ case 312: /* frame_exclude ::= GROUP|TIES */
+{yymsp[0].minor.yy218 = yymsp[0].major; /*A-overwrites-X*/}
break;
- case 312: /* window_clause ::= WINDOW windowdefn_list */
-{ yymsp[-1].minor.yy295 = yymsp[0].minor.yy295; }
+ case 313: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy379 = yymsp[0].minor.yy379; }
break;
- case 313: /* over_clause ::= filter_opt OVER LP window RP */
+ case 314: /* over_clause ::= filter_opt OVER LP window RP */
{
- yylhsminor.yy295 = yymsp[-1].minor.yy295;
- assert( yylhsminor.yy295!=0 );
- yylhsminor.yy295->pFilter = yymsp[-4].minor.yy524;
+ yylhsminor.yy379 = yymsp[-1].minor.yy379;
+ assert( yylhsminor.yy379!=0 );
+ yylhsminor.yy379->pFilter = yymsp[-4].minor.yy102;
}
- yymsp[-4].minor.yy295 = yylhsminor.yy295;
+ yymsp[-4].minor.yy379 = yylhsminor.yy379;
break;
- case 314: /* over_clause ::= filter_opt OVER nm */
+ case 315: /* over_clause ::= filter_opt OVER nm */
{
- yylhsminor.yy295 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yylhsminor.yy295 ){
- yylhsminor.yy295->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
- yylhsminor.yy295->pFilter = yymsp[-2].minor.yy524;
+ yylhsminor.yy379 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yylhsminor.yy379 ){
+ yylhsminor.yy379->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+ yylhsminor.yy379->pFilter = yymsp[-2].minor.yy102;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy524);
+ sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy102);
}
}
- yymsp[-2].minor.yy295 = yylhsminor.yy295;
+ yymsp[-2].minor.yy379 = yylhsminor.yy379;
break;
- case 316: /* filter_opt ::= FILTER LP WHERE expr RP */
-{ yymsp[-4].minor.yy524 = yymsp[-1].minor.yy524; }
+ case 317: /* filter_opt ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy102 = yymsp[-1].minor.yy102; }
break;
default:
- /* (317) input ::= cmdlist */ yytestcase(yyruleno==317);
- /* (318) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==318);
- /* (319) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=319);
- /* (320) ecmd ::= SEMI */ yytestcase(yyruleno==320);
- /* (321) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==321);
- /* (322) ecmd ::= explain cmdx */ yytestcase(yyruleno==322);
- /* (323) trans_opt ::= */ yytestcase(yyruleno==323);
- /* (324) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==324);
- /* (325) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==325);
- /* (326) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==326);
- /* (327) savepoint_opt ::= */ yytestcase(yyruleno==327);
- /* (328) cmd ::= create_table create_table_args */ yytestcase(yyruleno==328);
- /* (329) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==329);
- /* (330) columnlist ::= columnname carglist */ yytestcase(yyruleno==330);
- /* (331) nm ::= ID|INDEXED */ yytestcase(yyruleno==331);
- /* (332) nm ::= STRING */ yytestcase(yyruleno==332);
- /* (333) nm ::= JOIN_KW */ yytestcase(yyruleno==333);
- /* (334) typetoken ::= typename */ yytestcase(yyruleno==334);
- /* (335) typename ::= ID|STRING */ yytestcase(yyruleno==335);
- /* (336) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=336);
- /* (337) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=337);
- /* (338) carglist ::= carglist ccons */ yytestcase(yyruleno==338);
- /* (339) carglist ::= */ yytestcase(yyruleno==339);
- /* (340) ccons ::= NULL onconf */ yytestcase(yyruleno==340);
- /* (341) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==341);
- /* (342) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==342);
- /* (343) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=343);
- /* (344) tconscomma ::= */ yytestcase(yyruleno==344);
- /* (345) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=345);
- /* (346) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=346);
- /* (347) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=347);
- /* (348) oneselect ::= values */ yytestcase(yyruleno==348);
- /* (349) sclp ::= selcollist COMMA */ yytestcase(yyruleno==349);
- /* (350) as ::= ID|STRING */ yytestcase(yyruleno==350);
- /* (351) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=351);
- /* (352) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==352);
- /* (353) exprlist ::= nexprlist */ yytestcase(yyruleno==353);
- /* (354) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=354);
- /* (355) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=355);
- /* (356) nmnum ::= ON */ yytestcase(yyruleno==356);
- /* (357) nmnum ::= DELETE */ yytestcase(yyruleno==357);
- /* (358) nmnum ::= DEFAULT */ yytestcase(yyruleno==358);
- /* (359) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==359);
- /* (360) foreach_clause ::= */ yytestcase(yyruleno==360);
- /* (361) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==361);
- /* (362) trnm ::= nm */ yytestcase(yyruleno==362);
- /* (363) tridxby ::= */ yytestcase(yyruleno==363);
- /* (364) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==364);
- /* (365) database_kw_opt ::= */ yytestcase(yyruleno==365);
- /* (366) kwcolumn_opt ::= */ yytestcase(yyruleno==366);
- /* (367) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==367);
- /* (368) vtabarglist ::= vtabarg */ yytestcase(yyruleno==368);
- /* (369) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==369);
- /* (370) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==370);
- /* (371) anylist ::= */ yytestcase(yyruleno==371);
- /* (372) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==372);
- /* (373) anylist ::= anylist ANY */ yytestcase(yyruleno==373);
- /* (374) with ::= */ yytestcase(yyruleno==374);
+ /* (318) input ::= cmdlist */ yytestcase(yyruleno==318);
+ /* (319) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==319);
+ /* (320) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=320);
+ /* (321) ecmd ::= SEMI */ yytestcase(yyruleno==321);
+ /* (322) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==322);
+ /* (323) ecmd ::= explain cmdx */ yytestcase(yyruleno==323);
+ /* (324) trans_opt ::= */ yytestcase(yyruleno==324);
+ /* (325) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==325);
+ /* (326) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==326);
+ /* (327) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==327);
+ /* (328) savepoint_opt ::= */ yytestcase(yyruleno==328);
+ /* (329) cmd ::= create_table create_table_args */ yytestcase(yyruleno==329);
+ /* (330) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==330);
+ /* (331) columnlist ::= columnname carglist */ yytestcase(yyruleno==331);
+ /* (332) nm ::= ID|INDEXED */ yytestcase(yyruleno==332);
+ /* (333) nm ::= STRING */ yytestcase(yyruleno==333);
+ /* (334) nm ::= JOIN_KW */ yytestcase(yyruleno==334);
+ /* (335) typetoken ::= typename */ yytestcase(yyruleno==335);
+ /* (336) typename ::= ID|STRING */ yytestcase(yyruleno==336);
+ /* (337) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=337);
+ /* (338) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=338);
+ /* (339) carglist ::= carglist ccons */ yytestcase(yyruleno==339);
+ /* (340) carglist ::= */ yytestcase(yyruleno==340);
+ /* (341) ccons ::= NULL onconf */ yytestcase(yyruleno==341);
+ /* (342) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==342);
+ /* (343) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==343);
+ /* (344) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=344);
+ /* (345) tconscomma ::= */ yytestcase(yyruleno==345);
+ /* (346) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=346);
+ /* (347) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=347);
+ /* (348) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=348);
+ /* (349) oneselect ::= values */ yytestcase(yyruleno==349);
+ /* (350) sclp ::= selcollist COMMA */ yytestcase(yyruleno==350);
+ /* (351) as ::= ID|STRING */ yytestcase(yyruleno==351);
+ /* (352) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=352);
+ /* (353) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==353);
+ /* (354) exprlist ::= nexprlist */ yytestcase(yyruleno==354);
+ /* (355) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=355);
+ /* (356) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=356);
+ /* (357) nmnum ::= ON */ yytestcase(yyruleno==357);
+ /* (358) nmnum ::= DELETE */ yytestcase(yyruleno==358);
+ /* (359) nmnum ::= DEFAULT */ yytestcase(yyruleno==359);
+ /* (360) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==360);
+ /* (361) foreach_clause ::= */ yytestcase(yyruleno==361);
+ /* (362) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==362);
+ /* (363) trnm ::= nm */ yytestcase(yyruleno==363);
+ /* (364) tridxby ::= */ yytestcase(yyruleno==364);
+ /* (365) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==365);
+ /* (366) database_kw_opt ::= */ yytestcase(yyruleno==366);
+ /* (367) kwcolumn_opt ::= */ yytestcase(yyruleno==367);
+ /* (368) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==368);
+ /* (369) vtabarglist ::= vtabarg */ yytestcase(yyruleno==369);
+ /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==370);
+ /* (371) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==371);
+ /* (372) anylist ::= */ yytestcase(yyruleno==372);
+ /* (373) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==373);
+ /* (374) anylist ::= anylist ANY */ yytestcase(yyruleno==374);
+ /* (375) with ::= */ yytestcase(yyruleno==375);
break;
/********** End reduce actions ************************************************/
};
@@ -155460,6 +156047,9 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
{ SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema|
SQLITE_NoSchemaError },
+ { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter },
+ { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL },
+ { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -155490,28 +156080,17 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
return rc;
}
-
-/*
-** Return true if the buffer z[0..n-1] contains all spaces.
-*/
-static int allSpaces(const char *z, int n){
- while( n>0 && z[n-1]==' ' ){ n--; }
- return n==0;
-}
-
/*
** This is the default collating function named "BINARY" which is always
** available.
-**
-** If the padFlag argument is not NULL then space padding at the end
-** of strings is ignored. This implements the RTRIM collation.
*/
static int binCollFunc(
- void *padFlag,
+ void *NotUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
int rc, n;
+ UNUSED_PARAMETER(NotUsed);
n = nKey1<nKey2 ? nKey1 : nKey2;
/* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
** strings byte by byte using the memcmp() function from the standard C
@@ -155519,29 +156098,33 @@ static int binCollFunc(
assert( pKey1 && pKey2 );
rc = memcmp(pKey1, pKey2, n);
if( rc==0 ){
- if( padFlag
- && allSpaces(((char*)pKey1)+n, nKey1-n)
- && allSpaces(((char*)pKey2)+n, nKey2-n)
- ){
- /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
- ** spaces at the end of either string do not change the result. In other
- ** words, strings will compare equal to one another as long as they
- ** differ only in the number of spaces at the end.
- */
- }else{
- rc = nKey1 - nKey2;
- }
+ rc = nKey1 - nKey2;
}
return rc;
}
/*
+** This is the collating function named "RTRIM" which is always
+** available. Ignore trailing spaces.
+*/
+static int rtrimCollFunc(
+ void *pUser,
+ int nKey1, const void *pKey1,
+ int nKey2, const void *pKey2
+){
+ const u8 *pK1 = (const u8*)pKey1;
+ const u8 *pK2 = (const u8*)pKey2;
+ while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--;
+ while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--;
+ return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2);
+}
+
+/*
** Return true if CollSeq is the default built-in BINARY.
*/
SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){
- assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
- || strcmp(p->zName,"BINARY")==0 );
- return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
+ assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
+ return p==0 || p->xCmp==binCollFunc;
}
/*
@@ -157692,7 +158275,35 @@ static int openDatabase(
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
- db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+ db->flags |= SQLITE_ShortColNames
+ | SQLITE_EnableTrigger
+ | SQLITE_CacheSpill
+
+/* The SQLITE_DQS compile-time option determines the default settings
+** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
+**
+** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
+** ---------- ----------------------- -----------------------
+** undefined on on
+** 3 on on
+** 2 on off
+** 1 off on
+** 0 off off
+**
+** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
+** and so that is the default. But developers are encouranged to use
+** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
+*/
+#if !defined(SQLITE_DQS)
+# define SQLITE_DQS 3
+#endif
+#if (SQLITE_DQS&1)==1
+ | SQLITE_DqsDML
+#endif
+#if (SQLITE_DQS&2)==2
+ | SQLITE_DqsDDL
+#endif
+
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
@@ -157743,7 +158354,7 @@ static int openDatabase(
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
- createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
+ createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
@@ -158719,6 +159330,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
#endif /* defined(YYCOVERAGE) */
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
+ **
+ ** This test-control causes the most recent sqlite3_result_int64() value
+ ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally,
+ ** MEM_IntReal values only arise during an INSERT operation of integer
+ ** values into a REAL column, so they can be challenging to test. This
+ ** test-control enables us to write an intreal() SQL function that can
+ ** inject an intreal() value at arbitrary places in an SQL statement,
+ ** for testing purposes.
+ */
+ case SQLITE_TESTCTRL_RESULT_INTREAL: {
+ sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
+ sqlite3ResultIntReal(pCtx);
+ break;
+ }
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
@@ -172997,14 +173624,14 @@ static void fts3ColumnFilter(
nList -= (int)(p - pList);
pList = p;
- if( nList==0 ){
+ if( nList<=0 ){
break;
}
p = &pList[1];
p += fts3GetVarint32(p, &iCurrent);
}
- if( bZero && &pList[nList]!=pEnd ){
+ if( bZero && (pEnd - &pList[nList])>0){
memset(&pList[nList], 0, pEnd - &pList[nList]);
}
*ppList = pList;
@@ -174132,7 +174759,7 @@ static int nodeReaderNext(NodeReader *p){
}
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
- if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
+ if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
return FTS_CORRUPT_VTAB;
}
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
@@ -174151,7 +174778,7 @@ static int nodeReaderNext(NodeReader *p){
}
}
- assert( p->iOff<=p->nNode );
+ assert_fts3_nc( p->iOff<=p->nNode );
return rc;
}
@@ -174312,7 +174939,7 @@ static int fts3AppendToNode(
/* Node must have already been started. There must be a doclist for a
** leaf node, and there must not be a doclist for an internal node. */
assert( pNode->n>0 );
- assert( (pNode->a[0]=='\0')==(aDoclist!=0) );
+ assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) );
blobGrowBuffer(pPrev, nTerm, &rc);
if( rc!=SQLITE_OK ) return rc;
@@ -174528,7 +175155,7 @@ static int fts3TermCmp(
int nCmp = MIN(nLhs, nRhs);
int res;
- res = memcmp(zLhs, zRhs, nCmp);
+ res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
if( res==0 ) res = nLhs - nRhs;
return res;
@@ -174660,10 +175287,13 @@ static int fts3IncrmergeLoad(
pNode = &pWriter->aNodeWriter[nHeight];
pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight;
- blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc);
+ blobGrowBuffer(&pNode->block,
+ MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc
+ );
if( rc==SQLITE_OK ){
memcpy(pNode->block.a, aRoot, nRoot);
pNode->block.n = nRoot;
+ memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
}
for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
@@ -174671,23 +175301,28 @@ static int fts3IncrmergeLoad(
pNode = &pWriter->aNodeWriter[i];
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
- while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
- blobGrowBuffer(&pNode->key, reader.term.n, &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->key.a, reader.term.a, reader.term.n);
- pNode->key.n = reader.term.n;
- if( i>0 ){
- char *aBlock = 0;
- int nBlock = 0;
- pNode = &pWriter->aNodeWriter[i-1];
- pNode->iBlock = reader.iChild;
- rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
- blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->block.a, aBlock, nBlock);
- pNode->block.n = nBlock;
+ if( reader.aNode ){
+ while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
+ blobGrowBuffer(&pNode->key, reader.term.n, &rc);
+ if( rc==SQLITE_OK ){
+ memcpy(pNode->key.a, reader.term.a, reader.term.n);
+ pNode->key.n = reader.term.n;
+ if( i>0 ){
+ char *aBlock = 0;
+ int nBlock = 0;
+ pNode = &pWriter->aNodeWriter[i-1];
+ pNode->iBlock = reader.iChild;
+ rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
+ blobGrowBuffer(&pNode->block,
+ MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
+ );
+ if( rc==SQLITE_OK ){
+ memcpy(pNode->block.a, aBlock, nBlock);
+ pNode->block.n = nBlock;
+ memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
+ }
+ sqlite3_free(aBlock);
}
- sqlite3_free(aBlock);
}
}
nodeReaderRelease(&reader);
@@ -174930,7 +175565,10 @@ static int fts3TruncateNode(
NodeReader reader; /* Reader object */
Blob prev = {0, 0, 0}; /* Previous term written to new node */
int rc = SQLITE_OK; /* Return code */
- int bLeaf = aNode[0]=='\0'; /* True for a leaf node */
+ int bLeaf; /* True for a leaf node */
+
+ if( nNode<1 ) return FTS_CORRUPT_VTAB;
+ bLeaf = aNode[0]=='\0';
/* Allocate required output space */
blobGrowBuffer(pNew, nNode, &rc);
@@ -179732,7 +180370,7 @@ static JsonNode *jsonLookupStep(
u32 iStart, iLabel;
JsonNode *pNode;
iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
- iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+ iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
zPath += i;
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
if( pParse->oom ) return 0;
@@ -181216,10 +181854,6 @@ SQLITE_API int sqlite3_json_init(
/* #include "sqlite3.h" */
#endif
-/* #include <string.h> */
-/* #include <assert.h> */
-/* #include <stdio.h> */
-
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
@@ -181227,8 +181861,18 @@ typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+# define NDEBUG 1
+#endif
+#if defined(NDEBUG) && defined(SQLITE_DEBUG)
+# undef NDEBUG
+#endif
#endif
+/* #include <string.h> */
+/* #include <stdio.h> */
+/* #include <assert.h> */
+
/* The following macro is used to suppress compiler warnings.
*/
#ifndef UNUSED_PARAMETER
@@ -189792,7 +190436,8 @@ static void rbuTargetNameFunc(
zIn = (const char*)sqlite3_value_text(argv[0]);
if( zIn ){
if( rbuIsVacuum(p) ){
- if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
+ assert( argc==2 );
+ if( 0==sqlite3_value_int(argv[1]) ){
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
}
}else{
@@ -190243,7 +190888,8 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
}
pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
- pIter->abTblPk[iOrder] = (iPk!=0);
+ assert( iPk>=0 );
+ pIter->abTblPk[iOrder] = (u8)iPk;
pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
iOrder++;
}
@@ -190279,6 +190925,213 @@ static char *rbuObjIterGetCollist(
}
/*
+** Return a comma separated list of the quoted PRIMARY KEY column names,
+** in order, for the current table. Before each column name, add the text
+** zPre. After each column name, add the zPost text. Use zSeparator as
+** the separator text (usually ", ").
+*/
+static char *rbuObjIterGetPkList(
+ sqlite3rbu *p, /* RBU object */
+ RbuObjIter *pIter, /* Object iterator for column names */
+ const char *zPre, /* Before each quoted column name */
+ const char *zSeparator, /* Separator to use between columns */
+ const char *zPost /* After each quoted column name */
+){
+ int iPk = 1;
+ char *zRet = 0;
+ const char *zSep = "";
+ while( 1 ){
+ int i;
+ for(i=0; i<pIter->nTblCol; i++){
+ if( (int)pIter->abTblPk[i]==iPk ){
+ const char *zCol = pIter->azTblCol[i];
+ zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
+ zSep = zSeparator;
+ break;
+ }
+ }
+ if( i==pIter->nTblCol ) break;
+ iPk++;
+ }
+ return zRet;
+}
+
+/*
+** This function is called as part of restarting an RBU vacuum within
+** stage 1 of the process (while the *-oal file is being built) while
+** updating a table (not an index). The table may be a rowid table or
+** a WITHOUT ROWID table. It queries the target database to find the
+** largest key that has already been written to the target table and
+** constructs a WHERE clause that can be used to extract the remaining
+** rows from the source table. For a rowid table, the WHERE clause
+** is of the form:
+**
+** "WHERE _rowid_ > ?"
+**
+** and for WITHOUT ROWID tables:
+**
+** "WHERE (key1, key2) > (?, ?)"
+**
+** Instead of "?" placeholders, the actual WHERE clauses created by
+** this function contain literal SQL values.
+*/
+static char *rbuVacuumTableStart(
+ sqlite3rbu *p, /* RBU handle */
+ RbuObjIter *pIter, /* RBU iterator object */
+ int bRowid, /* True for a rowid table */
+ const char *zWrite /* Target table name prefix */
+){
+ sqlite3_stmt *pMax = 0;
+ char *zRet = 0;
+ if( bRowid ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
+ sqlite3_mprintf(
+ "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
+ )
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+ sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
+ zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
+ }
+ rbuFinalize(p, pMax);
+ }else{
+ char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
+ char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
+ char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
+ sqlite3_mprintf(
+ "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
+ zSelect, zWrite, pIter->zTbl, zOrder
+ )
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+ const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
+ zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
+ }
+ rbuFinalize(p, pMax);
+ }
+
+ sqlite3_free(zOrder);
+ sqlite3_free(zSelect);
+ sqlite3_free(zList);
+ }
+ return zRet;
+}
+
+/*
+** This function is called as part of restating an RBU vacuum when the
+** current operation is writing content to an index. If possible, it
+** queries the target index b-tree for the largest key already written to
+** it, then composes and returns an expression that can be used in a WHERE
+** clause to select the remaining required rows from the source table.
+** It is only possible to return such an expression if:
+**
+** * The index contains no DESC columns, and
+** * The last key written to the index before the operation was
+** suspended does not contain any NULL values.
+**
+** The expression is of the form:
+**
+** (index-field1, index-field2, ...) > (?, ?, ...)
+**
+** except that the "?" placeholders are replaced with literal values.
+**
+** If the expression cannot be created, NULL is returned. In this case,
+** the caller has to use an OFFSET clause to extract only the required
+** rows from the sourct table, just as it does for an RBU update operation.
+*/
+char *rbuVacuumIndexStart(
+ sqlite3rbu *p, /* RBU handle */
+ RbuObjIter *pIter /* RBU iterator object */
+){
+ char *zOrder = 0;
+ char *zLhs = 0;
+ char *zSelect = 0;
+ char *zVector = 0;
+ char *zRet = 0;
+ int bFailed = 0;
+ const char *zSep = "";
+ int iCol = 0;
+ sqlite3_stmt *pXInfo = 0;
+
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
+ );
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+ int iCid = sqlite3_column_int(pXInfo, 1);
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
+ const char *zCol;
+ if( sqlite3_column_int(pXInfo, 3) ){
+ bFailed = 1;
+ break;
+ }
+
+ if( iCid<0 ){
+ if( pIter->eType==RBU_PK_IPK ){
+ int i;
+ for(i=0; pIter->abTblPk[i]==0; i++);
+ assert( i<pIter->nTblCol );
+ zCol = pIter->azTblCol[i];
+ }else{
+ zCol = "_rowid_";
+ }
+ }else{
+ zCol = pIter->azTblCol[iCid];
+ }
+
+ zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
+ zLhs, zSep, zCol, zCollate
+ );
+ zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
+ zOrder, zSep, iCol, zCol, zCollate
+ );
+ zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
+ zSelect, zSep, iCol, zCol
+ );
+ zSep = ", ";
+ iCol++;
+ }
+ rbuFinalize(p, pXInfo);
+ if( bFailed ) goto index_start_out;
+
+ if( p->rc==SQLITE_OK ){
+ sqlite3_stmt *pSel = 0;
+
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
+ sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
+ zSelect, pIter->zTbl, zOrder
+ )
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
+ zSep = "";
+ for(iCol=0; iCol<pIter->nCol; iCol++){
+ const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
+ if( zQuoted[0]=='N' ){
+ bFailed = 1;
+ break;
+ }
+ zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
+ zSep = ", ";
+ }
+
+ if( !bFailed ){
+ zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
+ }
+ }
+ rbuFinalize(p, pSel);
+ }
+
+ index_start_out:
+ sqlite3_free(zOrder);
+ sqlite3_free(zSelect);
+ sqlite3_free(zVector);
+ sqlite3_free(zLhs);
+ return zRet;
+}
+
+/*
** This function is used to create a SELECT list (the list of SQL
** expressions that follows a SELECT keyword) for a SELECT statement
** used to read from an data_xxx or rbu_tmp_xxx table while updating the
@@ -190954,12 +191807,24 @@ static int rbuObjIterPrepareAll(
if( p->rc==SQLITE_OK ){
char *zSql;
if( rbuIsVacuum(p) ){
+ char *zStart = 0;
+ if( nOffset ){
+ zStart = rbuVacuumIndexStart(p, pIter);
+ if( zStart ){
+ sqlite3_free(zLimit);
+ zLimit = 0;
+ }
+ }
+
zSql = sqlite3_mprintf(
- "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
+ "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
zCollist,
pIter->zDataTbl,
- zPart, zCollist, zLimit
+ zPart,
+ (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
+ zCollist, zLimit
);
+ sqlite3_free(zStart);
}else
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
@@ -190982,7 +191847,11 @@ static int rbuObjIterPrepareAll(
zCollist, zLimit
);
}
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
+ }else{
+ sqlite3_free(zSql);
+ }
}
sqlite3_free(zImposterCols);
@@ -191082,18 +191951,42 @@ static int rbuObjIterPrepareAll(
/* Create the SELECT statement to read keys from data_xxx */
if( p->rc==SQLITE_OK ){
const char *zRbuRowid = "";
+ char *zStart = 0;
+ char *zOrder = 0;
if( bRbuRowid ){
zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
}
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
- sqlite3_mprintf(
- "SELECT %s,%s rbu_control%s FROM '%q'%s",
- zCollist,
- (rbuIsVacuum(p) ? "0 AS " : ""),
- zRbuRowid,
- pIter->zDataTbl, zLimit
- )
- );
+
+ if( rbuIsVacuum(p) ){
+ if( nOffset ){
+ zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
+ if( zStart ){
+ sqlite3_free(zLimit);
+ zLimit = 0;
+ }
+ }
+ if( bRbuRowid ){
+ zOrder = rbuMPrintf(p, "_rowid_");
+ }else{
+ zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
+ }
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
+ sqlite3_mprintf(
+ "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
+ zCollist,
+ (rbuIsVacuum(p) ? "0 AS " : ""),
+ zRbuRowid,
+ pIter->zDataTbl, (zStart ? zStart : ""),
+ (zOrder ? "ORDER BY" : ""), zOrder,
+ zLimit
+ )
+ );
+ }
+ sqlite3_free(zStart);
+ sqlite3_free(zOrder);
}
sqlite3_free(zWhere);
@@ -193320,9 +194213,7 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
- if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
- rbuMainlistAdd(p);
- }
+ rbuMainlistAdd(p);
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
@@ -193385,10 +194276,7 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
}else{
int bCapture = 0;
- if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
- && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
- && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
- ){
+ if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
bCapture = 1;
}
@@ -193421,20 +194309,24 @@ static int rbuVfsShmMap(
** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
** instead of a file on disk. */
assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
- if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
- if( iRegion<=p->nShm ){
- sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
- char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
- if( apNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
- p->apShm = apNew;
- p->nShm = iRegion+1;
- }
+ if( eStage==RBU_STAGE_OAL ){
+ sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
+ char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
+
+ /* This is an RBU connection that uses its own heap memory for the
+ ** pages of the *-shm file. Since no other process can have run
+ ** recovery, the connection must request *-shm pages in order
+ ** from start to finish. */
+ assert( iRegion==p->nShm );
+ if( apNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
+ p->apShm = apNew;
+ p->nShm = iRegion+1;
}
- if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
+ if( rc==SQLITE_OK ){
char *pNew = (char*)sqlite3_malloc64(szRegion);
if( pNew==0 ){
rc = SQLITE_NOMEM;
@@ -193663,7 +194555,8 @@ static int rbuVfsAccess(
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
- if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+ if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+ assert( pDb->pRbu );
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
@@ -196656,7 +197549,9 @@ SQLITE_API int sqlite3session_diff(
}
sqlite3_free((char*)azCol);
if( bMismatch ){
- *pzErrMsg = sqlite3_mprintf("table schemas do not match");
+ if( pzErrMsg ){
+ *pzErrMsg = sqlite3_mprintf("table schemas do not match");
+ }
rc = SQLITE_SCHEMA;
}
if( bHasPk==0 ){
@@ -196862,7 +197757,7 @@ SQLITE_API int sqlite3session_attach(
** set *pRc to SQLITE_NOMEM and return non-zero.
*/
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
- if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
+ if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){
u8 *aNew;
i64 nNew = p->nAlloc ? p->nAlloc : 128;
do {
@@ -204287,10 +205182,19 @@ static int sqlite3Fts5PoslistNext64(
i64 iOff = *piOff;
int iVal;
fts5FastGetVarint32(a, i, iVal);
- if( iVal==1 ){
+ if( iVal<=1 ){
+ if( iVal==0 ){
+ *pi = i;
+ return 0;
+ }
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
+ if( iVal<2 ){
+ /* This is a corrupt record. So stop parsing it here. */
+ *piOff = -1;
+ return 1;
+ }
}
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
*pi = i;
@@ -209873,7 +210777,7 @@ static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
/* TODO: Do we need this if the leaf-index is appended? Probably... */
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
- if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
+ if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
}
fts5DataRelease(pData);
@@ -213834,8 +214738,14 @@ static void fts5MergePrefixLists(
** first rowid in one input is a large negative number, and the first in
** the other a non-negative number, the delta for the non-negative
** number will be larger on disk than the literal integer value
- ** was. */
- if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
+ ** was.
+ **
+ ** Or, if the input position-lists are corrupt, then the output might
+ ** include up to 2 extra 10-byte positions created by interpreting -1
+ ** (the value PoslistNext64() uses for EOF) as a position and appending
+ ** it to the output. This can happen at most once for each input
+ ** position-list, hence two 10 byte paddings. */
+ if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return;
fts5DoclistIterInit(p1, &i1);
fts5DoclistIterInit(p2, &i2);
@@ -213846,6 +214756,7 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
fts5DoclistIterNext(&i1);
if( i1.aPoslist==0 ) break;
+ assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
else if( i2.iRowid!=i1.iRowid ){
/* Copy entry from i2 */
@@ -213853,6 +214764,7 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
fts5DoclistIterNext(&i2);
if( i2.aPoslist==0 ) break;
+ assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
else{
/* Merge the two position lists. */
@@ -213876,7 +214788,7 @@ static void fts5MergePrefixLists(
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
- assert( iPos1>=0 && iPos2>=0 );
+ assert_nc( iPos1>=0 && iPos2>=0 );
if( iPos1<iPos2 ){
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
@@ -213885,7 +214797,6 @@ static void fts5MergePrefixLists(
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
}
-
if( iPos1>=0 && iPos2>=0 ){
while( 1 ){
if( iPos1<iPos2 ){
@@ -213910,7 +214821,7 @@ static void fts5MergePrefixLists(
aCopy = &a1[iOff1];
nCopy = i1.nPoslist - iOff1;
}else{
- assert( iPos2>=0 && iPos2!=iPrev );
+ assert_nc( iPos2>=0 && iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
aCopy = &a2[iOff2];
nCopy = i2.nPoslist - iOff2;
@@ -213924,8 +214835,9 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
fts5DoclistIterNext(&i1);
fts5DoclistIterNext(&i2);
- assert( out.n<=(p1->n+p2->n+9) );
+ assert_nc( out.n<=(p1->n+p2->n+9) );
if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
+ assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
}
@@ -213937,7 +214849,7 @@ static void fts5MergePrefixLists(
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
}
- assert( out.n<=(p1->n+p2->n+9) );
+ assert_nc( out.n<=(p1->n+p2->n+9) );
fts5BufferSet(&p->rc, p1, out.n, out.p);
fts5BufferFree(&tmp);
@@ -218103,7 +219015,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6", -1, SQLITE_TRANSIENT);
}
/*
@@ -222362,8 +223274,10 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
}
if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
- while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
- assert( pCsr->iCol<pCsr->pFts5->pConfig->nCol );
+ for(/* noop */; pCsr->iCol<nCol && pCsr->aDoc[pCsr->iCol]==0; pCsr->iCol++);
+ if( pCsr->iCol==nCol ){
+ rc = FTS5_CORRUPT;
+ }
}
return rc;
}
@@ -222867,9 +223781,9 @@ SQLITE_API int sqlite3_stmt_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=222870
+#if __LINE__!=223781
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f8315alt2"
+#define SQLITE_SOURCE_ID "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index fadfe1e152..a4bab0ad6b 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.28.0"
-#define SQLITE_VERSION_NUMBER 3028000
-#define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50"
+#define SQLITE_VERSION "3.29.0"
+#define SQLITE_VERSION_NUMBER 3029000
+#define SQLITE_SOURCE_ID "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1296,8 +1296,14 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. The file can be a
-** directory.
+** to test whether a file is at least readable. The SQLITE_ACCESS_READ
+** flag is never actually used and is not implemented in the built-in
+** VFSes of SQLite. The file is named by the second argument and can be a
+** directory. The xAccess method returns [SQLITE_OK] on success or some
+** non-zero error code if there is an I/O error or if the name of
+** the file given in the second argument is illegal. If SQLITE_OK
+** is returned, then non-zero or zero is written into *pResOut to indicate
+** whether or not the file is accessible.
**
** ^SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname. The exact size of the output buffer
@@ -2198,6 +2204,7 @@ struct sqlite3_mem_methods {
** features include but are not limited to the following:
** <ul>
** <li> The [PRAGMA writable_schema=ON] statement.
+** <li> The [PRAGMA journal_mode=OFF] statement.
** <li> Writes to the [sqlite_dbpage] virtual table.
** <li> Direct writes to [shadow tables].
** </ul>
@@ -2213,6 +2220,34 @@ struct sqlite3_mem_methods {
** integer into which is written 0 or 1 to indicate whether the writable_schema
** is enabled or disabled following this call.
** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
+** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
+** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
+** the legacy behavior of the [ALTER TABLE RENAME] command such it
+** behaves as it did prior to [version 3.24.0] (2018-06-04). See the
+** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
+** additional information. This feature can also be turned on and off
+** using the [PRAGMA legacy_alter_table] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DML]]
+** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DML statement
+** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DDL]]
+** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DDL statements,
+** such as CREATE TABLE and CREATE INDEX. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -2227,7 +2262,10 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */
-#define SQLITE_DBCONFIG_MAX 1011 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -7319,7 +7357,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
-#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_RESULT_INTREAL 27
+#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index c33d5016ce..7db16002ff 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -1013,6 +1013,25 @@ public class QtNative
});
}
+ private static String[] listAssetContent(android.content.res.AssetManager asset, String path) {
+ String [] list;
+ ArrayList<String> res = new ArrayList<String>();
+ try {
+ list = asset.list(path);
+ if (list.length > 0) {
+ for (String file : list) {
+ try {
+ String[] isDir = asset.list(path.length() > 0 ? path + "/" + file : file);
+ if (isDir != null && isDir.length > 0)
+ file += "/";
+ res.add(file);
+ } catch (Exception e) {}
+ }
+ }
+ } catch (Exception e) {}
+ return res.toArray(new String[res.size()]);
+ }
+
// screen methods
public static native void setDisplayMetrics(int screenWidthPixels,
int screenHeightPixels,
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
index 45941e8ed8..1e72aa3841 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
@@ -44,8 +44,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ComponentInfo;
-import android.content.pm.PackageInfo;
-import android.content.res.AssetManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -55,15 +53,8 @@ import android.util.Log;
import org.kde.necessitas.ministro.IMinistro;
import org.kde.necessitas.ministro.IMinistroCallback;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -88,8 +79,6 @@ public abstract class QtLoader {
public static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables";
public static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
public static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
- public static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id";
- public static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id";
public static final String MAIN_LIBRARY_KEY = "main.library";
public static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
public static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
@@ -141,7 +130,6 @@ public abstract class QtLoader {
public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme.
public static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded.
- public static final int BUFFER_SIZE = 1024;
public String[] m_sources = {"https://download.qt-project.org/ministro/android/qt5/qt-5.7"}; // Make sure you are using ONLY secure locations
public String m_repository = "default"; // Overwrites the default Ministro repository
@@ -368,263 +356,6 @@ public abstract class QtLoader {
errorDialog.show();
}
- static private void copyFile(InputStream inputStream, OutputStream outputStream)
- throws IOException
- {
- byte[] buffer = new byte[BUFFER_SIZE];
-
- int count;
- while ((count = inputStream.read(buffer)) > 0)
- outputStream.write(buffer, 0, count);
- }
-
- private void copyAsset(String source, String destination)
- throws IOException
- {
- // Already exists, we don't have to do anything
- File destinationFile = new File(destination);
- if (destinationFile.exists())
- return;
-
- File parentDirectory = destinationFile.getParentFile();
- if (!parentDirectory.exists())
- parentDirectory.mkdirs();
-
- destinationFile.createNewFile();
-
- AssetManager assetsManager = m_context.getAssets();
- InputStream inputStream = null;
- FileOutputStream outputStream = null;
- try {
- inputStream = assetsManager.open(source);
- outputStream = new FileOutputStream(destinationFile);
- copyFile(inputStream, outputStream);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null)
- inputStream.close();
-
- if (outputStream != null)
- // Ensure that the buffered data is flushed to the OS for writing.
- outputStream.flush();
- }
- // Mark the output stream as still needing to be written to physical disk.
- // The output stream will be closed after this sync completes.
- m_fileOutputStreams.add(outputStream);
- }
-
- private static void createBundledBinary(String source, String destination)
- throws IOException
- {
- // Already exists, we don't have to do anything
- File destinationFile = new File(destination);
- if (destinationFile.exists())
- return;
-
- File parentDirectory = destinationFile.getParentFile();
- if (!parentDirectory.exists())
- parentDirectory.mkdirs();
-
- destinationFile.createNewFile();
-
- InputStream inputStream = null;
- FileOutputStream outputStream = null;
- try {
- inputStream = new FileInputStream(source);
- outputStream = new FileOutputStream(destinationFile);
- copyFile(inputStream, outputStream);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null)
- inputStream.close();
-
- if (outputStream != null)
- // Ensure that the buffered data is flushed to the OS for writing.
- outputStream.flush();
- }
- // Mark the output stream as still needing to be written to physical disk.
- // The output stream will be closed after this sync completes.
- m_fileOutputStreams.add(outputStream);
- }
-
- private boolean cleanCacheIfNecessary(String pluginsPrefix, long packageVersion)
- {
- File versionFile = new File(pluginsPrefix + "cache.version");
-
- long cacheVersion = 0;
- if (versionFile.exists() && versionFile.canRead()) {
- DataInputStream inputStream = null;
- try {
- inputStream = new DataInputStream(new FileInputStream(versionFile));
- cacheVersion = inputStream.readLong();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- if (cacheVersion != packageVersion) {
- deleteRecursively(new File(pluginsPrefix));
- return true;
- } else {
- return false;
- }
- }
-
- private void extractBundledPluginsAndImports(String pluginsPrefix, String libsDir)
- throws IOException
- {
- long packageVersion = -1;
- try {
- PackageInfo packageInfo = m_context.getPackageManager().getPackageInfo(m_context.getPackageName(), 0);
- packageVersion = packageInfo.lastUpdateTime;
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- if (!cleanCacheIfNecessary(pluginsPrefix, packageVersion))
- return;
-
- {
- // why can't we load the plugins directly from libs ?!?!
- String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY;
- if (m_contextInfo.metaData.containsKey(key)) {
- int resourceId = m_contextInfo.metaData.getInt(key);
- ArrayList<String> list = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
-
- for (String bundledImportBinary : list) {
- String[] split = bundledImportBinary.split(":");
- String sourceFileName = libsDir + split[0];
- String destinationFileName = pluginsPrefix + split[1];
- createBundledBinary(sourceFileName, destinationFileName);
- }
- }
- }
-
- {
- String key = BUNDLED_IN_ASSETS_RESOURCE_ID_KEY;
- if (m_contextInfo.metaData.containsKey(key)) {
- String[] list = m_context.getResources().getStringArray(m_contextInfo.metaData.getInt(key));
-
- for (String fileName : list) {
- String[] split = fileName.split(":");
- String sourceFileName = split[0];
- String destinationFileName = pluginsPrefix + split[1];
- copyAsset(sourceFileName, destinationFileName);
- }
- }
-
- }
-
- // The Java compiler must be assured that variables belonging to this parent thread will not
- // go out of scope during the runtime of the spawned thread (since in general spawned
- // threads can outlive their parent threads). Copy variables and declare as 'final' before
- // passing into the spawned thread.
- final String pluginsPrefixFinal = pluginsPrefix;
- final long packageVersionFinal = packageVersion;
-
- // Spawn a worker thread to write all installed files to physical disk and indicate
- // successful installation by creating the 'cache.version' file.
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- finalizeInstallation(pluginsPrefixFinal, packageVersionFinal);
- } catch (Exception e) {
- Log.e(QtApplication.QtTAG, e.getMessage());
- e.printStackTrace();
- return;
- }
- }
- }).start();
- }
-
- private void finalizeInstallation(String pluginsPrefix, long packageVersion)
- throws IOException
- {
- {
- // Write all installed files to physical disk and close each output stream
- for (FileOutputStream fileOutputStream : m_fileOutputStreams) {
- fileOutputStream.getFD().sync();
- fileOutputStream.close();
- }
-
- m_fileOutputStreams.clear();
- }
-
- {
- // Create 'cache.version' file
-
- File versionFile = new File(pluginsPrefix + "cache.version");
-
- File parentDirectory = versionFile.getParentFile();
- if (!parentDirectory.exists())
- parentDirectory.mkdirs();
-
- versionFile.createNewFile();
-
- DataOutputStream outputStream = null;
- try {
- outputStream = new DataOutputStream(new FileOutputStream(versionFile));
- outputStream.writeLong(packageVersion);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (outputStream != null)
- outputStream.close();
- }
- }
-
- }
-
- private void deleteRecursively(File directory)
- {
- File[] files = directory.listFiles();
- if (files != null) {
- for (File file : files) {
- if (file.isDirectory())
- deleteRecursively(file);
- else
- file.delete();
- }
-
- directory.delete();
- }
- }
-
- private void cleanOldCacheIfNecessary(String oldLocalPrefix, String localPrefix)
- {
- File newCache = new File(localPrefix);
- if (!newCache.exists()) {
- {
- File oldPluginsCache = new File(oldLocalPrefix + "plugins/");
- if (oldPluginsCache.exists() && oldPluginsCache.isDirectory())
- deleteRecursively(oldPluginsCache);
- }
-
- {
- File oldImportsCache = new File(oldLocalPrefix + "imports/");
- if (oldImportsCache.exists() && oldImportsCache.isDirectory())
- deleteRecursively(oldImportsCache);
- }
-
- {
- File oldQmlCache = new File(oldLocalPrefix + "qml/");
- if (oldQmlCache.exists() && oldQmlCache.isDirectory())
- deleteRecursively(oldQmlCache);
- }
- }
- }
-
public void startApp(final boolean firstStart)
{
try {
@@ -688,29 +419,13 @@ public abstract class QtLoader {
if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
&& m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) {
- File dataDir = new File(m_context.getApplicationInfo().dataDir);
- String dataPath = dataDir.getCanonicalPath() + "/";
- String pluginsPrefix = dataPath + "qt-reserved-files/";
-
- if (libsDir == null)
- throw new Exception("Invalid libsDir");
-
- cleanOldCacheIfNecessary(dataPath, pluginsPrefix);
- extractBundledPluginsAndImports(pluginsPrefix, libsDir);
-
- if (m_contextInfo.metaData.containsKey(BUNDLED_IN_LIB_RESOURCE_ID_KEY)) {
- int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id");
- for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) {
- for (String lib : libs.split(":")) {
- if (!lib.isEmpty())
- libraryList.add(libsDir + lib);
- }
+ int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id");
+ for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) {
+ for (String lib : libs.split(":")) {
+ if (!lib.isEmpty())
+ libraryList.add(libsDir + lib);
}
}
-
- ENVIRONMENT_VARIABLES += "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
- + "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
- + "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins";
if (bundledLibsDir != null)
ENVIRONMENT_VARIABLES += "\tQT_BUNDLED_LIBS_PATH=" + bundledLibsDir;
}
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index 75da314c2b..6d0f4e0d45 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -34,8 +34,6 @@
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
- <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
- <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle
index d2da115936..3087d08c83 100644
--- a/src/android/templates/build.gradle
+++ b/src/android/templates/build.gradle
@@ -54,4 +54,9 @@ android {
lintOptions {
abortOnError false
}
+
+ // Do not compress Qt binary resources file
+ aaptOptions {
+ noCompress 'rcc'
+ }
}
diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml
index db777bf433..6b1a4a2a02 100644
--- a/src/android/templates/res/values/libs.xml
+++ b/src/android/templates/res/values/libs.xml
@@ -11,20 +11,12 @@
<!-- %%INSERT_EXTRA_LIBS%% -->
</array>
- <array name="qt_libs">
+ <array name="qt_libs">
<!-- %%INSERT_QT_LIBS%% -->
- </array>
-
- <array name="bundled_in_lib">
- <!-- %%INSERT_BUNDLED_IN_LIB%% -->
</array>
<array name="load_local_libs">
<!-- %%INSERT_LOCAL_LIBS%% -->
</array>
- <array name="bundled_in_assets">
- <!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
- </array>
-
</resources>
diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
index cafae0e742..af53d4c621 100644
--- a/src/angle/src/config.pri
+++ b/src/angle/src/config.pri
@@ -53,6 +53,7 @@ CONFIG(debug, debug|release) {
}
!isEmpty(BUILD_PASS): BUILDSUBDIR = $$lower($$BUILD_PASS)/
+else: BUILDSUBDIR = $$PWD/
# c++11 is needed by MinGW to get support for unordered_map.
CONFIG += stl exceptions c++11 c++14
diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h
index 87fcf30cf9..7c9538a015 100644
--- a/src/concurrent/qtconcurrentmapkernel.h
+++ b/src/concurrent/qtconcurrentmapkernel.h
@@ -118,16 +118,16 @@ public:
return false;
}
- bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *) override
+ bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override
{
IntermediateResults<typename MapFunctor::result_type> results;
- results.begin = begin;
- results.end = end;
- results.vector.reserve(end - begin);
+ results.begin = beginIndex;
+ results.end = endIndex;
+ results.vector.reserve(endIndex - beginIndex);
Iterator it = sequenceBeginIterator;
- std::advance(it, begin);
- for (int i = begin; i < end; ++i) {
+ std::advance(it, beginIndex);
+ for (int i = beginIndex; i < endIndex; ++i) {
results.vector.append(map(*(it)));
std::advance(it, 1);
}
@@ -176,13 +176,13 @@ public:
return true;
}
- bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *results) override
+ bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, T *results) override
{
Iterator it = sequenceBeginIterator;
- std::advance(it, begin);
- for (int i = begin; i < end; ++i) {
- runIteration(it, i, results + (i - begin));
+ std::advance(it, beginIndex);
+ for (int i = beginIndex; i < endIndex; ++i) {
+ runIteration(it, i, results + (i - beginIndex));
std::advance(it, 1);
}
diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp
index ed40817222..69e2cfc9bc 100644
--- a/src/corelib/animation/qanimationgroup.cpp
+++ b/src/corelib/animation/qanimationgroup.cpp
@@ -195,8 +195,11 @@ void QAnimationGroup::insertAnimation(int index, QAbstractAnimation *animation)
return;
}
- if (QAnimationGroup *oldGroup = animation->group())
+ if (QAnimationGroup *oldGroup = animation->group()) {
oldGroup->removeAnimation(animation);
+ // ensure we don't insert out of bounds if oldGroup == this
+ index = qMin(index, d->animations.size());
+ }
d->animations.insert(index, animation);
QAbstractAnimationPrivate::get(animation)->group = this;
diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp
index b9f1a814fa..5a778c2638 100644
--- a/src/corelib/codecs/qicucodec.cpp
+++ b/src/corelib/codecs/qicucodec.cpp
@@ -42,16 +42,17 @@
#include "qtextcodec_p.h"
#include "qutfcodec_p.h"
#include "qlatincodec_p.h"
-#if QT_CONFIG(codecs)
-#include "qtsciicodec_p.h"
-#include "qisciicodec_p.h"
-#endif
#include "qsimplecodec_p.h"
#include "private/qcoreglobaldata_p.h"
#include "qdebug.h"
#include "unicode/ucnv.h"
+#if QT_CONFIG(codecs)
+#include "qtsciicodec_p.h"
+#include "qisciicodec_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
typedef QList<QTextCodec*>::ConstIterator TextCodecListConstIt;
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 14f9abc28a..06fd88da90 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -103,10 +103,13 @@ typedef QList<QByteArray>::ConstIterator ByteArrayListConstIt;
Q_GLOBAL_STATIC(QRecursiveMutex, textCodecsMutex);
-class TextCodecsMutexLocker {
+class TextCodecsMutexLocker
+{
using Lock = decltype(qt_unique_lock(std::declval<QRecursiveMutex&>()));
// ### FIXME: this is used when textCodecsMutex already == nullptr
const Lock lock = qt_unique_lock(textCodecsMutex());
+public:
+ TextCodecsMutexLocker() {} // required d/t an ICC 19 bug
};
#if !QT_CONFIG(icu)
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index ef05d227cc..af4cd3b786 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -158,21 +158,6 @@
"-latomic"
]
},
- "libdl": {
- "label": "dlopen()",
- "test": {
- "main": [
- "dlclose(dlopen(0, 0));",
- "dlsym(RTLD_DEFAULT, 0);",
- "dlerror();"
- ]
- },
- "headers": "dlfcn.h",
- "sources": [
- "",
- "-ldl"
- ]
- },
"librt": {
"label": "clock_gettime()",
"test": {
@@ -612,11 +597,6 @@
"condition": "features.clock-gettime && tests.clock-monotonic",
"output": [ "feature" ]
},
- "dlopen": {
- "label": "dlopen()",
- "condition": "config.unix && libs.libdl",
- "output": [ "privateFeature" ]
- },
"doubleconversion": {
"label": "DoubleConversion",
"output": [ "privateFeature", "feature" ]
@@ -879,7 +859,7 @@
},
"datestring": {
"label": "QDate/QTime/QDateTime",
- "purpose": "Provides convertion between dates and strings.",
+ "purpose": "Provides conversion between dates and strings.",
"section": "Data structures",
"condition": "features.textdate",
"output": [ "publicFeature", "feature" ]
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 121db51eb5..452d2db0fd 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -21,7 +21,7 @@ CONFIG += simd optimize_full
QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf
ANDROID_LIB_DEPENDENCIES = \
- plugins/platforms/android/libqtforandroid.so
+ plugins/platforms/libplugins_platforms_qtforandroid.so
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
jar/QtAndroid.jar
ANDROID_PERMISSIONS = \
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp
index 1e31a5292f..1966f8195a 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp
@@ -416,7 +416,7 @@ public:
LoadArchiveMemberHint = 0x04
};
Q_DECLARE_FLAGS(LoadHints, LoadHint)
- Q_FLAG(LoadHints)
+ Q_FLAG(LoadHint)
...
}
//! [39]
diff --git a/src/corelib/doc/snippets/hellotrmain.cpp b/src/corelib/doc/snippets/hellotrmain.cpp
index 2fab919a47..721a83240b 100644
--- a/src/corelib/doc/snippets/hellotrmain.cpp
+++ b/src/corelib/doc/snippets/hellotrmain.cpp
@@ -56,13 +56,13 @@ int main(int argc, char *argv[])
QTranslator translator;
// look up e.g. :/translations/myapp_de.qm
if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations")))
- app.installTranslator(&translator);
+ QCoreApplication::installTranslator(&translator);
QPushButton hello(QCoreApplication::translate("main", "Hello world!"));
hello.resize(100, 30);
hello.show();
- return app.exec();
+ return QCoreApplication::exec();
}
//! [0]
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 2e58dabf5f..e6ad80525a 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -109,6 +109,7 @@
# define QT_FEATURE_renameat2 -1
#endif
#define QT_FEATURE_sharedmemory -1
+#define QT_FEATURE_signaling_nan -1
#define QT_FEATURE_slog2 -1
#ifdef __GLIBC_PREREQ
# define QT_FEATURE_statx (__GLIBC_PREREQ(2, 28) ? 1 : -1)
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index ff2997b73a..6c21b7de5a 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -107,14 +107,55 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \internal
- Implements qFpClassify() for qfloat16.
- */
+ \internal
+ \since 5.14
+ bool qfloat16::isInf() const noexcept
+
+ Tests whether this \c qfloat16 value is an infinity.
+
+ \sa qIsInf()
+*/
+
+/*!
+ \internal
+ \since 5.14
+ bool qfloat16::isNaN() const noexcept
+
+ Tests whether this \c qfloat16 value is "not a number".
+
+ \sa qIsNaN()
+*/
+
+/*!
+ \since 5.14
+ bool qfloat16::isNormal() const noexcept
+ Tests whether this \c qfloat16 value is finite and in normal form.
+
+ \sa qFpClassify()
+*/
+
+/*!
+ \internal
+ \since 5.14
+ bool qfloat16::isFinite() const noexcept
+
+ Tests whether this \c qfloat16 value is finite.
+
+ \sa qIsFinite()
+*/
+
+/*!
+ \internal
+ \since 5.14
+ Implements qFpClassify() for qfloat16.
+
+ \sa qFpClassify()
+*/
int qfloat16::fpClassify() const noexcept
{
return isInf() ? FP_INFINITE : isNaN() ? FP_NAN
- : !b16 ? FP_ZERO : isNormal() ? FP_NORMAL : FP_SUBNORMAL;
+ : !(b16 & 0x7fff) ? FP_ZERO : isNormal() ? FP_NORMAL : FP_SUBNORMAL;
}
/*! \fn int qRound(qfloat16 value)
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index 4d1aa91349..9a4f1800a4 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -94,7 +94,7 @@ public:
static constexpr qfloat16 _limit_quiet_NaN() noexcept { return qfloat16(Wrap(0x7e00)); }
// Signalling NaN is 0x7f00
inline constexpr bool isNormal() const noexcept
- { return b16 == 0 || ((b16 & 0x7c00) && (b16 & 0x7c00) != 0x7c00); }
+ { return (b16 & 0x7fff) == 0 || ((b16 & 0x7c00) && (b16 & 0x7c00) != 0x7c00); }
private:
quint16 b16;
constexpr inline explicit qfloat16(Wrap nibble) noexcept : b16(nibble.b16) {}
@@ -296,7 +296,7 @@ class numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> : public numeric_limits<flo
public:
/*
Treat quint16 b16 as if it were:
- uint S: 1; // b16 >> 15 (sign)
+ uint S: 1; // b16 >> 15 (sign); can be set for zero
uint E: 5; // (b16 >> 10) & 0x1f (offset exponent)
uint M: 10; // b16 & 0x3ff (adjusted mantissa)
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 2b1a40cf4c..114a4d71e2 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -48,6 +48,10 @@
#include "qoperatingsystemversion_p.h"
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT)
#include "qoperatingsystemversion_win_p.h"
+# if QT_CONFIG(settings)
+# include "qsettings.h"
+# include "qvariant.h"
+# endif
#endif
#include <private/qlocale_tools_p.h>
@@ -2202,12 +2206,36 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
QT_WARNING_POP
#endif
+static QString readRegistryString(const QString &key, const QString &subKey)
+{
+#if QT_CONFIG(settings)
+ QSettings settings(key, QSettings::NativeFormat);
+ return settings.value(subKey).toString();
+#else
+ Q_UNUSED(key);
+ Q_UNUSED(subKey);
+ return QString();
+#endif
+}
+
+static inline QString windowsVersionKey() { return QStringLiteral(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"); }
+
+static inline QString windows10ReleaseId()
+{
+ return readRegistryString(windowsVersionKey(), QStringLiteral("ReleaseId"));
+}
+
+static inline QString windows7Build()
+{
+ return readRegistryString(windowsVersionKey(), QStringLiteral("CurrentBuild"));
+}
+
static QString winSp_helper()
{
const auto osv = qWindowsVersionInfo();
const qint16 major = osv.wServicePackMajor;
if (major) {
- QString sp = QStringLiteral(" SP ") + QString::number(major);
+ QString sp = QStringLiteral("SP ") + QString::number(major);
const qint16 minor = osv.wServicePackMinor;
if (minor)
sp += QLatin1Char('.') + QString::number(minor);
@@ -2920,19 +2948,34 @@ QString QSysInfo::prettyProductName()
{
#if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
const auto version = QOperatingSystemVersion::current();
+ const int majorVersion = version.majorVersion();
+ const QString versionString = QString::number(majorVersion) + QLatin1Char('.')
+ + QString::number(version.minorVersion());
+ QString result = version.name() + QLatin1Char(' ');
const char *name = osVer_helper(version);
- if (name)
- return version.name() + QLatin1Char(' ') + QLatin1String(name)
-# if defined(Q_OS_WIN)
- + winSp_helper()
-# endif
- + QLatin1String(" (") + QString::number(version.majorVersion())
- + QLatin1Char('.') + QString::number(version.minorVersion())
- + QLatin1Char(')');
- else
- return version.name() + QLatin1Char(' ')
- + QString::number(version.majorVersion()) + QLatin1Char('.')
- + QString::number(version.minorVersion());
+ if (!name)
+ return result + versionString;
+ result += QLatin1String(name);
+# if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
+ return result + QLatin1String(" (") + versionString + QLatin1Char(')');
+# else
+ // (resembling winver.exe): Windows 10 "Windows 10 Version 1809"
+ if (majorVersion >= 10) {
+ const auto releaseId = windows10ReleaseId();
+ if (!releaseId.isEmpty())
+ result += QLatin1String(" Version ") + releaseId;
+ return result;
+ }
+ // Windows 7: "Windows 7 Version 6.1 (Build 7601: Service Pack 1)"
+ result += QLatin1String(" Version ") + versionString + QLatin1String(" (");
+ const auto build = windows7Build();
+ if (!build.isEmpty())
+ result += QLatin1String("Build ") + build;
+ const auto servicePack = winSp_helper();
+ if (!servicePack.isEmpty())
+ result += QLatin1String(": ") + servicePack;
+ return result + QLatin1Char(')');
+# endif // Windows
#elif defined(Q_OS_HAIKU)
return QLatin1String("Haiku ") + productVersion();
#elif defined(Q_OS_UNIX)
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 2b271ef5be..2da5861ccf 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -55,15 +55,24 @@ QT_END_NAMESPACE
# include "qcoreapplication.h"
#endif
+#ifndef QT_BUILD_QMAKE_BOOTSTRAP
+# include "private/qglobal_p.h"
+# include "qconfig.cpp"
+#endif
+
#ifdef Q_OS_DARWIN
# include "private/qcore_mac_p.h"
-#endif
+#endif // Q_OS_DARWIN
-#ifndef QT_BUILD_QMAKE_BOOTSTRAP
-# include "qconfig.cpp"
+#include "archdetect.cpp"
+
+#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable) && QT_CONFIG(dlopen) && !QT_CONFIG(framework)
+# include <dlfcn.h>
#endif
-#include "archdetect.cpp"
+#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable) && defined(Q_OS_WIN)
+# include <qt_windows.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -274,7 +283,7 @@ QLibraryInfo::licensedProducts()
QDate
QLibraryInfo::buildDate()
{
- return QDate::fromString(QString::fromLatin1(qt_configure_installation + 12), Qt::ISODate);
+ return QDate::fromString(QString::fromLatin1("2012-12-20"), Qt::ISODate);
}
#endif
#endif // datestring
@@ -410,7 +419,6 @@ static const struct {
#endif
{ "Binaries", "bin" },
{ "Plugins", "plugins" }, // should be ${ArchData}/plugins
- { "Imports", "imports" }, // should be ${ArchData}/imports
{ "Qml2Imports", "qml" }, // should be ${ArchData}/qml
{ "ArchData", "." },
{ "Data", "." },
@@ -453,6 +461,180 @@ void QLibraryInfo::sysrootify(QString *path)
}
#endif // QT_BUILD_QMAKE
+#ifndef QT_BUILD_QMAKE
+static QString prefixFromAppDirHelper()
+{
+ QString appDir;
+
+ if (QCoreApplication::instance()) {
+#ifdef Q_OS_DARWIN
+ CFBundleRef bundleRef = CFBundleGetMainBundle();
+ if (bundleRef) {
+ QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
+ if (urlRef) {
+ QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
+#ifdef Q_OS_MACOS
+ QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
+ if (QDir(bundleContentsDir).exists())
+ return QDir::cleanPath(bundleContentsDir);
+#else
+ return QDir::cleanPath(QString(path)); // iOS
+#endif // Q_OS_MACOS
+ }
+ }
+#endif // Q_OS_DARWIN
+ // We make the prefix path absolute to the executable's directory.
+ appDir = QCoreApplication::applicationDirPath();
+ } else {
+ appDir = QDir::currentPath();
+ }
+
+ return appDir;
+}
+#endif
+
+#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable)
+#if !defined(QT_STATIC) && !(defined(Q_OS_DARWIN) && QT_CONFIG(framework)) \
+ && (QT_CONFIG(dlopen) || defined(Q_OS_WIN))
+static QString prefixFromQtCoreLibraryHelper(const QString &qtCoreLibraryPath)
+{
+ const QString qtCoreLibrary = QDir::fromNativeSeparators(qtCoreLibraryPath);
+ const QString libDir = QFileInfo(qtCoreLibrary).absolutePath();
+ const QString prefixDir = libDir + QLatin1Char('/')
+ + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
+ return QDir::cleanPath(prefixDir);
+}
+#endif
+
+#if defined(Q_OS_WIN)
+#if defined(Q_OS_WINRT)
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+static HMODULE getWindowsModuleHandle()
+{
+ return reinterpret_cast<HMODULE>(&__ImageBase);
+}
+#else // Q_OS_WINRT
+static HMODULE getWindowsModuleHandle()
+{
+ HMODULE hModule = NULL;
+ GetModuleHandleEx(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ (LPCTSTR)&QLibraryInfo::isDebugBuild, &hModule);
+ return hModule;
+}
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
+
+static QString getRelocatablePrefix()
+{
+ QString prefixPath;
+
+ // For static builds, the prefix will be the app directory.
+ // For regular builds, the prefix will be relative to the location of the QtCore shared library.
+#if defined(QT_STATIC)
+ prefixPath = prefixFromAppDirHelper();
+#elif defined(Q_OS_DARWIN) && QT_CONFIG(framework)
+ CFBundleRef qtCoreBundle = CFBundleGetBundleWithIdentifier(
+ CFSTR("org.qt-project.QtCore"));
+ Q_ASSERT(qtCoreBundle);
+
+ QCFType<CFURLRef> qtCorePath = CFBundleCopyBundleURL(qtCoreBundle);
+ Q_ASSERT(qtCorePath);
+
+ QCFType<CFURLRef> qtCorePathAbsolute = CFURLCopyAbsoluteURL(qtCorePath);
+ Q_ASSERT(qtCorePathAbsolute);
+
+ QCFType<CFURLRef> libDirCFPath = CFURLCreateCopyDeletingLastPathComponent(NULL, qtCorePathAbsolute);
+
+ const QCFString libDirCFString = CFURLCopyFileSystemPath(libDirCFPath, kCFURLPOSIXPathStyle);
+
+ const QString prefixDir = QString(libDirCFString) + QLatin1Char('/')
+ + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
+
+ prefixPath = QDir::cleanPath(prefixDir);
+#elif QT_CONFIG(dlopen)
+ Dl_info info;
+ int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info);
+ if (result > 0 && info.dli_fname)
+ prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLatin1(info.dli_fname));
+#elif defined(Q_OS_WIN)
+ HMODULE hModule = getWindowsModuleHandle();
+ const int kBufferSize = 4096;
+ wchar_t buffer[kBufferSize];
+ const int pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
+ if (pathSize > 0)
+ prefixPath = prefixFromQtCoreLibraryHelper(QString::fromWCharArray(buffer, pathSize));
+#else
+#error "The chosen platform / config does not support querying for a dynamic prefix."
+#endif
+
+#if defined(Q_OS_LINUX) && !defined(QT_STATIC) && defined(__GLIBC__)
+ // QTBUG-78948: libQt5Core.so may be located in subdirectories below libdir.
+ // See "Hardware capabilities" in the ld.so documentation and the Qt 5.3.0
+ // changelog regarding SSE2 support.
+ const QString libdir = QString::fromLatin1(
+ qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]);
+ QDir prefixDir(prefixPath);
+ while (!prefixDir.exists(libdir)) {
+ prefixDir.cdUp();
+ prefixPath = prefixDir.absolutePath();
+ if (prefixDir.isRoot()) {
+ prefixPath.clear();
+ break;
+ }
+ }
+#endif
+
+ Q_ASSERT_X(!prefixPath.isEmpty(), "getRelocatablePrefix",
+ "Failed to find the Qt prefix path.");
+ return prefixPath;
+}
+#endif
+
+#if defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_QMAKE_BOOTSTRAP)
+QString qmake_abslocation();
+
+static QString getPrefixFromHostBinDir(const char *hostBinDirToPrefixPath)
+{
+ const QFileInfo qmfi = QFileInfo(qmake_abslocation()).canonicalFilePath();
+ return QDir::cleanPath(qmfi.absolutePath() + QLatin1Char('/')
+ + QLatin1String(hostBinDirToPrefixPath));
+}
+
+static QString getExtPrefixFromHostBinDir()
+{
+ return getPrefixFromHostBinDir(QT_CONFIGURE_HOSTBINDIR_TO_EXTPREFIX_PATH);
+}
+
+static QString getHostPrefixFromHostBinDir()
+{
+ return getPrefixFromHostBinDir(QT_CONFIGURE_HOSTBINDIR_TO_HOSTPREFIX_PATH);
+}
+#endif
+
+#ifndef QT_BUILD_QMAKE_BOOTSTRAP
+static const char *getPrefix(
+#ifdef QT_BUILD_QMAKE
+ QLibraryInfo::PathGroup group
+#endif
+ )
+{
+#if defined(QT_BUILD_QMAKE)
+# if QT_CONFIGURE_CROSSBUILD
+ if (group == QLibraryInfo::DevicePaths)
+ return QT_CONFIGURE_PREFIX_PATH;
+# endif
+ static QByteArray extPrefixPath = getExtPrefixFromHostBinDir().toLatin1();
+ return extPrefixPath.constData();
+#elif QT_CONFIG(relocatable)
+ static QByteArray prefixPath = getRelocatablePrefix().toLatin1();
+ return prefixPath.constData();
+#else
+ return QT_CONFIGURE_PREFIX_PATH;
+#endif
+}
+#endif // QT_BUILD_QMAKE_BOOTSTRAP
+
/*!
Returns the location specified by \a loc.
*/
@@ -562,14 +744,18 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
#ifndef QT_BUILD_QMAKE_BOOTSTRAP
if (!fromConf) {
+ // "volatile" here is a hack to prevent compilers from doing a
+ // compile-time strlen() on "path". The issue is that Qt installers
+ // will binary-patch the Qt installation paths -- in such scenarios, Qt
+ // will be built with a dummy path, thus the compile-time result of
+ // strlen is meaningless.
const char * volatile path = 0;
if (loc == PrefixPath) {
- path =
-# ifdef QT_BUILD_QMAKE
- (group != DevicePaths) ?
- QT_CONFIGURE_EXT_PREFIX_PATH :
-# endif
- QT_CONFIGURE_PREFIX_PATH;
+ path = getPrefix(
+#ifdef QT_BUILD_QMAKE
+ group
+#endif
+ );
} else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) {
path = qt_configure_strs + qt_configure_str_offsets[loc - 1];
#ifndef Q_OS_WIN // On Windows we use the registry
@@ -578,7 +764,8 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
#endif
# ifdef QT_BUILD_QMAKE
} else if (loc == HostPrefixPath) {
- path = QT_CONFIGURE_HOST_PREFIX_PATH;
+ static const QByteArray hostPrefixPath = getHostPrefixFromHostBinDir().toLatin1();
+ path = hostPrefixPath.constData();
# endif
}
@@ -612,28 +799,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
}
#else
if (loc == PrefixPath) {
- if (QCoreApplication::instance()) {
-#ifdef Q_OS_DARWIN
- CFBundleRef bundleRef = CFBundleGetMainBundle();
- if (bundleRef) {
- QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
- if (urlRef) {
- QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
-#ifdef Q_OS_OSX
- QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
- if (QDir(bundleContentsDir).exists())
- return QDir::cleanPath(bundleContentsDir + ret);
-#else
- return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
-#endif // Q_OS_OSX
- }
- }
-#endif // Q_OS_DARWIN
- // We make the prefix path absolute to the executable's directory.
- baseDir = QCoreApplication::applicationDirPath();
- } else {
- baseDir = QDir::currentPath();
- }
+ baseDir = prefixFromAppDirHelper();
} else {
// we make any other path absolute to the prefix directory
baseDir = location(PrefixPath);
@@ -689,7 +855,6 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
\value LibraryExecutablesPath The location of installed executables required by libraries at runtime.
\value BinariesPath The location of installed Qt binaries (tools and applications).
\value PluginsPath The location of installed Qt plugins.
- \value ImportsPath The location of installed QML extensions to import (QML 1.x).
\value Qml2ImportsPath The location of installed QML extensions to import (QML 2.x).
\value ArchDataPath The location of general architecture-dependent Qt data.
\value DataPath The location of general architecture-independent Qt data.
@@ -709,10 +874,14 @@ QT_END_NAMESPACE
#include "private/qcoreapplication_p.h"
+QT_WARNING_DISABLE_GCC("-Wattributes")
+QT_WARNING_DISABLE_CLANG("-Wattributes")
+QT_WARNING_DISABLE_INTEL(2621)
+
extern const char qt_core_interpreter[] __attribute__((section(".interp")))
= ELF_INTERPRETER;
-extern "C" void qt_core_boilerplate();
+extern "C" void qt_core_boilerplate() __attribute__((force_align_arg_pointer));
void qt_core_boilerplate()
{
printf("This is the QtCore library version " QT_BUILD_STR "\n"
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index ed60b170a5..031dfe37e2 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -79,7 +79,6 @@ public:
LibraryExecutablesPath,
BinariesPath,
PluginsPath,
- ImportsPath,
Qml2ImportsPath,
ArchDataPath,
DataPath,
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index a97a496290..3a9ff1651b 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1803,8 +1803,8 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
#ifndef QT_BOOTSTRAPPED
Q_TRACE(qt_message_print, msgType, context.category, context.function, context.file, context.line, message);
- // qDebug, qWarning, ... macros do not check whether category is enabled
- if (isDefaultCategory(context.category)) {
+ // qDebug, qWarning, ... macros do not check whether category is enabledgc
+ if (msgType != QtFatalMsg && isDefaultCategory(context.category)) {
if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
if (!defaultCategory->isEnabled(msgType))
return;
@@ -1910,12 +1910,14 @@ void qErrnoWarning(const char *msg, ...)
{
// qt_error_string() will allocate anyway, so we don't have
// to be careful here (like we do in plain qWarning())
+ QString error_string = qt_error_string(-1); // before vasprintf changes errno/GetLastError()
+
va_list ap;
va_start(ap, msg);
QString buf = QString::vasprintf(msg, ap);
va_end(ap);
- buf += QLatin1String(" (") + qt_error_string(-1) + QLatin1Char(')');
+ buf += QLatin1String(" (") + error_string + QLatin1Char(')');
QMessageLogContext context;
qt_message_output(QtCriticalMsg, context, buf);
}
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 886aedb4f3..cce88782e9 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -3287,7 +3287,7 @@
the application object is created, or by setting the QT_SCALE_FACTOR_ROUNDING_POLICY
environment variable.
- \sa QGuiApplication::setHighDdpiScaleFactorRoundingPolicy()
+ \sa QGuiApplication::setHighDpiScaleFactorRoundingPolicy()
\sa AA_EnableHighDpiScaling.
\omitvalue Unset
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index 11440f40a4..9cb9c1283a 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -81,11 +81,13 @@ Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); }
*/
Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); }
+#if QT_CONFIG(signaling_nan)
/*!
Returns the bit pattern of a signalling NaN as a double.
\relates <QtGlobal>
*/
Q_CORE_EXPORT double qSNaN() { return qt_snan(); }
+#endif
/*!
Returns the bit pattern of a quiet NaN as a double.
diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h
index 6a0c64712f..2771eea64f 100644
--- a/src/corelib/global/qnumeric.h
+++ b/src/corelib/global/qnumeric.h
@@ -44,7 +44,6 @@
QT_BEGIN_NAMESPACE
-
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(double d);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(double d);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(double d);
@@ -53,7 +52,9 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(float f);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(float f);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(float f);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION int qFpClassify(float val);
+#if QT_CONFIG(signaling_nan)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qSNaN();
+#endif
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN();
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf();
@@ -61,7 +62,9 @@ Q_CORE_EXPORT quint32 qFloatDistance(float a, float b);
Q_CORE_EXPORT quint64 qFloatDistance(double a, double b);
#define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)())
-#define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)())
+#if QT_CONFIG(signaling_nan)
+# define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)())
+#endif
#define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)())
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 21f9cfbef0..86e7997680 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -133,13 +133,14 @@ Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_inf() noexcept
return std::numeric_limits<double>::infinity();
}
-// Signaling NaN
+#if QT_CONFIG(signaling_nan)
Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_snan() noexcept
{
Q_STATIC_ASSERT_X(std::numeric_limits<double>::has_signaling_NaN,
"platform has no definition for signaling NaN for type double");
return std::numeric_limits<double>::signaling_NaN();
}
+#endif
// Quiet NaN
Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_qnan() noexcept
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index ded86cbc4e..33793ca168 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -356,14 +356,6 @@ bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) c
}
/*!
- \variable QOperatingSystemVersion::WindowsVista
- \brief a version corresponding to Windows Vista (version 6.0).
- \since 6.0
- */
-const QOperatingSystemVersion QOperatingSystemVersion::WindowsVista =
- QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 0);
-
-/*!
\variable QOperatingSystemVersion::Windows7
\brief a version corresponding to Windows 7 (version 6.1).
\since 5.9
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index 879bd379b0..f22878de89 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -60,7 +60,6 @@ public:
Android
};
- static const QOperatingSystemVersion WindowsVista;
static const QOperatingSystemVersion Windows7;
static const QOperatingSystemVersion Windows8;
static const QOperatingSystemVersion Windows8_1;
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 711eb8f4d5..3cbd40b772 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -90,42 +90,6 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando
QT_BEGIN_NAMESPACE
-#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
-static qsizetype qt_random_cpu(void *buffer, qsizetype count) noexcept;
-
-# ifdef Q_PROCESSOR_X86_64
-# define _rdrandXX_step _rdrand64_step
-# else
-# define _rdrandXX_step _rdrand32_step
-# endif
-
-static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype count) noexcept
-{
- unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
- unsigned *end = ptr + count;
-
- while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
- if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)) == 0)
- goto out;
- ptr += sizeof(qregisteruint)/sizeof(*ptr);
- }
-
- if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
- if (_rdrand32_step(ptr))
- goto out;
- ++ptr;
- }
-
-out:
- return ptr - reinterpret_cast<unsigned *>(buffer);
-}
-#else
-static qsizetype qt_random_cpu(void *, qsizetype)
-{
- return 0;
-}
-#endif
-
enum {
// may be "overridden" by a member enum
FillBufferNoexcept = true
@@ -366,8 +330,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin,
}
qsizetype filled = 0;
- if (qt_has_hwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0)
- filled += qt_random_cpu(buffer, count);
+ if (qHasHwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0)
+ filled += qRandomCpu(buffer, count);
if (filled != count && (uint(qt_randomdevice_control.loadAcquire()) & SkipSystemRNG) == 0) {
qsizetype bytesFilled =
diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h
index 167f4cc57d..934a9282b8 100644
--- a/src/corelib/global/qrandom_p.h
+++ b/src/corelib/global/qrandom_p.h
@@ -81,14 +81,6 @@ static const struct {
} qt_randomdevice_control;
#endif
-inline bool qt_has_hwrng()
-{
-#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
- return qCpuHasFeature(RDRND);
-#else
- return false;
-#endif
-}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index a6f8b45ea3..89834de29f 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -249,16 +249,18 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request)
isSymLink(). The symLinkTarget() function provides the name of the file
the symlink points to.
- On Unix (including \macos and iOS), the symlink has the same size() has
- the file it points to, because Unix handles symlinks
- transparently; similarly, opening a symlink using QFile
- effectively opens the link's target. For example:
+ On Unix (including \macos and iOS), the property getter functions in this
+ class return the properties such as times and size of the target file, not
+ the symlink, because Unix handles symlinks transparently. Opening a symlink
+ using QFile effectively opens the link's target. For example:
\snippet code/src_corelib_io_qfileinfo.cpp 0
- On Windows, shortcuts are \c .lnk files. The reported size() is that of
- the shortcut (not the link's target), and opening a shortcut using QFile
- opens the \c .lnk file. For example:
+ On Windows, shortcuts (\c .lnk files) are currently treated as symlinks. As
+ on Unix systems, the property getters return the size of the targeted file,
+ not the \c .lnk file itself. This behavior is deprecated and will likely be
+ removed in a future version of Qt, after which \c .lnk files will be treated
+ as regular files.
\snippet code/src_corelib_io_qfileinfo.cpp 1
@@ -903,6 +905,9 @@ QDir QFileInfo::absoluteDir() const
/*!
Returns \c true if the user can read the file; otherwise returns \c false.
+ If the file is a symlink, this function returns true if the target is
+ readable (not the symlink).
+
\note If the \l{NTFS permissions} check has not been enabled, the result
on Windows will merely reflect whether the file exists.
@@ -920,6 +925,9 @@ bool QFileInfo::isReadable() const
/*!
Returns \c true if the user can write to the file; otherwise returns \c false.
+ If the file is a symlink, this function returns true if the target is
+ writeable (not the symlink).
+
\note If the \l{NTFS permissions} check has not been enabled, the result on
Windows will merely reflect whether the file is marked as Read Only.
@@ -937,6 +945,9 @@ bool QFileInfo::isWritable() const
/*!
Returns \c true if the file is executable; otherwise returns \c false.
+ If the file is a symlink, this function returns true if the target is
+ executable (not the symlink).
+
\sa isReadable(), isWritable(), permission()
*/
bool QFileInfo::isExecutable() const
@@ -951,8 +962,13 @@ bool QFileInfo::isExecutable() const
/*!
Returns \c true if this is a `hidden' file; otherwise returns \c false.
- \b{Note:} This function returns \c true for the special entries
- "." and ".." on Unix, even though QDir::entryList threats them as shown.
+ \b{Note:} This function returns \c true for the special entries "." and
+ ".." on Unix, even though QDir::entryList threats them as shown. And note
+ that, since this function inspects the file name, on Unix it will inspect
+ the name of the symlink, if this file is a symlink, not the target's name.
+
+ On Windows, this function returns \c true if the target file is hidden (not
+ the symlink).
*/
bool QFileInfo::isHidden() const
{
@@ -991,6 +1007,9 @@ bool QFileInfo::isNativePath() const
link to a file. Returns \c false if the
object points to something which isn't a file, such as a directory.
+ If the file is a symlink, this function returns true if the target is a
+ regular file (not the symlink).
+
\sa isDir(), isSymLink(), isBundle()
*/
bool QFileInfo::isFile() const
@@ -1006,6 +1025,9 @@ bool QFileInfo::isFile() const
Returns \c true if this object points to a directory or to a symbolic
link to a directory; otherwise returns \c false.
+ If the file is a symlink, this function returns true if the target is a
+ directory (not the symlink).
+
\sa isFile(), isSymLink(), isBundle()
*/
bool QFileInfo::isDir() const
@@ -1023,6 +1045,9 @@ bool QFileInfo::isDir() const
Returns \c true if this object points to a bundle or to a symbolic
link to a bundle on \macos and iOS; otherwise returns \c false.
+ If the file is a symlink, this function returns true if the target is a
+ bundle (not the symlink).
+
\sa isDir(), isSymLink(), isFile()
*/
bool QFileInfo::isBundle() const
@@ -1044,7 +1069,8 @@ bool QFileInfo::isBundle() const
the \l{symLinkTarget()}{link's target}.
In addition, true will be returned for shortcuts (\c *.lnk files) on
- Windows. Opening those will open the \c .lnk file itself.
+ Windows. This behavior is deprecated and will likely change in a future
+ version of Qt. Opening those will open the \c .lnk file itself.
Example:
@@ -1190,6 +1216,9 @@ QString QFileInfo::symLinkTarget() const
milliseconds). On Windows, it will return an empty string unless
the \l{NTFS permissions} check has been enabled.
+ If the file is a symlink, this function returns the owner of the target
+ (not the symlink).
+
\sa ownerId(), group(), groupId()
*/
QString QFileInfo::owner() const
@@ -1206,6 +1235,9 @@ QString QFileInfo::owner() const
On Windows and on systems where files do not have owners this
function returns ((uint) -2).
+ If the file is a symlink, this function returns the id of the owner of the target
+ (not the symlink).
+
\sa owner(), group(), groupId()
*/
uint QFileInfo::ownerId() const
@@ -1225,6 +1257,9 @@ uint QFileInfo::ownerId() const
This function can be time consuming under Unix (in the order of
milliseconds).
+ If the file is a symlink, this function returns the owning group of the
+ target (not the symlink).
+
\sa groupId(), owner(), ownerId()
*/
QString QFileInfo::group() const
@@ -1241,6 +1276,9 @@ QString QFileInfo::group() const
On Windows and on systems where files do not have groups this
function always returns (uint) -2.
+ If the file is a symlink, this function returns the id of the group owning the
+ target (not the symlink).
+
\sa group(), owner(), ownerId()
*/
uint QFileInfo::groupId() const
@@ -1266,6 +1304,9 @@ uint QFileInfo::groupId() const
Example:
\snippet code/src_corelib_io_qfileinfo.cpp 10
+ If the file is a symlink, this function checks the permissions of the
+ target (not the symlink).
+
\sa isReadable(), isWritable(), isExecutable()
*/
bool QFileInfo::permission(QFile::Permissions permissions) const
@@ -1288,6 +1329,9 @@ bool QFileInfo::permission(QFile::Permissions permissions) const
\note The result might be inaccurate on Windows if the
\l{NTFS permissions} check has not been enabled.
+
+ If the file is a symlink, this function returns the permissions of the
+ target (not the symlink).
*/
QFile::Permissions QFileInfo::permissions() const
{
@@ -1305,6 +1349,9 @@ QFile::Permissions QFileInfo::permissions() const
Returns the file size in bytes. If the file does not exist or cannot be
fetched, 0 is returned.
+ If the file is a symlink, the size of the target file is returned
+ (not the symlink).
+
\sa exists()
*/
qint64 QFileInfo::size() const
@@ -1334,6 +1381,9 @@ qint64 QFileInfo::size() const
the time the file was created, metadataChangeTime() to get the time its
metadata was last changed, or lastModified() to get the time it was last modified.
+ If the file is a symlink, the time of the target file is returned
+ (not the symlink).
+
\sa birthTime(), metadataChangeTime(), lastModified(), lastRead()
*/
QDateTime QFileInfo::created() const
@@ -1352,6 +1402,9 @@ QDateTime QFileInfo::created() const
If the file birth time is not available, this function returns an invalid
QDateTime.
+ If the file is a symlink, the time of the target file is returned
+ (not the symlink).
+
\sa lastModified(), lastRead(), metadataChangeTime()
*/
QDateTime QFileInfo::birthTime() const
@@ -1366,6 +1419,9 @@ QDateTime QFileInfo::birthTime() const
user writes or sets inode information (for example, changing the file
permissions).
+ If the file is a symlink, the time of the target file is returned
+ (not the symlink).
+
\sa lastModified(), lastRead()
*/
QDateTime QFileInfo::metadataChangeTime() const
@@ -1376,6 +1432,9 @@ QDateTime QFileInfo::metadataChangeTime() const
/*!
Returns the date and local time when the file was last modified.
+ If the file is a symlink, the time of the target file is returned
+ (not the symlink).
+
\sa birthTime(), lastRead(), metadataChangeTime(), fileTime()
*/
QDateTime QFileInfo::lastModified() const
@@ -1389,6 +1448,9 @@ QDateTime QFileInfo::lastModified() const
On platforms where this information is not available, returns the
same as lastModified().
+ If the file is a symlink, the time of the target file is returned
+ (not the symlink).
+
\sa birthTime(), lastModified(), metadataChangeTime(), fileTime()
*/
QDateTime QFileInfo::lastRead() const
@@ -1402,6 +1464,9 @@ QDateTime QFileInfo::lastRead() const
Returns the file time specified by \a time. If the time cannot be
determined, an invalid date time is returned.
+ If the file is a symlink, the time of the target file is returned
+ (not the symlink).
+
\sa QFile::FileTime, QDateTime::isValid()
*/
QDateTime QFileInfo::fileTime(QFile::FileTime time) const
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index 7194a2faf7..ceea3a467c 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -69,7 +69,9 @@ static bool checkNameDecodable(const char *d_name, qsizetype len)
# ifdef QT_LOCALE_IS_UTF8
int mibEnum = 106;
# else
- int mibEnum = codec->mibEnum();
+ int mibEnum = 4; // Latin 1
+ if (codec)
+ mibEnum = codec->mibEnum();
# endif
if (Q_LIKELY(mibEnum == 106)) // UTF-8
return QUtf8::isValidUtf8(d_name, len).isValidUtf8;
@@ -86,6 +88,8 @@ static bool checkNameDecodable(const char *d_name, qsizetype len)
Q_UNUSED(d_name);
Q_UNUSED(len);
// if we have no text codecs, then QString::fromLocal8Bit is fromLatin1
+ Q_UNUSED(d_name)
+ Q_UNUSED(len)
return true;
#endif
}
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 64c422c55a..54460aff77 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -41,9 +41,9 @@
#include "qfilesystemwatcher_p.h"
#include <qdatetime.h>
-#include <qdebug.h>
#include <qdir.h>
#include <qfileinfo.h>
+#include <qloggingcategory.h>
#include <qset.h>
#include <qtimer.h>
@@ -67,6 +67,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcWatcher, "qt.core.filesystemwatcher")
+
QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent)
{
#if defined(Q_OS_WIN)
@@ -137,6 +139,7 @@ void QFileSystemWatcherPrivate::initPollerEngine()
void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed)
{
Q_Q(QFileSystemWatcher);
+ qCDebug(lcWatcher) << "file changed" << path << "removed?" << removed << "watching?" << files.contains(path);
if (!files.contains(path)) {
// the path was removed after a change was detected, but before we delivered the signal
return;
@@ -149,6 +152,7 @@ void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
{
Q_Q(QFileSystemWatcher);
+ qCDebug(lcWatcher) << "directory changed" << path << "removed?" << removed << "watching?" << directories.contains(path);
if (!directories.contains(path)) {
// perhaps the path was removed after a change was detected, but before we delivered the signal
return;
@@ -355,7 +359,7 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
qWarning("QFileSystemWatcher::addPaths: list is empty");
return p;
}
-
+ qCDebug(lcWatcher) << "adding" << paths;
const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* {
#ifdef QT_BUILD_INTERNAL
const QString on = objectName();
@@ -364,11 +368,11 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
// Autotest override case - use the explicitly selected engine only
const QStringRef forceName = on.midRef(26);
if (forceName == QLatin1String("poller")) {
- qDebug("QFileSystemWatcher: skipping native engine, using only polling engine");
+ qCDebug(lcWatcher, "QFileSystemWatcher: skipping native engine, using only polling engine");
d_func()->initPollerEngine();
return d->poller;
} else if (forceName == QLatin1String("native")) {
- qDebug("QFileSystemWatcher: skipping polling engine, using only native engine");
+ qCDebug(lcWatcher, "QFileSystemWatcher: skipping polling engine, using only native engine");
return d->native;
}
return nullptr;
@@ -431,6 +435,7 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
qWarning("QFileSystemWatcher::removePaths: list is empty");
return p;
}
+ qCDebug(lcWatcher) << "removing" << paths;
if (d->native)
p = d->native->removePaths(p, &d->files, &d->directories);
@@ -446,6 +451,12 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
This signal is emitted when the file at the specified \a path is
modified, renamed or removed from disk.
+ \note As a safety measure, many applications save an open file by
+ writing a new file and then deleting the old one. In your slot
+ function, you can check \c watcher.files().contains(path).
+ If it returns \c false, check whether the file still exists
+ and then call \c addPath() to continue watching it.
+
\sa directoryChanged()
*/
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index f6ff56c83c..4d4784cdf7 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -70,14 +70,16 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
QLoggingCategory represents a certain logging category - identified by a
string - at runtime. A category can be configured to enable or disable
- logging of messages per message type. Whether a message type is enabled or
- not can be checked with the \l isDebugEnabled(), \l isInfoEnabled(),
- \l isWarningEnabled(), and \l isCriticalEnabled() methods.
-
- All objects are meant to be configured by a common registry (see also
- \l{Configuring Categories}). Different objects can also represent the same
- category. It is therefore not recommended to export objects across module
- boundaries, nor to manipulate the objects directly, nor to inherit from
+ logging of messages per message type.
+
+ To check whether a message type is enabled or not, use one of these methods:
+ \l isDebugEnabled(), \l isInfoEnabled(), \l isWarningEnabled(), and
+ \l isCriticalEnabled().
+
+ All objects are meant to be configured by a common registry, as described in
+ \l{Configuring Categories}. Different objects can also represent the same
+ category. Therefore, it's \b{not} recommended to export objects across
+ module boundaries, to manipulate the objects directly, or to inherit from
QLoggingCategory.
\section1 Creating Category Objects
@@ -87,17 +89,17 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\snippet qloggingcategory/main.cpp 1
- \note Category names are free text. However, to allow easy configuration
- of the categories using \l{Logging Rules} the names should follow some rules:
+ Category names are free text; to configure categories using \l{Logging Rules}, their
+ names should follow this convention:
\list
\li Use letters and numbers only.
- \li Further structure categories into common areas by using dots.
- \li Avoid the category names \c{debug}, \c{info}, \c{warning}, and \c{critical}.
- \li Category names starting with \c{qt} are reserved for Qt modules.
+ \li Use dots to further structure categories into common areas.
+ \li Avoid the category names: \c{debug}, \c{info}, \c{warning}, and \c{critical}.
+ \li Category names with the \c{qt} prefix are solely reserved for Qt modules.
\endlist
- QLoggingCategory objects implicitly defined by Q_LOGGING_CATEGORY()
- are created on first use in a thread-safe manner.
+ QLoggingCategory objects that are implicitly defined by Q_LOGGING_CATEGORY()
+ are created on first use, in a thread-safe manner.
\section1 Checking Category Configuration
@@ -105,8 +107,8 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\l isWarningEnabled(), \l isCriticalEnabled(), as well as \l isEnabled()
to check whether messages for the given message type should be logged.
- \note The qCDebug(), qCWarning(), qCCritical() macros prevent arguments
- from being evaluated if the respective message types are not enabled for the
+ The qCDebug(), qCWarning(), and qCCritical() macros prevent arguments from
+ being evaluated if the respective message types are not enabled for the
category, so explicit checking is not needed:
\snippet qloggingcategory/main.cpp 4
@@ -119,28 +121,27 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\snippet qloggingcategory/main.cpp 5
- will log messages of type \c QtWarningMsg, \c QtCriticalMsg, \c QtFatalMsg, but will
- ignore messages of type \c QtDebugMsg and \c QtInfoMsg.
+ logs messages of type \c QtWarningMsg, \c QtCriticalMsg, \c QtFatalMsg, but
+ ignores messages of type \c QtDebugMsg and \c QtInfoMsg.
- If no argument is passed, all messages will be logged.
+ If no argument is passed, all messages are logged.
\section1 Configuring Categories
- The default configuration of categories can be overridden either by setting logging
- rules, or by installing a custom filter.
+ You can override the default configuration for categories either by setting
+ logging rules, or by installing a custom filter.
\section2 Logging Rules
- Logging rules allow logging for categories to be enabled or disabled in a
- flexible way. Rules are specified in text, where every line must have the
- format
+ Logging rules let you enable or disable logging for categories in a flexible
+ way. Rules are specified in text, where every line must have the format:
\snippet code/src_corelib_io_qloggingcategory.cpp 0
\c <category> is the name of the category, potentially with \c{*} as a
- wildcard symbol as the first or last character (or at both positions).
- The optional \c <type> must be either \c debug, \c info, \c warning, or \c critical.
- Lines that do not fit this scheme are ignored.
+ wildcard symbol for the first or last character; or at both positions.
+ The optional \c <type> must be \c debug, \c info, \c warning, or \c critical.
+ Lines that don't fit this scheme are ignored.
Rules are evaluated in text order, from first to last. That is, if two rules
apply to a category/type, the rule that comes later is applied.
@@ -149,47 +150,37 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\snippet code/src_corelib_io_qloggingcategory.cpp 1
- Since Qt 5.3, logging rules are also
- automatically loaded from the \c [Rules] section of a logging
- configuration file. Such configuration files are looked up in the QtProject
- configuration directory, or explicitly set in a \c QT_LOGGING_CONF
- environment variable:
+ Logging rules are automatically loaded from the \c [Rules] section in a logging
+ configuration file. These configuration files are looked up in the QtProject
+ configuration directory, or explicitly set in a \c QT_LOGGING_CONF environment
+ variable:
\snippet code/src_corelib_io_qloggingcategory.cpp 2
- Since Qt 5.3, logging rules can also be specified in a \c QT_LOGGING_RULES
- environment variable. And since Qt 5.6, multiple rules can also be
- separated by semicolons:
+ Logging rules can also be specified in a \c QT_LOGGING_RULES environment variable;
+ multiple rules can also be separated by semicolons:
\snippet code/src_corelib_io_qloggingcategory.cpp 3
- Rules set by \l setFilterRules() take precedence over rules specified
- in the QtProject configuration directory, and can, in turn, be
- overwritten by rules from the configuration file specified by
- \c QT_LOGGING_CONF, and rules set by \c QT_LOGGING_RULES.
-
- Order of evaluation:
- \list
- \li [QLibraryInfo::DataPath]/qtlogging.ini
- \li QtProject/qtlogging.ini
- \li \l setFilterRules()
- \li \c QT_LOGGING_CONF
- \li \c QT_LOGGING_RULES
+ Rules set by \l setFilterRules() take precedence over rules specified in the
+ QtProject configuration directory. In turn, these rules can be overwritten by those
+ from the configuration file specified by \c QT_LOGGING_CONF, and those set by
+ \c QT_LOGGING_RULES.
+
+ The order of evaluation is as follows:
+ \list 1
+ \li [QLibraryInfo::DataPath]/qtlogging.ini
+ \li QtProject/qtlogging.ini
+ \li \l setFilterRules()
+ \li \c QT_LOGGING_CONF
+ \li \c QT_LOGGING_RULES
\endlist
The \c QtProject/qtlogging.ini file is looked up in all directories returned
- by QStandardPaths::GenericConfigLocation, e.g.
+ by QStandardPaths::GenericConfigLocation.
- \list
- \li on \macos and iOS: \c ~/Library/Preferences
- \li on Unix: \c ~/.config, \c /etc/xdg
- \li on Windows: \c %LOCALAPPDATA%, \c %ProgramData%,
- \l QCoreApplication::applicationDirPath(),
- QCoreApplication::applicationDirPath() + \c "/data"
- \endlist
-
- Set the \c QT_LOGGING_DEBUG environment variable to see from where
- logging rules are loaded.
+ Set the \c QT_LOGGING_DEBUG environment variable to find out where you logging
+ rules are loaded from.
\section2 Installing a Custom Filter
@@ -211,7 +202,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
If \a category is \c{0}, the category name is changed to \c "default".
- Note that \a category must be kept valid during the lifetime of this object.
+ \note \a category must be kept valid during the lifetime of this object.
*/
QLoggingCategory::QLoggingCategory(const char *category)
: d(nullptr),
@@ -226,7 +217,7 @@ QLoggingCategory::QLoggingCategory(const char *category)
If \a category is \c{0}, the category name is changed to \c "default".
- Note that \a category must be kept valid during the lifetime of this object.
+ \note \a category must be kept valid during the lifetime of this object.
\since 5.4
*/
@@ -251,7 +242,7 @@ void QLoggingCategory::init(const char *category, QtMsgType severityLevel)
}
/*!
- Destructs a QLoggingCategory object.
+ Destroys a QLoggingCategory object.
*/
QLoggingCategory::~QLoggingCategory()
{
@@ -268,24 +259,24 @@ QLoggingCategory::~QLoggingCategory()
/*!
\fn bool QLoggingCategory::isDebugEnabled() const
- Returns \c true if debug messages should be shown for this category.
- Returns \c false otherwise.
+ Returns \c true if debug messages should be shown for this category;
+ \c false otherwise.
- \note The \l qCDebug() macro already does this check before executing any
- code. However, calling this method may be useful to avoid
- expensive generation of data that is only used for debug output.
+ \note The \l qCDebug() macro already does this check before running any
+ code. However, calling this method may be useful to avoid the
+ expensive generation of data for debug output only.
*/
/*!
\fn bool QLoggingCategory::isInfoEnabled() const
- Returns \c true if informational messages should be shown for this category.
- Returns \c false otherwise.
+ Returns \c true if informational messages should be shown for this category;
+ \c false otherwise.
\note The \l qCInfo() macro already does this check before executing any
- code. However, calling this method may be useful to avoid
- expensive generation of data that is only used for debug output.
+ code. However, calling this method may be useful to avoid the
+ expensive generation of data for debug output only.
\since 5.5
*/
@@ -294,28 +285,28 @@ QLoggingCategory::~QLoggingCategory()
/*!
\fn bool QLoggingCategory::isWarningEnabled() const
- Returns \c true if warning messages should be shown for this category.
- Returns \c false otherwise.
+ Returns \c true if warning messages should be shown for this category;
+ \c false otherwise.
\note The \l qCWarning() macro already does this check before executing any
- code. However, calling this method may be useful to avoid
- expensive generation of data that is only used for debug output.
+ code. However, calling this method may be useful to avoid the
+ expensive generation of data for debug output only.
*/
/*!
\fn bool QLoggingCategory::isCriticalEnabled() const
- Returns \c true if critical messages should be shown for this category.
- Returns \c false otherwise.
+ Returns \c true if critical messages should be shown for this category;
+ \c false otherwise.
\note The \l qCCritical() macro already does this check before executing any
- code. However, calling this method may be useful to avoid
- expensive generation of data that is only used for debug output.
+ code. However, calling this method may be useful to avoid the
+ expensive generation of data for debug output only.
*/
/*!
Returns \c true if a message of type \a msgtype for the category should be
- shown. Returns \c false otherwise.
+ shown; \c false otherwise.
*/
bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
{
@@ -332,11 +323,11 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
/*!
Changes the message type \a type for the category to \a enable.
- This method is meant to be used only from inside a filter
- installed by \l installFilter(). See \l {Configuring Categories} for
- an overview on how to configure categories globally.
+ This method is meant for use only from inside a filter installed with
+ \l installFilter(). For an overview on how to configure categories globally,
+ see \l {Configuring Categories}.
- \note \c QtFatalMsg cannot be changed. It will always remain \c true.
+ \note \c QtFatalMsg cannot be changed; it will always remain \c true.
*/
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
@@ -359,28 +350,25 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
/*!
\fn QLoggingCategory &QLoggingCategory::operator()()
- Returns the object itself. This allows both a QLoggingCategory variable, and
- a factory method returning a QLoggingCategory, to be used in \l qCDebug(),
- \l qCWarning(), \l qCCritical() macros.
+ Returns the object itself. This allows for both: a QLoggingCategory variable, and
+ a factory method that returns a QLoggingCategory, to be used in \l qCDebug(),
+ \l qCWarning(), or \l qCCritical() macros.
*/
/*!
\fn const QLoggingCategory &QLoggingCategory::operator()() const
- Returns the object itself. This allows both a QLoggingCategory variable, and
- a factory method returning a QLoggingCategory, to be used in \l qCDebug(),
- \l qCWarning(), \l qCCritical() macros.
+ Returns the object itself. This allows for both: a QLoggingCategory variable, and
+ a factory method that returns a QLoggingCategory, to be used in \l qCDebug(),
+ \l qCWarning(), or \l qCCritical() macros.
*/
/*!
- Returns a pointer to the global category \c "default" that
- is used e.g. by qDebug(), qInfo(), qWarning(), qCritical(), qFatal().
+ Returns a pointer to the global category \c "default" that is used, for
+ example, by qDebug(), qInfo(), qWarning(), qCritical(), or qFatal().
- \note The returned pointer may be null during destruction of
- static objects.
-
- \note Ownership of the category is not transferred, do not
- \c delete the returned pointer.
+ \note The pointer returned may be null during destruction of static objects.
+ Also, don't \c delete this pointer, as ownership of the category isn't transferred.
*/
QLoggingCategory *QLoggingCategory::defaultCategory()
@@ -391,8 +379,7 @@ QLoggingCategory *QLoggingCategory::defaultCategory()
/*!
\typedef QLoggingCategory::CategoryFilter
- This is a typedef for a pointer to a function with the following
- signature:
+ This is a typedef for a pointer to a function with the following signature:
\snippet qloggingcategory/main.cpp 20
@@ -408,14 +395,13 @@ QLoggingCategory *QLoggingCategory::defaultCategory()
filter is free to change the respective category configuration with
\l setEnabled().
- The filter might be called from different threads, but never concurrently.
- The filter shall not call any static functions of QLoggingCategory.
+ When you define your filter, note that it can be called from different threads; but never
+ concurrently. This filter cannot call any static functions from QLoggingCategory.
Example:
\snippet qloggingcategory/main.cpp 21
- An alternative way of configuring the default filter is via
- \l setFilterRules().
+ Alternatively, you can configure the default filter via \l setFilterRules().
*/
QLoggingCategory::CategoryFilter
QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
@@ -425,15 +411,15 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
/*!
Configures which categories and message types should be enabled through a
- a set of \a rules.
+ set of \a rules.
Example:
\snippet qloggingcategory/main.cpp 2
\note The rules might be ignored if a custom category filter is installed
- with \l installFilter(), or if the user defined \c QT_LOGGING_CONF or \c QT_LOGGING_RULES
- environment variable.
+ with \l installFilter(), or if the user has defined the \c QT_LOGGING_CONF
+ or the \c QT_LOGGING_RULES environment variable.
*/
void QLoggingCategory::setFilterRules(const QString &rules)
{
@@ -446,7 +432,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.2
- Returns an output stream for debug messages in the logging category
+ Returns an output stream for debug messages in the logging category,
\a category.
The macro expands to code that checks whether
@@ -457,8 +443,8 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qloggingcategory/main.cpp 10
- \note Arguments are not processed if debug output for the category is not
- enabled, so do not rely on any side effects.
+ \note Arguments aren't processed if the debug output for that \a category is not
+ enabled, so don't rely on any side effects.
\sa qDebug()
*/
@@ -469,16 +455,16 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.3
- Logs a debug message \a message in the logging category \a category.
- \a message might contain place holders that are replaced by additional
- arguments, similar to the C printf() function.
+ Logs a debug message, \a message, in the logging category, \a category.
+ \a message may contain place holders to be replaced by additional arguments,
+ similar to the C printf() function.
Example:
\snippet qloggingcategory/main.cpp 13
- \note Arguments might not be processed if debug output for the category is
- not enabled, so do not rely on any side effects.
+ \note Arguments aren't processed if the debug output for that \a category is not
+ enabled, so don't rely on any side effects.
\sa qDebug()
*/
@@ -489,7 +475,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.5
- Returns an output stream for informational messages in the logging category
+ Returns an output stream for informational messages in the logging category,
\a category.
The macro expands to code that checks whether
@@ -500,8 +486,8 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qloggingcategory/main.cpp qcinfo_stream
- \note Arguments are not processed if debug output for the category is not
- enabled, so do not rely on any side effects.
+ \note If the debug output for a particular category isn't enabled, arguments
+ won't be processed, so don't rely on any side effects.
\sa qInfo()
*/
@@ -512,16 +498,16 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.5
- Logs an informational message \a message in the logging category \a category.
- \a message might contain place holders that are replaced by additional
- arguments, similar to the C printf() function.
+ Logs an informational message, \a message, in the logging category, \a category.
+ \a message may contain place holders to be replaced by additional arguments,
+ similar to the C printf() function.
Example:
\snippet qloggingcategory/main.cpp qcinfo_printf
- \note Arguments might not be processed if debug output for the category is
- not enabled, so do not rely on any side effects.
+ \note If the debug output for a particular category isn't enabled, arguments
+ won't be processed, so don't rely on any side effects.
\sa qInfo()
*/
@@ -532,7 +518,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.2
- Returns an output stream for warning messages in the logging category
+ Returns an output stream for warning messages in the logging category,
\a category.
The macro expands to code that checks whether
@@ -543,8 +529,8 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qloggingcategory/main.cpp 11
- \note Arguments are not processed if warning output for the category is not
- enabled, so do not rely on any side effects.
+ \note If the warning output for a particular category isn't enabled, arguments
+ won't be processed, so don't rely on any side effects.
\sa qWarning()
*/
@@ -555,16 +541,16 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.3
- Logs a warning message \a message in the logging category \a category.
- \a message might contain place holders that are replaced by additional
- arguments, similar to the C printf() function.
+ Logs a warning message, \a message, in the logging category, \a category.
+ \a message may contain place holders to be replaced by additional arguments,
+ similar to the C printf() function.
Example:
\snippet qloggingcategory/main.cpp 14
- \note Arguments might not be processed if warning output for the category is
- not enabled, so do not rely on any side effects.
+ \note If the warning output for a particular category isn't enabled, arguments
+ won't be processed, so don't rely on any side effects.
\sa qWarning()
*/
@@ -575,7 +561,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.2
- Returns an output stream for critical messages in the logging category
+ Returns an output stream for critical messages in the logging category,
\a category.
The macro expands to code that checks whether
@@ -586,8 +572,9 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qloggingcategory/main.cpp 12
- \note Arguments are not processed if critical output for the category is not
- enabled, so do not rely on any side effects.
+
+ \note If the critical output for a particular category isn't enabled, arguments
+ won't be processed, so don't rely on any side effects.
\sa qCritical()
*/
@@ -598,16 +585,16 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\threadsafe
\since 5.3
- Logs a critical message \a message in the logging category \a category.
- \a message might contain place holders that are replaced by additional
- arguments, similar to the C printf() function.
+ Logs a critical message, \a message, in the logging category, \a category.
+ \a message may contain place holders to be replaced by additional arguments,
+ similar to the C printf() function.
Example:
\snippet qloggingcategory/main.cpp 15
- \note Arguments might not be processed if critical output for the category
- is not enabled, so do not rely on any side effects.
+ \note If the critical output for a particular category isn't enabled, arguments
+ won't be processed, so don't rely on any side effects.
\sa qCritical()
*/
@@ -633,7 +620,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\a string identifier. By default, all message types are enabled.
Only one translation unit in a library or executable can define a category
- with a specific name. The implicitly defined QLoggingCategory object is
+ with a specific name. The implicitly-defined QLoggingCategory object is
created on first use, in a thread-safe manner.
This macro must be used outside of a class or method.
@@ -650,7 +637,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
and more severe are enabled, types with a lower severity are disabled.
Only one translation unit in a library or executable can define a category
- with a specific name. The implicitly defined QLoggingCategory object is
+ with a specific name. The implicitly-defined QLoggingCategory object is
created on first use, in a thread-safe manner.
This macro must be used outside of a class or method. It is only defined
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 22c22ce711..86d361b06a 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1109,14 +1109,8 @@ bool QDynamicFileResourceRoot::registerSelf(const QString &f)
uchar *data = nullptr;
qsizetype data_len = 0;
-#ifdef QT_USE_MMAP
- int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,
-#if defined(Q_OS_WIN)
- _S_IREAD | _S_IWRITE
-#else
- 0666
-#endif
- );
+#if defined(QT_USE_MMAP)
+ int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, 0666);
if (fd >= 0) {
QT_STATBUF st;
if (!QT_FSTAT(fd, &st) && st.st_size <= std::numeric_limits<qsizetype>::max()) {
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index f41e6302a2..0a884a7df9 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -243,9 +243,15 @@ bool QSaveFile::open(OpenMode mode)
return false;
};
+ bool requiresDirectWrite = false;
#ifdef Q_OS_WIN
// check if it is an Alternate Data Stream
- if (d->finalFileName == d->fileName && d->fileName.indexOf(QLatin1Char(':'), 2) > 1) {
+ requiresDirectWrite = d->finalFileName == d->fileName && d->fileName.indexOf(QLatin1Char(':'), 2) > 1;
+#elif defined(Q_OS_ANDROID)
+ // check if it is a content:// URL
+ requiresDirectWrite = d->fileName.startsWith(QLatin1String("content://"));
+#endif
+ if (requiresDirectWrite) {
// yes, we can't rename onto it...
if (d->directWriteFallback) {
if (openDirectly())
@@ -254,14 +260,12 @@ bool QSaveFile::open(OpenMode mode)
d->fileEngine.reset();
} else {
QString msg =
- QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback "
- "enabled: path contains an Alternate Data Stream specifier")
- .arg(QDir::toNativeSeparators(d->fileName));
+ QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback enabled.")
+ .arg(QDir::toNativeSeparators(d->fileName));
d->setError(QFileDevice::OpenError, msg);
}
return false;
}
-#endif
d->fileEngine.reset(new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared));
// if the target file exists, we'll copy its permissions below,
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 4a119a1e2f..fc7122d904 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -746,7 +746,6 @@ bool QSettingsPrivate::iniUnescapedStringList(const QByteArray &str, int from, i
{ '\'', '\'' },
{ '\\', '\\' }
};
- static const int numEscapeCodes = sizeof(escapeCodes) / sizeof(escapeCodes[0]);
bool isStringList = false;
bool inQuotedString = false;
@@ -770,9 +769,9 @@ StNormal:
goto end;
ch = str.at(i++);
- for (int j = 0; j < numEscapeCodes; ++j) {
- if (ch == escapeCodes[j][0]) {
- stringResult += QLatin1Char(escapeCodes[j][1]);
+ for (const auto &escapeCode : escapeCodes) {
+ if (ch == escapeCode[0]) {
+ stringResult += QLatin1Char(escapeCode[1]);
goto StNormal;
}
}
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index f56fef7f8e..7874b854e4 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -232,7 +232,7 @@ QT_BEGIN_NAMESPACE
\row \li DocumentsLocation
\li "~/Documents"
\row \li FontsLocation
- \li "~/.fonts"
+ \li "~/.fonts", "~/.local/share/fonts", "/usr/local/share/fonts", "/usr/share/fonts"
\row \li ApplicationsLocation
\li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
\row \li MusicLocation
@@ -345,6 +345,8 @@ QT_BEGIN_NAMESPACE
\note On Android, applications with open files on the external storage (<USER> locations),
will be killed if the external storage is unmounted.
+ \note On Android, reading/writing to GenericDataLocation needs the READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE permission granted.
+
\note On iOS, if you do pass \c {QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()}
as argument to \l{QFileDialog::setDirectory()},
a native image picker dialog will be used for accessing the user's photo album.
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 6425890e3f..c35d7adc9f 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -339,6 +339,9 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
break;
case FontsLocation:
dirs += QDir::homePath() + QLatin1String("/.fonts");
+ dirs += xdgDataDirs();
+ for (int i = 1; i < dirs.count(); ++i)
+ dirs[i].append(QLatin1String("/fonts"));
break;
default:
break;
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index 912609ec91..fc3e16b241 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -125,10 +125,10 @@ Q_CORE_EXPORT bool qIsEffectiveTLD(const QStringRef &domain)
return true;
const int dot = domain.indexOf(QLatin1Char('.'));
- if (dot >= 0) {
- if (containsTLDEntry(domain.mid(dot), SuffixMatch)) // 2
- return !containsTLDEntry(domain, ExceptionMatch); // 3
- }
+ if (dot < 0) // Actual TLD: may be effective if the subject of a wildcard rule:
+ return containsTLDEntry(QString(QLatin1Char('.') + domain), SuffixMatch);
+ if (containsTLDEntry(domain.mid(dot), SuffixMatch)) // 2
+ return !containsTLDEntry(domain, ExceptionMatch); // 3
return false;
}
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 878e007fb0..a7650390f9 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -979,7 +979,7 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro
// validate it:
int needsLowercasing = -1;
- const ushort *p = reinterpret_cast<const ushort *>(value.constData());
+ const ushort *p = value.utf16();
for (int i = 0; i < len; ++i) {
if (p[i] >= 'a' && p[i] <= 'z')
continue;
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index 43649cf79b..2cc1bd8ce6 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -156,7 +156,6 @@ inline uint qHash(const QPersistentModelIndex &index, uint seed) noexcept
Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
#endif
-template<typename T> class QList;
typedef QList<QModelIndex> QModelIndexList;
class QMimeData;
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 9e9e71c397..b1f3b74cd4 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -211,6 +211,12 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
debug << "QMacAutoReleasePool(" << (const void *)pool << ')';
return debug;
}
+
+QDebug operator<<(QDebug debug, const QCFString &string)
+{
+ debug << static_cast<QString>(string);
+ return debug;
+}
#endif // !QT_NO_DEBUG_STREAM
#ifdef Q_OS_MACOS
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 3266dc10a8..535d3579b2 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -137,8 +137,10 @@ private:
template <typename T>
class QCFType : public QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>
{
+ using Base = QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>;
public:
- using QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>::QAppleRefCounted;
+ using Base::Base;
+ explicit QCFType(CFTypeRef r) : Base(static_cast<T>(r)) {}
template <typename X> X as() const { return reinterpret_cast<X>(this->value); }
static QCFType constructFromGet(const T &t)
{
@@ -151,6 +153,7 @@ public:
class Q_CORE_EXPORT QCFString : public QCFType<CFStringRef>
{
public:
+ using QCFType<CFStringRef>::QCFType;
inline QCFString(const QString &str) : QCFType<CFStringRef>(0), string(str) {}
inline QCFString(const CFStringRef cfstr = 0) : QCFType<CFStringRef>(cfstr) {}
inline QCFString(const QCFType<CFStringRef> &other) : QCFType<CFStringRef>(other) {}
@@ -168,7 +171,8 @@ Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
#endif
#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool);
+Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool);
+Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QCFString &string);
#endif
Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 1ecef00a2d..6531cd8e0c 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2693,7 +2693,14 @@ Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
QStringList QCoreApplication::libraryPaths()
{
QMutexLocker locker(libraryPathMutex());
+ return libraryPathsLocked();
+}
+/*!
+ \internal
+*/
+QStringList QCoreApplication::libraryPathsLocked()
+{
if (coreappdata()->manual_libpaths)
return *(coreappdata()->manual_libpaths);
@@ -2701,18 +2708,22 @@ QStringList QCoreApplication::libraryPaths()
QStringList *app_libpaths = new QStringList;
coreappdata()->app_libpaths.reset(app_libpaths);
- QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH");
- if (!libPathEnv.isEmpty()) {
- QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts);
- for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
- QString canonicalPath = QDir(*it).canonicalPath();
- if (!canonicalPath.isEmpty()
- && !app_libpaths->contains(canonicalPath)) {
- app_libpaths->append(canonicalPath);
+ auto setPathsFromEnv = [&](QString libPathEnv) {
+ if (!libPathEnv.isEmpty()) {
+ QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts);
+ for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
+ QString canonicalPath = QDir(*it).canonicalPath();
+ if (!canonicalPath.isEmpty()
+ && !app_libpaths->contains(canonicalPath)) {
+ app_libpaths->append(canonicalPath);
+ }
}
}
- }
-
+ };
+ setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH"));
+#ifdef Q_OS_ANDROID
+ setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH"));
+#endif
#ifdef Q_OS_DARWIN
// Check the main bundle's PlugIns directory as this is a standard location for Apple OSes.
// Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value
@@ -2769,7 +2780,7 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
// When the application is constructed it should still amend the paths. So we keep the originals
// around, and even create them if they don't exist, yet.
if (!coreappdata()->app_libpaths)
- libraryPaths();
+ libraryPathsLocked();
if (coreappdata()->manual_libpaths)
*(coreappdata()->manual_libpaths) = paths;
@@ -2812,7 +2823,7 @@ void QCoreApplication::addLibraryPath(const QString &path)
return;
} else {
// make sure that library paths are initialized
- libraryPaths();
+ libraryPathsLocked();
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (app_libpaths->contains(canonicalPath))
return;
@@ -2851,7 +2862,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
return;
} else {
// make sure that library paths is initialized
- libraryPaths();
+ libraryPathsLocked();
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (!app_libpaths->contains(canonicalPath))
return;
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index b7df004736..71ea124fbe 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -208,6 +208,9 @@ private:
static bool notifyInternal2(QObject *receiver, QEvent *);
static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr);
#endif
+#if QT_CONFIG(library)
+ static QStringList libraryPathsLocked();
+#endif
static QCoreApplication *self;
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 33c231987f..177551467c 100644
--- a/src/corelib/kernel/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -56,6 +56,14 @@
# include <UIKit/UIApplication.h>
#endif
+QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher");
+Q_LOGGING_CATEGORY(lcEventDispatcherTimers, "qt.eventdispatcher.timers");
+}
+using namespace QtPrivate;
+QT_END_NAMESPACE
+
QT_USE_NAMESPACE
/*
@@ -148,9 +156,6 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher");
-Q_LOGGING_CATEGORY(lcEventDispatcherTimers, "qt.eventdispatcher.timers");
-
class RunLoopDebugger : public QObject
{
Q_OBJECT
@@ -423,7 +428,7 @@ bool QEventDispatcherCoreFoundation::processPostedEvents()
m_processEvents.processedPostedEvents = true;
qCDebug(lcEventDispatcher) << "Sending posted events for"
- << QEventLoop::ProcessEventsFlags(m_processEvents.flags.load());
+ << QEventLoop::ProcessEventsFlags(m_processEvents.flags.loadRelaxed());
QCoreApplication::sendPostedEvents();
return true;
diff --git a/src/corelib/kernel/qeventdispatcher_cf_p.h b/src/corelib/kernel/qeventdispatcher_cf_p.h
index 26191d520c..a2cecd9a93 100644
--- a/src/corelib/kernel/qeventdispatcher_cf_p.h
+++ b/src/corelib/kernel/qeventdispatcher_cf_p.h
@@ -98,8 +98,10 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(RunLoopModeTracker));
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher);
-Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcherTimers)
+namespace QtPrivate {
+Q_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher);
+Q_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcherTimers)
+}
class QEventDispatcherCoreFoundation;
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 600c6c38fd..f7a1f969a8 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -44,12 +44,13 @@
#include <QtCore/QHash>
#include <QtCore/QMutex>
#include <QtCore/QSemaphore>
-#include <QtCore/QSharedPointer>
#include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
#include <functional>
+#include <memory>
+
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.system.threading.h>
@@ -300,19 +301,19 @@ HRESULT QEventDispatcherWinRT::runOnMainThread(const std::function<HRESULT()> &d
if (QThread::currentThread() == QCoreApplication::instance()->thread())
return delegate();
- auto semaphore = QSharedPointer<QSemaphore>(new QSemaphore);
- auto ptrSemaphore = new QSharedPointer<QSemaphore>(semaphore);
- auto result = QSharedPointer<HRESULT>(new HRESULT);
- auto ptrResult = new QSharedPointer<HRESULT>(result);
+ struct State {
+ QSemaphore semaphore;
+ HRESULT result;
+ };
+
+ const auto state = std::make_shared<State>();
- QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, ptrSemaphore, ptrResult]() {
- **ptrResult = delegate();
- delete ptrResult;
- (*ptrSemaphore)->release();
- delete ptrSemaphore;
+ QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, state]() {
+ const QSemaphoreReleaser releaser{state->semaphore};
+ state->result = delegate();
}, nullptr);
- return semaphore->tryAcquire(1, timeout) ? *result : E_FAIL;
+ return state->semaphore.tryAcquire(1, timeout) ? state->result : E_FAIL;
}
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index cc396d9239..a8e8866339 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -112,6 +112,13 @@ QT_BEGIN_NAMESPACE
are returned by classInfo(), and you can search for pairs with
indexOfClassInfo().
+ \note Operations that use the meta object system are generally thread-
+ safe, as QMetaObjects are typically static read-only instances
+ generated at compile time. However, if meta objects are dynamically
+ modified by the application (for instance, when using QQmlPropertyMap),
+ then the application has to explicitly synchronize access to the
+ respective meta object.
+
\sa QMetaClassInfo, QMetaEnum, QMetaMethod, QMetaProperty, QMetaType,
{Meta-Object System}
*/
@@ -3648,6 +3655,21 @@ const char* QMetaClassInfo::value() const
}
/*!
+ \class QMethodRawArguments
+ \internal
+
+ A wrapper class for the void ** arguments array used by the meta
+ object system. If a slot uses a single argument of this type,
+ the meta object system will pass the raw arguments array directly
+ to the slot and set the arguments count in the slot description to
+ zero, so that any signal can connect to it.
+
+ This is used internally to implement signal relay functionality in
+ our state machine and dbus.
+*/
+
+
+/*!
\macro QGenericArgument Q_ARG(Type, const Type &value)
\relates QMetaObject
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index fcd92afd89..31fecd0b07 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -46,9 +46,6 @@
QT_BEGIN_NAMESPACE
-
-template <typename T> class QList;
-
#define Q_METAMETHOD_INVOKE_MAX_ARGS 10
class Q_CORE_EXPORT QMetaMethod
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index ef28c0164c..d713555bb6 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -161,7 +161,6 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
#endif
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
-void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
@@ -902,30 +901,8 @@ static bool check_parent_thread(QObject *parent,
*/
QObject::QObject(QObject *parent)
- : d_ptr(new QObjectPrivate)
+ : QObject(*new QObjectPrivate, parent)
{
- Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");
-
- Q_D(QObject);
- d_ptr->q_ptr = this;
- d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
- d->threadData->ref();
- if (parent) {
- QT_TRY {
- if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
- parent = 0;
- setParent(parent);
- } QT_CATCH(...) {
- d->threadData->deref();
- QT_RETHROW;
- }
- }
-#if QT_VERSION < 0x60000
- qt_addObject(this);
-#endif
- if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
- reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
- Q_TRACE(QObject_ctor, this);
}
/*!
@@ -1013,15 +990,8 @@ QObject::~QObject()
emit destroyed(this);
}
- if (d->declarativeData) {
- if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
- if (QAbstractDeclarativeData::destroyed_qml1)
- QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
- } else {
- if (QAbstractDeclarativeData::destroyed)
- QAbstractDeclarativeData::destroyed(d->declarativeData, this);
- }
- }
+ if (d->declarativeData && QAbstractDeclarativeData::destroyed)
+ QAbstractDeclarativeData::destroyed(d->declarativeData, this);
QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
if (cd) {
@@ -2153,7 +2123,9 @@ void QObjectPrivate::setParent_helper(QObject *o)
// cleared our entry in parentD->children.
} else {
const int index = parentD->children.indexOf(q);
- if (parentD->isDeletingChildren) {
+ if (index < 0) {
+ // we're probably recursing into setParent() from a ChildRemoved event, don't do anything
+ } else if (parentD->isDeletingChildren) {
parentD->children[index] = 0;
} else {
parentD->children.removeAt(index);
@@ -3904,11 +3876,12 @@ void doActivate(QObject *sender, int signal_index, void **argv)
if (connections->currentConnectionId.loadRelaxed() == 0)
senderDeleted = true;
}
- if (!senderDeleted)
+ if (!senderDeleted) {
sp->connections.loadRelaxed()->cleanOrphanedConnections(sender);
- if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
- signal_spy_set->signal_end_callback(sender, signal_index);
+ if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
+ signal_spy_set->signal_end_callback(sender, signal_index);
+ }
}
/*!
@@ -4343,22 +4316,18 @@ QDebug operator<<(QDebug dbg, const QObject *o)
\relates QObject
\obsolete
+ In new code, you should prefer the use of the Q_ENUM() macro, which makes the
+ type available also to the meta type system.
+ For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS().
+
This macro registers one or several enum types to the meta-object
system.
- For example:
-
- \snippet code/src_corelib_kernel_qobject.cpp 38
-
If you want to register an enum that is declared in another class,
the enum must be fully qualified with the name of the class
defining it. In addition, the class \e defining the enum has to
inherit QObject as well as declare the enum using Q_ENUMS().
- In new code, you should prefer the use of the Q_ENUM() macro, which makes the
- type available also to the meta type system.
- For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS().
-
\sa {Qt's Property System}
*/
@@ -4560,7 +4529,7 @@ QDebug operator<<(QDebug dbg, const QObject *o)
It works exactly like the Q_NAMESPACE macro. However, the external
\c{staticMetaObject} variable that gets defined in the namespace
is declared with the supplied \c{EXPORT_MACRO} qualifier. This is
- useful f.i. if the object needs to be exported from a dynamic library.
+ useful if the object needs to be exported from a dynamic library.
\sa Q_NAMESPACE, {Creating Shared Libraries}
*/
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index d19d10b47c..11ebba7787 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -89,7 +89,6 @@ class Q_CORE_EXPORT QAbstractDeclarativeData
{
public:
static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
- static void (*destroyed_qml1)(QAbstractDeclarativeData *, QObject *);
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
@@ -97,14 +96,6 @@ public:
static void (*setWidgetParent)(QObject *, QObject *); // Used by the QML engine to specify parents for widgets. Set by QtWidgets.
};
-// This is an implementation of QAbstractDeclarativeData that is identical with
-// the implementation in QtDeclarative and QtQml for the first bit
-struct QAbstractDeclarativeDataImpl : public QAbstractDeclarativeData
-{
- quint32 ownedByQml1:1;
- quint32 unused: 31;
-};
-
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index dc2d832fe5..9f654b0318 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -285,6 +285,10 @@ class QMetaEnum;
class QMetaProperty;
class QMetaClassInfo;
+struct QMethodRawArguments
+{
+ void **arguments;
+};
class Q_CORE_EXPORT QGenericArgument
{
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index 7052bcf0d4..5efdb0b395 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -54,20 +54,11 @@ class QPointer
{
Q_STATIC_ASSERT_X(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
- template<typename U>
- struct TypeSelector
- {
- typedef QObject Type;
- };
- template<typename U>
- struct TypeSelector<const U>
- {
- typedef const QObject Type;
- };
- typedef typename TypeSelector<T>::Type QObjectType;
+ using QObjectType =
+ typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
QWeakPointer<QObjectType> wp;
public:
- inline QPointer() { }
+ QPointer() = default;
inline QPointer(T *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine!
// compiler-generated dtor is fine!
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 178227e914..948f697dc5 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -604,8 +604,8 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
\since 5.12
\overload
- Creates a connection from the timeout() signal to \a slot, and returns a
- handle to the connection.
+ Creates a connection of type \a connectionType from the timeout() signal
+ to \a slot, and returns a handle to the connection.
This method is provided for convenience.
It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, slot, connectionType)}.
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index ddb96ecad6..31c1277b03 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -58,11 +58,11 @@
#include "qendian.h"
#include "qresource.h"
-#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
-#define QT_USE_MMAP
-#include "private/qcore_unix_p.h"
+#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
+# define QT_USE_MMAP
+# include "private/qcore_unix_p.h"
// for mmap
-#include <sys/mman.h>
+# include <sys/mman.h>
#endif
#include <stdlib.h>
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index f7fa47c801..a7e16ac351 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2254,10 +2254,10 @@ QVariant::QVariant(const QRegularExpression &re)
: d(RegularExpression)
{ v_construct<QRegularExpression>(&d, re); }
#endif // QT_CONFIG(regularexpression)
-#ifndef QT_BOOTSTRAPPED
QVariant::QVariant(const QUuid &uuid)
: d(Uuid)
{ v_construct<QUuid>(&d, uuid); }
+#ifndef QT_BOOTSTRAPPED
QVariant::QVariant(const QJsonValue &jsonValue)
: d(QMetaType::QJsonValue)
{ v_construct<QJsonValue>(&d, jsonValue); }
@@ -3011,7 +3011,6 @@ QPersistentModelIndex QVariant::toPersistentModelIndex() const
}
#endif // QT_CONFIG(itemmodel)
-#ifndef QT_BOOTSTRAPPED
/*!
\since 5.0
@@ -3026,6 +3025,7 @@ QUuid QVariant::toUuid() const
return qVariantToHelper<QUuid>(d, handlerManager);
}
+#ifndef QT_BOOTSTRAPPED
/*!
\since 5.0
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index e7d3d9c835..86c7414704 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -256,12 +256,12 @@ class Q_CORE_EXPORT QVariant
#if QT_CONFIG(regularexpression)
QVariant(const QRegularExpression &re);
#endif // QT_CONFIG(regularexpression)
-#ifndef QT_BOOTSTRAPPED
- QVariant(const QUrl &url);
#if QT_CONFIG(easingcurve)
QVariant(const QEasingCurve &easing);
#endif
QVariant(const QUuid &uuid);
+#ifndef QT_BOOTSTRAPPED
+ QVariant(const QUrl &url);
QVariant(const QJsonValue &jsonValue);
QVariant(const QJsonObject &jsonObject);
QVariant(const QJsonArray &jsonArray);
@@ -332,12 +332,12 @@ class Q_CORE_EXPORT QVariant
#if QT_CONFIG(regularexpression)
QRegularExpression toRegularExpression() const;
#endif // QT_CONFIG(regularexpression)
-#ifndef QT_BOOTSTRAPPED
- QUrl toUrl() const;
#if QT_CONFIG(easingcurve)
QEasingCurve toEasingCurve() const;
#endif
QUuid toUuid() const;
+#ifndef QT_BOOTSTRAPPED
+ QUrl toUrl() const;
QJsonValue toJsonValue() const;
QJsonObject toJsonObject() const;
QJsonArray toJsonArray() const;
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 24a7a35ea5..ce84a15831 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -91,8 +91,8 @@ bool QMimeDatabasePrivate::shouldCheck()
return true;
}
-#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
-#define QT_USE_MMAP
+#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
+# define QT_USE_MMAP
#endif
void QMimeDatabasePrivate::loadProviders()
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 6737aeccd2..18f10c9b43 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -193,7 +193,11 @@ void QFactoryLoader::update()
continue;
d->loadedPaths << pluginDir;
+#ifdef Q_OS_ANDROID
+ QString path = pluginDir;
+#else
QString path = pluginDir + d->suffix;
+#endif
if (qt_debug_component())
qDebug() << "QFactoryLoader::QFactoryLoader() checking directory path" << path << "...";
@@ -202,8 +206,10 @@ void QFactoryLoader::update()
continue;
QStringList plugins = QDir(path).entryList(
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN)
QStringList(QStringLiteral("*.dll")),
+#elif defined(Q_OS_ANDROID)
+ QStringList(QLatin1String("libplugins_%1_*.so").arg(d->suffix)),
#endif
QDir::Files);
QLibraryPrivate *library = 0;
@@ -339,6 +345,10 @@ QFactoryLoader::QFactoryLoader(const char *iid,
#if QT_CONFIG(library)
d->cs = cs;
d->suffix = suffix;
+# ifdef Q_OS_ANDROID
+ if (!d->suffix.isEmpty() && d->suffix.at(0) == QLatin1Char('/'))
+ d->suffix.remove(0, 1);
+# endif
QMutexLocker locker(qt_factoryloader_mutex());
update();
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index a8db108eeb..39a170db3f 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
# define QLIBRARY_AS_DEBUG true
#endif
-#if defined(Q_OS_UNIX) || defined(Q_CC_MINGW)
+#if defined(Q_OS_UNIX) || (defined(Q_CC_MINGW) && !QT_CONFIG(debug_and_release))
// We don't use separate debug and release libs on UNIX, so we want
// to allow loading plugins, regardless of how they were built.
# define QT_NO_DEBUG_PLUGIN_CHECK
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 44d5513163..f0de1010d7 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -236,6 +236,14 @@ bool QLibraryPrivate::load_sys()
auto attemptFromBundle = attempt;
pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
}
+ if (pHnd) {
+ using JniOnLoadPtr = jint (*)(JavaVM *vm, void *reserved);
+ JniOnLoadPtr jniOnLoad = reinterpret_cast<JniOnLoadPtr>(dlsym(pHnd, "JNI_OnLoad"));
+ if (jniOnLoad && jniOnLoad(QtAndroidPrivate::javaVM(), nullptr) == JNI_ERR) {
+ dlclose(pHnd);
+ pHnd = nullptr;
+ }
+ }
#endif
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 4e0c3a511b..cadff4f32b 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -311,6 +311,16 @@ static QString locatePlugin(const QString& fileName)
for (const QString &path : qAsConst(paths)) {
for (const QString &prefix : qAsConst(prefixes)) {
for (const QString &suffix : qAsConst(suffixes)) {
+#ifdef Q_OS_ANDROID
+ {
+ QString pluginPath = basePath + prefix + baseName + suffix;
+ const QString fn = path + QLatin1String("/lib") + pluginPath.replace(QLatin1Char('/'), QLatin1Char('_'));
+ if (debug)
+ qDebug() << "Trying..." << fn;
+ if (QFileInfo(fn).isFile())
+ return fn;
+ }
+#endif
const QString fn = path + QLatin1Char('/') + basePath + prefix + baseName + suffix;
if (debug)
qDebug() << "Trying..." << fn;
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index cfcd89333b..bcfcd47ccf 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -43,6 +43,7 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qiodevice.h>
#include <QtCore/qpair.h>
+#include <QtCore/qcontainerfwd.h>
#ifdef Status
#error qdatastream.h must be included before any header file that defines Status
@@ -54,12 +55,6 @@ class qfloat16;
class QByteArray;
class QIODevice;
-template <typename T> class QList;
-template <typename T> class QVector;
-template <typename T> class QSet;
-template <class Key, class T> class QHash;
-template <class Key, class T> class QMap;
-
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
class QDataStreamPrivate;
namespace QtPrivate {
diff --git a/src/corelib/serialization/qjsonarray.h b/src/corelib/serialization/qjsonarray.h
index 983a6753b5..287671419f 100644
--- a/src/corelib/serialization/qjsonarray.h
+++ b/src/corelib/serialization/qjsonarray.h
@@ -48,7 +48,6 @@ QT_BEGIN_NAMESPACE
class QDebug;
class QStringList;
-template <typename T> class QList;
typedef QList<QVariant> QVariantList;
class Q_CORE_EXPORT QJsonArray
diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp
index 193b80ee22..8c3818caff 100644
--- a/src/corelib/serialization/qjsondocument.cpp
+++ b/src/corelib/serialization/qjsondocument.cpp
@@ -332,7 +332,7 @@ QVariant QJsonDocument::toVariant() const
}
/*!
- Converts the QJsonDocument to a UTF-8 encoded JSON document.
+ Converts the QJsonDocument to an indented, UTF-8 encoded JSON document.
\sa fromJson()
*/
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index a675c3cede..cf59cc54c7 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -2056,7 +2056,7 @@ bool QTextStreamPrivate::getReal(double *f)
// nan/+inf/-inf, so here we also check for uppercase and mixed
// case versions.
if (!qstricmp(buf, "nan") || !qstricmp(buf, "+nan") || !qstricmp(buf, "-nan")) {
- *f = qSNaN();
+ *f = qQNaN();
return true;
} else if (!qstricmp(buf, "+inf") || !qstricmp(buf, "inf")) {
*f = qInf();
diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h
index 72592b8731..a9d5b96920 100644
--- a/src/corelib/statemachine/qsignaleventgenerator_p.h
+++ b/src/corelib/statemachine/qsignaleventgenerator_p.h
@@ -62,13 +62,12 @@ class QStateMachine;
class QSignalEventGenerator : public QObject
{
- Q_OBJECT_FAKE
+ Q_OBJECT
public:
QSignalEventGenerator(QStateMachine *parent);
-private:
-// slots
- void execute(void **_a);
+private Q_SLOTS:
+ void execute(QMethodRawArguments a);
private:
Q_DISABLE_COPY_MOVE(QSignalEventGenerator)
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 3a86d971e2..0ed92514f9 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -2538,6 +2538,10 @@ QStateMachine::~QStateMachine()
state machine. Commonly, this could mean that one of the states has not been given
any parent or added to any machine. The context of this error is the source state of
the transition.
+ \value StateMachineChildModeSetToParallelError The machine's \l childMode
+ property was set to \l{QState::ParallelStates}. This is illegal.
+ Only states may be declared as parallel, not the state machine
+ itself. This enum value was added in Qt 5.14.
\sa setErrorState()
*/
@@ -3041,102 +3045,14 @@ void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation)
#endif // animation
-
-// Begin moc-generated code -- modify carefully (check "HAND EDIT" parts)!
-struct qt_meta_stringdata_QSignalEventGenerator_t {
- QByteArrayData data[3];
- char stringdata[32];
-};
-#define QT_MOC_LITERAL(idx, ofs, len) \
- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
- offsetof(qt_meta_stringdata_QSignalEventGenerator_t, stringdata) + ofs \
- - idx * sizeof(QByteArrayData) \
- )
-static const qt_meta_stringdata_QSignalEventGenerator_t qt_meta_stringdata_QSignalEventGenerator = {
- {
-QT_MOC_LITERAL(0, 0, 21),
-QT_MOC_LITERAL(1, 22, 7),
-QT_MOC_LITERAL(2, 30, 0)
- },
- "QSignalEventGenerator\0execute\0\0"
-};
-#undef QT_MOC_LITERAL
-
-static const uint qt_meta_data_QSignalEventGenerator[] = {
-
- // content:
- 7, // revision
- 0, // classname
- 0, 0, // classinfo
- 1, 14, // methods
- 0, 0, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 0, // signalCount
-
- // slots: name, argc, parameters, tag, flags
- 1, 0, 19, 2, 0x0a,
-
- // slots: parameters
- QMetaType::Void,
-
- 0 // eod
-};
-
-void QSignalEventGenerator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
-{
- if (_c == QMetaObject::InvokeMetaMethod) {
- Q_ASSERT(staticMetaObject.cast(_o));
- QSignalEventGenerator *_t = static_cast<QSignalEventGenerator *>(_o);
- switch (_id) {
- case 0: _t->execute(_a); break; // HAND EDIT: add the _a parameter
- default: ;
- }
- }
- Q_UNUSED(_a);
-}
-
-const QMetaObject QSignalEventGenerator::staticMetaObject = {
- { &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator.data,
- qt_meta_data_QSignalEventGenerator, qt_static_metacall, 0, 0 }
-};
-
-const QMetaObject *QSignalEventGenerator::metaObject() const
-{
- return &staticMetaObject;
-}
-
-void *QSignalEventGenerator::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_QSignalEventGenerator.stringdata))
- return static_cast<void*>(const_cast< QSignalEventGenerator*>(this));
- return QObject::qt_metacast(_clname);
-}
-
-int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
- _id = QObject::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- if (_c == QMetaObject::InvokeMetaMethod) {
- if (_id < 1)
- qt_static_metacall(this, _c, _id, _a);
- _id -= 1;
- }
- return _id;
-}
-// End moc-generated code
-
-void QSignalEventGenerator::execute(void **_a)
+void QSignalEventGenerator::execute(QMethodRawArguments a)
{
auto machinePrivate = QStateMachinePrivate::get(qobject_cast<QStateMachine*>(parent()));
if (machinePrivate->state != QStateMachinePrivate::Running)
return;
int signalIndex = senderSignalIndex();
Q_ASSERT(signalIndex != -1);
- machinePrivate->handleTransitionSignal(sender(), signalIndex, _a);
+ machinePrivate->handleTransitionSignal(sender(), signalIndex, a.arguments);
}
QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent)
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index c50e087c10..444980e9c0 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -1775,12 +1775,7 @@ void QByteArray::resize(int size)
return;
}
- if (size == 0 && !d->capacityReserved) {
- Data *x = Data::allocate(0);
- if (!d->ref.deref())
- Data::deallocate(d);
- d = x;
- } else if (d->size == 0 && d->ref.isStatic()) {
+ if (d->size == 0 && d->ref.isStatic()) {
//
// Optimize the idiom:
// QByteArray a;
@@ -1795,9 +1790,7 @@ void QByteArray::resize(int size)
x->data()[size] = '\0';
d = x;
} else {
- if (d->ref.isShared() || uint(size) + 1u > d->alloc
- || (!d->capacityReserved && size < d->size
- && uint(size) + 1u < uint(d->alloc >> 1)))
+ if (d->ref.isShared() || uint(size) + 1u > d->alloc)
reallocData(uint(size) + 1u, d->detachFlags() | Data::Grow);
if (d->alloc) {
d->size = size;
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h
index 7c571706d8..03d842e9bc 100644
--- a/src/corelib/text/qbytearray.h
+++ b/src/corelib/text/qbytearray.h
@@ -44,6 +44,7 @@
#include <QtCore/qrefcount.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qarraydata.h>
+#include <QtCore/qcontainerfwd.h>
#include <stdlib.h>
#include <string.h>
@@ -112,7 +113,6 @@ Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len, Qt::ChecksumType standa
class QByteRef;
class QString;
class QDataStream;
-template <typename T> class QList;
typedef QArrayData QByteArrayData;
diff --git a/src/corelib/text/qchar.cpp b/src/corelib/text/qchar.cpp
index 7dd353b4ba..9b03a93278 100644
--- a/src/corelib/text/qchar.cpp
+++ b/src/corelib/text/qchar.cpp
@@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QLatin1Char
\inmodule QtCore
+ \reentrant
\brief The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
\ingroup string-processing
@@ -1465,18 +1466,18 @@ QChar::UnicodeVersion QChar::currentUnicodeVersion() noexcept
}
-template <typename Traits, typename T>
-Q_DECL_CONST_FUNCTION static inline T convertCase_helper(T uc) noexcept
+template <typename T>
+Q_DECL_CONST_FUNCTION static inline T convertCase_helper(T uc, QUnicodeTables::Case which) noexcept
{
- const QUnicodeTables::Properties *prop = qGetProp(uc);
+ const auto fold = qGetProp(uc)->cases[which];
- if (Q_UNLIKELY(Traits::caseSpecial(prop))) {
- const ushort *specialCase = specialCaseMap + Traits::caseDiff(prop);
+ if (Q_UNLIKELY(fold.special)) {
+ const ushort *specialCase = specialCaseMap + fold.diff;
// so far, there are no special cases beyond BMP (guaranteed by the qunicodetables generator)
return *specialCase == 1 ? specialCase[1] : uc;
}
- return uc + Traits::caseDiff(prop);
+ return uc + fold.diff;
}
/*!
@@ -1496,7 +1497,7 @@ uint QChar::toLower(uint ucs4) noexcept
{
if (ucs4 > LastValidCodePoint)
return ucs4;
- return convertCase_helper<QUnicodeTables::LowercaseTraits>(ucs4);
+ return convertCase_helper(ucs4, QUnicodeTables::LowerCase);
}
/*!
@@ -1516,7 +1517,7 @@ uint QChar::toUpper(uint ucs4) noexcept
{
if (ucs4 > LastValidCodePoint)
return ucs4;
- return convertCase_helper<QUnicodeTables::UppercaseTraits>(ucs4);
+ return convertCase_helper(ucs4, QUnicodeTables::UpperCase);
}
/*!
@@ -1536,7 +1537,7 @@ uint QChar::toTitleCase(uint ucs4) noexcept
{
if (ucs4 > LastValidCodePoint)
return ucs4;
- return convertCase_helper<QUnicodeTables::TitlecaseTraits>(ucs4);
+ return convertCase_helper(ucs4, QUnicodeTables::TitleCase);
}
static inline uint foldCase(const ushort *ch, const ushort *start)
@@ -1544,7 +1545,7 @@ static inline uint foldCase(const ushort *ch, const ushort *start)
uint ucs4 = *ch;
if (QChar::isLowSurrogate(ucs4) && ch > start && QChar::isHighSurrogate(*(ch - 1)))
ucs4 = QChar::surrogateToUcs4(*(ch - 1), ucs4);
- return convertCase_helper<QUnicodeTables::CasefoldTraits>(ucs4);
+ return convertCase_helper(ucs4, QUnicodeTables::CaseFold);
}
static inline uint foldCase(uint ch, uint &last) noexcept
@@ -1553,12 +1554,12 @@ static inline uint foldCase(uint ch, uint &last) noexcept
if (QChar::isLowSurrogate(ucs4) && QChar::isHighSurrogate(last))
ucs4 = QChar::surrogateToUcs4(last, ucs4);
last = ch;
- return convertCase_helper<QUnicodeTables::CasefoldTraits>(ucs4);
+ return convertCase_helper(ucs4, QUnicodeTables::CaseFold);
}
static inline ushort foldCase(ushort ch) noexcept
{
- return convertCase_helper<QUnicodeTables::CasefoldTraits>(ch);
+ return convertCase_helper(ch, QUnicodeTables::CaseFold);
}
static inline QChar foldCase(QChar ch) noexcept
@@ -1582,7 +1583,7 @@ uint QChar::toCaseFolded(uint ucs4) noexcept
{
if (ucs4 > LastValidCodePoint)
return ucs4;
- return convertCase_helper<QUnicodeTables::CasefoldTraits>(ucs4);
+ return convertCase_helper(ucs4, QUnicodeTables::CaseFold);
}
/*!
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp
index 91e393e343..75a5bc802e 100644
--- a/src/corelib/text/qlocale.cpp
+++ b/src/corelib/text/qlocale.cpp
@@ -345,6 +345,23 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const
return localeId.withLikelySubtagsRemoved().name(separator);
}
+/*!
+ \internal
+ */
+QByteArray QLocalePrivate::rawName(char separator) const
+{
+ QByteArrayList parts;
+ if (m_data->m_language_id != QLocale::AnyLanguage)
+ parts.append(languageCode().latin1());
+ if (m_data->m_script_id != QLocale::AnyScript)
+ parts.append(scriptCode().latin1());
+ if (m_data->m_country_id != QLocale::AnyCountry)
+ parts.append(countryCode().latin1());
+
+ return parts.join(separator);
+}
+
+
static const QLocaleData *findLocaleDataById(const QLocaleId &lid)
{
QLocaleId localeId = lid.withLikelySubtagsAdded();
@@ -2916,7 +2933,7 @@ static QString rawStandaloneWeekDayName(const QLocaleData *data, const int day,
QString QCalendarBackend::monthName(const QLocale &locale, int month, int,
QLocale::FormatType format) const
{
- Q_ASSERT(month >= 1 && month <= maxMonthsInYear());
+ Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
return rawMonthName(localeMonthIndexData()[locale.d->m_data_offset],
localeMonthData(), month, format);
}
@@ -2942,7 +2959,7 @@ QString QGregorianCalendar::monthName(const QLocale &locale, int month, int year
QString QCalendarBackend::standaloneMonthName(const QLocale &locale, int month, int,
QLocale::FormatType format) const
{
- Q_ASSERT(month >= 1 && month <= maxMonthsInYear());
+ Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
return rawStandaloneMonthName(localeMonthIndexData()[locale.d->m_data_offset],
localeMonthData(), month, format);
}
@@ -4367,30 +4384,63 @@ QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats
*/
QStringList QLocale::uiLanguages() const
{
+ QStringList uiLanguages;
+ QVector<QLocale> locales;
#ifndef QT_NO_SYSTEMLOCALE
if (d->m_data == systemData()) {
QVariant res = systemLocale()->query(QSystemLocale::UILanguages, QVariant());
if (!res.isNull()) {
- QStringList result = res.toStringList();
- if (!result.isEmpty())
- return result;
+ uiLanguages = res.toStringList();
+ // ... but we need to include likely-adjusted forms of each of those, too:
+ for (const auto entry : qAsConst(uiLanguages))
+ locales.append(QLocale(entry));
}
- }
+ } else
#endif
- QLocaleId id = QLocaleId::fromIds(d->m_data->m_language_id, d->m_data->m_script_id,
- d->m_data->m_country_id);
- const QLocaleId max = id.withLikelySubtagsAdded();
- const QLocaleId min = max.withLikelySubtagsRemoved();
+ {
+ locales.append(*this);
+ }
+ for (int i = locales.size(); i-- > 0; ) {
+ const QLocale &locale = locales.at(i);
+ int j;
+ QByteArray prior;
+ if (i < uiLanguages.size()) {
+ // Adding likely-adjusted forms to system locale's list.
+ // Name the locale is derived from:
+ const QString &name = uiLanguages.at(i);
+ prior = name.toLatin1();
+ // Don't try to likely-adjust if construction's likely-adjustments
+ // were so drastic the result doesn't match the prior name:
+ if (locale.name() != name && locale.d->rawName() != prior)
+ continue;
+ // Insert just after prior:
+ j = i + 1;
+ } else {
+ // Plain locale, not system locale; just append.
+ j = uiLanguages.size();
+ }
+ const auto data = locale.d->m_data;
+
+ QLocaleId id
+ = QLocaleId::fromIds(data->m_language_id, data->m_script_id, data->m_country_id);
+ const QLocaleId max = id.withLikelySubtagsAdded();
+ const QLocaleId min = max.withLikelySubtagsRemoved();
+ id.script_id = 0; // For re-use as script-less variant.
+
+ // Include version with all likely sub-tags (last) if distinct from the rest:
+ if (max != min && max != id && max.name() != prior)
+ uiLanguages.insert(j, QString::fromLatin1(max.name()));
+
+ // Include scriptless version if likely-equivalent and distinct:
+ if (data->m_script_id && id != min && id.name() != prior
+ && id.withLikelySubtagsAdded() == max) {
+ uiLanguages.insert(j, QString::fromLatin1(id.name()));
+ }
- QStringList uiLanguages;
- uiLanguages.append(QString::fromLatin1(min.name()));
- if (id.script_id) {
- id.script_id = 0;
- if (id != min && id.withLikelySubtagsAdded() == max)
- uiLanguages.append(QString::fromLatin1(id.name()));
+ // Include minimal version (first) unless it's what our locale is derived from:
+ if (min.name() != prior)
+ uiLanguages.insert(j, QString::fromLatin1(min.name()));
}
- if (max != min && max != id)
- uiLanguages.append(QString::fromLatin1(max.name()));
return uiLanguages;
}
diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h
index 5ebed9b385..edee3a89c7 100644
--- a/src/corelib/text/qlocale_p.h
+++ b/src/corelib/text/qlocale_p.h
@@ -359,6 +359,7 @@ public:
quint16 countryId() const { return m_data->m_country_id; }
QByteArray bcp47Name(char separator = '-') const;
+ QByteArray rawName(char separator = '-') const;
inline QLatin1String languageCode() const { return languageToCode(QLocale::Language(m_data->m_language_id)); }
inline QLatin1String scriptCode() const { return scriptToCode(QLocale::Script(m_data->m_script_id)); }
diff --git a/src/corelib/text/qlocale_tools.cpp b/src/corelib/text/qlocale_tools.cpp
index db8c8cd12f..c246028b4d 100644
--- a/src/corelib/text/qlocale_tools.cpp
+++ b/src/corelib/text/qlocale_tools.cpp
@@ -293,7 +293,7 @@ double qt_asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
// "-nan" or "+nan"
if (qstrcmp(num, "nan") == 0) {
processed = 3;
- return qt_snan();
+ return qt_qnan();
} else if ((num[0] == '-' || num[0] == '+') && qstrcmp(num + 1, "nan") == 0) {
processed = 0;
ok = false;
@@ -322,7 +322,7 @@ double qt_asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
conv_flags = double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES
| double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES;
}
- double_conversion::StringToDoubleConverter conv(conv_flags, 0.0, qt_snan(), 0, 0);
+ double_conversion::StringToDoubleConverter conv(conv_flags, 0.0, qt_qnan(), 0, 0);
d = conv.StringToDouble(num, numLen, &processed);
if (!qIsFinite(d)) {
diff --git a/src/corelib/text/qlocale_tools_p.h b/src/corelib/text/qlocale_tools_p.h
index 594331ae37..e2142bf545 100644
--- a/src/corelib/text/qlocale_tools_p.h
+++ b/src/corelib/text/qlocale_tools_p.h
@@ -54,22 +54,6 @@
#include "qlocale_p.h"
#include "qstring.h"
-#if !defined(QT_QLOCALE_NEEDS_VOLATILE)
-# if defined(Q_CC_GNU)
-# if __GNUC__ == 4
-# define QT_QLOCALE_NEEDS_VOLATILE
-# elif defined(Q_OS_WIN)
-# define QT_QLOCALE_NEEDS_VOLATILE
-# endif
-# endif
-#endif
-
-#if defined(QT_QLOCALE_NEEDS_VOLATILE)
-# define NEEDS_VOLATILE volatile
-#else
-# define NEEDS_VOLATILE
-#endif
-
QT_BEGIN_NAMESPACE
enum StrayCharacterMode {
diff --git a/src/corelib/text/qregexp.cpp b/src/corelib/text/qregexp.cpp
index 41f3508ff8..ac4d9bbc36 100644
--- a/src/corelib/text/qregexp.cpp
+++ b/src/corelib/text/qregexp.cpp
@@ -3008,12 +3008,10 @@ int QRegExpEngine::getEscape()
yyCharClass->addSingleton(0x005f); // '_'
return Tok_CharClass;
case 'I':
- if (xmlSchemaExtensions) {
- yyCharClass->setNegative(!yyCharClass->negative());
- Q_FALLTHROUGH();
- } else {
+ if (!xmlSchemaExtensions)
break;
- }
+ yyCharClass->setNegative(!yyCharClass->negative());
+ Q_FALLTHROUGH();
case 'i':
if (xmlSchemaExtensions) {
yyCharClass->addCategories(FLAG(QChar::Mark_NonSpacing) |
@@ -3048,12 +3046,10 @@ int QRegExpEngine::getEscape()
break;
}
case 'C':
- if (xmlSchemaExtensions) {
- yyCharClass->setNegative(!yyCharClass->negative());
- Q_FALLTHROUGH();
- } else {
+ if (!xmlSchemaExtensions)
break;
- }
+ yyCharClass->setNegative(!yyCharClass->negative());
+ Q_FALLTHROUGH();
case 'c':
if (xmlSchemaExtensions) {
yyCharClass->addCategories(FLAG(QChar::Mark_NonSpacing) |
@@ -3094,12 +3090,10 @@ int QRegExpEngine::getEscape()
break;
}
case 'P':
- if (xmlSchemaExtensions) {
- yyCharClass->setNegative(!yyCharClass->negative());
- Q_FALLTHROUGH();
- } else {
+ if (!xmlSchemaExtensions)
break;
- }
+ yyCharClass->setNegative(!yyCharClass->negative());
+ Q_FALLTHROUGH();
case 'p':
if (xmlSchemaExtensions) {
if (yyCh != '{') {
diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp
index 17acd476b2..8d2187eb28 100644
--- a/src/corelib/text/qregularexpression.cpp
+++ b/src/corelib/text/qregularexpression.cpp
@@ -531,7 +531,7 @@ QT_BEGIN_NAMESPACE
optimize the execution of the matching algorithm. The JIT makes extensive
usage of self-modifying code, which can lead debugging tools such as
Valgrind to crash. You must enable all checks for self-modifying code if
- you want to debug programs using QRegularExpression (f.i., see Valgrind's
+ you want to debug programs using QRegularExpression (for instance, Valgrind's
\c{--smc-check} command line option). The downside of enabling such checks
is that your program will run considerably slower.
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 375843e36e..51aa0b7512 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -1193,10 +1193,10 @@ static int qt_compare_strings(QLatin1String lhs, QStringView rhs, Qt::CaseSensit
static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSensitivity cs) noexcept
{
- if (cs == Qt::CaseInsensitive)
- return qstrnicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size());
if (lhs.isEmpty())
return lencmp(0, rhs.size());
+ if (cs == Qt::CaseInsensitive)
+ return qstrnicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size());
const auto l = std::min(lhs.size(), rhs.size());
int r = qstrncmp(lhs.data(), rhs.data(), l);
return r ? r : lencmp(lhs.size(), rhs.size());
@@ -6629,9 +6629,9 @@ namespace QUnicodeTables {
reallocate memory to grow the buffer. In that case, we need to adjust the \a
it pointer.
*/
-template <typename Traits, typename T>
+template <typename T>
Q_NEVER_INLINE
-static QString detachAndConvertCase(T &str, QStringIterator it)
+static QString detachAndConvertCase(T &str, QStringIterator it, QUnicodeTables::Case which)
{
Q_ASSERT(!str.isEmpty());
QString s = std::move(str); // will copy if T is const QString
@@ -6640,10 +6640,10 @@ static QString detachAndConvertCase(T &str, QStringIterator it)
do {
uint uc = it.nextUnchecked();
- const QUnicodeTables::Properties *prop = qGetProp(uc);
- signed short caseDiff = Traits::caseDiff(prop);
+ const auto fold = qGetProp(uc)->cases[which];
+ signed short caseDiff = fold.diff;
- if (Q_UNLIKELY(Traits::caseSpecial(prop))) {
+ if (Q_UNLIKELY(fold.special)) {
const ushort *specialCase = specialCaseMap + caseDiff;
ushort length = *specialCase++;
@@ -6674,8 +6674,8 @@ static QString detachAndConvertCase(T &str, QStringIterator it)
return s;
}
-template <typename Traits, typename T>
-static QString convertCase(T &str)
+template <typename T>
+static QString convertCase(T &str, QUnicodeTables::Case which)
{
const QChar *p = str.constBegin();
const QChar *e = p + str.size();
@@ -6687,9 +6687,9 @@ static QString convertCase(T &str)
QStringIterator it(p, e);
while (it.hasNext()) {
uint uc = it.nextUnchecked();
- if (Traits::caseDiff(qGetProp(uc))) {
+ if (qGetProp(uc)->cases[which].diff) {
it.recedeUnchecked();
- return detachAndConvertCase<Traits>(str, it);
+ return detachAndConvertCase(str, it, which);
}
}
return std::move(str);
@@ -6698,12 +6698,12 @@ static QString convertCase(T &str)
QString QString::toLower_helper(const QString &str)
{
- return QUnicodeTables::convertCase<QUnicodeTables::LowercaseTraits>(str);
+ return QUnicodeTables::convertCase(str, QUnicodeTables::LowerCase);
}
QString QString::toLower_helper(QString &str)
{
- return QUnicodeTables::convertCase<QUnicodeTables::LowercaseTraits>(str);
+ return QUnicodeTables::convertCase(str, QUnicodeTables::LowerCase);
}
/*!
@@ -6715,12 +6715,12 @@ QString QString::toLower_helper(QString &str)
QString QString::toCaseFolded_helper(const QString &str)
{
- return QUnicodeTables::convertCase<QUnicodeTables::CasefoldTraits>(str);
+ return QUnicodeTables::convertCase(str, QUnicodeTables::CaseFold);
}
QString QString::toCaseFolded_helper(QString &str)
{
- return QUnicodeTables::convertCase<QUnicodeTables::CasefoldTraits>(str);
+ return QUnicodeTables::convertCase(str, QUnicodeTables::CaseFold);
}
/*!
@@ -6738,12 +6738,12 @@ QString QString::toCaseFolded_helper(QString &str)
QString QString::toUpper_helper(const QString &str)
{
- return QUnicodeTables::convertCase<QUnicodeTables::UppercaseTraits>(str);
+ return QUnicodeTables::convertCase(str, QUnicodeTables::UpperCase);
}
QString QString::toUpper_helper(QString &str)
{
- return QUnicodeTables::convertCase<QUnicodeTables::UppercaseTraits>(str);
+ return QUnicodeTables::convertCase(str, QUnicodeTables::UpperCase);
}
#if QT_DEPRECATED_SINCE(5, 14)
diff --git a/src/corelib/text/qunicodetables.cpp b/src/corelib/text/qunicodetables.cpp
index d57b39ff1f..805a5a6e34 100644
--- a/src/corelib/text/qunicodetables.cpp
+++ b/src/corelib/text/qunicodetables.cpp
@@ -6149,2658 +6149,2658 @@ static const unsigned short uc_property_trie[] = {
(uc_property_trie[uc_property_trie[ucs2>>5] + (ucs2 & 0x1f)])
static const Properties uc_properties[] = {
- { 9, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
- { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 5, 17, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 37, 2 },
- { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 5, 38, 2 },
- { 9, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 5, 38, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 36, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
- { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 35, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 13, 3, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 13, 3, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 2, 2 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 11, 8, 2 },
- { 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 16, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 10, 8, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 7, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 0, 8, 2 },
- { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 0, 0, 10, 7, 12, 3 },
- { 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
- { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 2, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 17, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 2 },
- { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 38, 2 },
- { 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 23, 10, 0, 0, -1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 17, 2 },
- { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
- { 26, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
- { 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 18, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 743, 0, 743, 0, 775, 1, 80, 0, 10, 6, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 0, 12, 2 },
- { 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 24, 10, 0, 0, -1, -16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 17, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 410, 1, 407, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 121, 0, 121, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 17, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 413, 0, 0, 0, 0, 0, 0, 1, 17, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -232, 0, -232, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 80, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 492, 1, 492, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -121, 0, 0, 0, 0, 0, -121, 1, 17, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -300, 0, -300, 0, -268, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 195, 0, 195, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 210, 0, 0, 0, 0, 0, 210, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 206, 0, 0, 0, 0, 0, 206, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 205, 0, 0, 0, 0, 0, 205, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 79, 0, 0, 0, 0, 0, 79, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 202, 0, 0, 0, 0, 0, 202, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 203, 0, 0, 0, 0, 0, 203, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 207, 0, 0, 0, 0, 0, 207, 1, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 97, 0, 97, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 211, 0, 0, 0, 0, 0, 211, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 209, 0, 0, 0, 0, 0, 209, 1, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 163, 0, 163, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 213, 0, 0, 0, 0, 0, 213, 1, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 130, 0, 130, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 214, 0, 0, 0, 0, 0, 214, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 218, 0, 0, 0, 0, 0, 218, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 217, 0, 0, 0, 0, 0, 217, 1, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 219, 0, 0, 0, 0, 0, 219, 1, 0, 0, 10, 7, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 56, 0, 56, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 2, 0, 0, 0, 1, 0, 2, 1, 80, 0, 10, 7, 12, 3 },
- { 16, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 1, 1, 80, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -2, 0, -1, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -79, 0, -79, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 503, 1, 503, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -97, 0, 0, 0, 0, 0, -97, 4, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -56, 0, 0, 0, 0, 0, -56, 4, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 4, 17, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 4, 17, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 4, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 4, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -130, 0, 0, 0, 0, 0, -130, 6, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 8, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 8, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 8, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -163, 0, 0, 0, 0, 0, -163, 8, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 1, 3, 8, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 5, 1, 5, 0, 0, 8, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 7, 1, 7, 0, 0, 8, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 9, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -195, 0, 0, 0, 0, 0, -195, 9, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 69, 0, 0, 0, 0, 0, 69, 9, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 71, 0, 0, 0, 0, 0, 71, 9, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 9, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 9, 1, 9, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 11, 1, 11, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 13, 1, 13, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -210, 0, -210, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -206, 0, -206, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -205, 0, -205, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -202, 0, -202, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -203, 0, -203, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 15, 1, 15, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 17, 1, 17, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -207, 0, -207, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 19, 1, 19, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 21, 1, 21, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -209, 0, -209, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -211, 0, -211, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 23, 1, 23, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 25, 1, 25, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 27, 1, 27, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 29, 1, 29, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -213, 0, -213, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -214, 0, -214, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 31, 1, 31, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -218, 0, -218, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 33, 1, 33, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -69, 0, -69, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -217, 0, -217, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -71, 0, -71, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -219, 0, -219, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 35, 1, 35, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 37, 1, 37, 0, 0, 1, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 6, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 0, 12, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 18, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 0, 18, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 36 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 0, 12, 2 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 216, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 4, 4, 4, 21, 1 },
- { 0, 17, 240, 5, -1, 0, 0, 0, 0, 84, 0, 84, 0, 116, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 234, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 234, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 10, 0, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 10, 0, 0, 10, 6, 12, 4 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 4 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 130, 0, 130, 0, 0, 9, 0, 0, 10, 6, 12, 4 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 15, 0, 8, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 116, 0, 0, 0, 0, 0, 116, 16, 0, 0, 10, 7, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 38, 0, 0, 0, 0, 0, 38, 1, 17, 0, 10, 7, 12, 4 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 14, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 37, 0, 0, 0, 0, 0, 37, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 64, 0, 0, 0, 0, 0, 64, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 63, 0, 0, 0, 0, 0, 63, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 495, 1, 495, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 0, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -38, 0, -38, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -37, 0, -37, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 499, 1, 499, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 0, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -31, 0, -31, 0, 1, 1, 0, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -64, 0, -64, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -63, 0, -63, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 8, 0, 0, 0, 0, 0, 8, 10, 0, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -62, 0, -62, 0, -30, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -57, 0, -57, 0, -25, 1, 80, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -47, 0, -47, 0, -15, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -54, 0, -54, 0, -22, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -8, 0, -8, 0, 0, 4, 0, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 6, 0, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 6, 0, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 4, 0, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 10, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 10, 6, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -86, 0, -86, 0, -54, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -80, 0, -80, 0, -48, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 7, 0, 0, 1, 80, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -116, 0, -116, 0, 0, 1, 0, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -60, 0, 0, 0, 0, 0, -60, 5, 80, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -96, 0, -96, 0, -64, 5, 80, 0, 10, 6, 12, 4 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 7, 0, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 7, 0, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -7, 0, 0, 0, 0, 0, -7, 7, 80, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -130, 0, 0, 0, 0, 0, -130, 8, 0, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 80, 0, 0, 0, 0, 0, 80, 4, 17, 0, 10, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 80, 0, 0, 0, 0, 0, 80, 1, 17, 0, 10, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 80, 0, 0, 0, 0, 0, 80, 1, 0, 0, 10, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 0, 0, 10, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 17, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 17, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -80, 0, -80, 0, 0, 4, 17, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -80, 0, -80, 0, 0, 1, 17, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -80, 0, -80, 0, 0, 1, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 17, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 1, 17, 0, 10, 6, 12, 5 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 5 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 5 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
- { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 6, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 6, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 4, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 4, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 15, 0, 0, 0, 0, 0, 15, 1, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -15, 0, -15, 0, 0, 9, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 4, 17, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 4, 17, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 8, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 8, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 9, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 9, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 10, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 10, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 11, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 11, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 12, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 12, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 16, 0, 0, 10, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 16, 0, 0, 10, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 0, 48, 0, 0, 0, 0, 0, 48, 1, 0, 0, 10, 7, 12, 6 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -48, 0, -48, 0, 0, 1, 0, 0, 10, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 459, 1, 456, 0, 0, 1, 80, 0, 10, 6, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 12, 8, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 6 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 6 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 9, 6 },
- { 13, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 222, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 10, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 11, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 12, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 13, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 14, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 15, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 16, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 17, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 18, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 19, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 19, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 20, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 21, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 22, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 20, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 7 },
- { 0, 17, 23, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 7 },
- { 0, 17, 24, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 25, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 7 },
- { 0, 17, 18, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 8, 13, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 0, 12, 7 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 4, 12, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 6, 4, 12, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 7, 6, 4, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
- { 26, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 8 },
- { 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 15, 11, 8, 8 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 30, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 31, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 32, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 2 },
- { 10, 13, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 6, 4, 21, 8 },
- { 13, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 2 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 8 },
- { 17, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 2 },
- { 0, 17, 27, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 28, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 29, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 30, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 31, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 32, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 33, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 34, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 8 },
- { 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 8 },
- { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 9, 11, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 8 },
- { 0, 17, 35, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 4, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
- { 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 8 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 8 },
- { 29, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 9 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 9 },
- { 10, 13, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 6, 4, 12, 9 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 9 },
- { 0, 17, 36, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 9 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 9 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 10 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 10 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 10 },
- { 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 3, 1, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 66 },
- { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 66 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
- { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 66 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 15, 11, 8, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 6, 66 },
- { 17, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 66 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 82 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 82 },
- { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 82 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 82 },
- { 18, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 95 },
- { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 95 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 95 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 95 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 95 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 9 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 9 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 8 },
- { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 7, 6, 4, 12, 2 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 27, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 28, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 29, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 10, 8, 12, 11 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 11 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 8, 4, 4, 21, 11 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 11 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 21, 11 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 8, 12, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 17, 2 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 11 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 12 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 12 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 12 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 12 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 8, 4, 4, 21, 12 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 8, 12, 12 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 12 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 12 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 12 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 12 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 12 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 9, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 12 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 12, 12 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 13 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 8, 4, 4, 21, 13 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 13 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 8, 12, 13 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 13 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 13 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 13 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 14 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 14 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 14 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 14 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 9, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 14 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 14 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 15 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 15 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 8, 4, 4, 21, 15 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 8, 12, 15 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 15 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 15 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 15 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 10, 8, 12, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 16 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 16 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 16 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 8, 4, 4, 21, 16 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 16 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 16 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 16 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 16 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 9, 16 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 17 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 17 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 4, 4, 21, 17 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
- { 0, 17, 84, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
- { 0, 17, 91, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 17 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 17 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 17 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 17 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 18 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 18 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 18 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 18 },
- { 0, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 8, 4, 4, 21, 18 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 18 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 18 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 18 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 19 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 4, 4, 21, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 19 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 19 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 19 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 8, 4, 4, 21, 19 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 10, 8, 12, 19 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 19 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 19 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 19 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 19 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 19 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 8, 4, 4, 21, 20 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 20 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 20 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 8, 4, 4, 21, 20 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 20 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 20 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 33, 21 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 21 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 8, 0, 8, 33, 21 },
- { 0, 17, 103, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 21 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 21 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 33, 21 },
- { 0, 17, 107, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 21 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 21 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 21 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 21 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 33, 22 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 8, 0, 8, 33, 22 },
- { 0, 17, 118, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 22 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 33, 22 },
- { 0, 17, 122, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 33, 22 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 9, 11, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 8, 33, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 8, 33, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 10, 8, 12, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 0, 0, 0, 4, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 16, 9, 11, 23 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 23 },
- { 0, 17, 216, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 13, 0, 23 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 13, 1, 23 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 8, 4, 4, 21, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 0, 10, 8, 12, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 23 },
- { 0, 17, 129, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 130, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 4, 4, 4, 21, 23 },
- { 0, 17, 132, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 8, 4, 4, 17, 23 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 23 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 23 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 4, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 33, 24 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 33, 24 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 0, 0, 8, 33, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 4, 4, 33, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 4, 33, 24 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 33, 24 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 33, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 8, 4, 4, 33, 24 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 33, 24 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 33, 24 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 33, 24 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 33, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 33, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 24 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 17, 24 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 24 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 33, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 4, 4, 33, 24 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 33, 24 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 33, 24 },
- { 14, 0, 0, 0, -1, 0, 0, 7264, 0, 0, 0, 0, 0, 7264, 1, 0, 0, 10, 7, 12, 25 },
- { 14, 0, 0, 0, -1, 0, 0, 7264, 0, 0, 0, 0, 0, 7264, 13, 0, 0, 10, 7, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 25 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 10, 8, 25, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 9, 10, 8, 25, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 10, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 10, 10, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 10, 10, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 11, 10, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 10, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 10, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 27 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 27 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 27 },
- { 14, 0, 0, 0, -1, 0, 1, 39, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 41, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 43, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 45, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 47, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 49, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 51, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 53, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 55, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 57, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 59, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 61, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 63, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 65, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 67, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 69, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 71, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 73, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 75, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 77, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 79, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 81, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 83, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 85, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 87, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 89, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 91, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 93, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 95, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 97, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 99, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 101, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 103, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 105, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 107, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 109, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 111, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 113, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 115, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 117, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 119, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 121, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 123, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 125, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 127, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 129, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 131, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 133, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 135, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 137, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 139, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 141, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 143, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 145, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 147, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 149, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 151, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 153, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 155, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 157, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 159, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 161, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 163, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 165, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 167, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 169, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 171, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 173, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 175, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 177, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 179, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 181, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 183, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 185, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 187, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 189, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 191, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 193, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 195, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 1, 197, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 7, 12, 28 },
- { 14, 0, 0, 0, -1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 7, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -8, 0, -8, 0, -8, 17, 0, 0, 10, 6, 12, 28 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 29 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 29 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 29 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 29 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 29 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 17, 30 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 30 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 30 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 1, 30 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 31 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 31 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 31 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 42 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 43 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 17, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 44 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 44 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 45 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 45 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 33, 32 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 33, 32 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 8, 4, 4, 33, 32 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 33, 32 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 32 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 32 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 33, 32 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 32 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 9, 32 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 33, 32 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 32 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 32 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 33 },
- { 25, 10, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 6, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 33 },
- { 25, 10, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 6, 4, 4, 33 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 16, 9, 11, 33 },
- { 18, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 33 },
- { 17, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 12, 33 },
- { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
- { 18, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 47 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 47 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 8, 4, 4, 21, 47 },
- { 0, 17, 222, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 47 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 6, 47 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 47 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 8, 33, 48 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 33, 56 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 56 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 16, 9, 11, 56 },
- { 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 33, 56 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 33, 56 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 32 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 55 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 8, 4, 4, 21, 55 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 55 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 78 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 33, 78 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 33, 78 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 33, 78 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 4, 4, 33, 78 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 33, 78 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 78 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 78 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 33, 78 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 78 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 33, 78 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 8, 4, 4, 21, 62 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 62 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 0, 10, 8, 12, 62 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 204, 8, 4, 4, 21, 62 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 8, 4, 4, 21, 62 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 8, 4, 4, 21, 62 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 16, 9, 11, 62 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 17, 62 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 62 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 62 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 62 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 67 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 67 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 67 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 67 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 67 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 93 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 8, 4, 4, 21, 93 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 8, 4, 4, 21, 93 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 93 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 68 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 68 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 68 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 69 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 69 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 69 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 69 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6254, 0, -6254, 0, -6222, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6253, 0, -6253, 0, -6221, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6244, 0, -6244, 0, -6212, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6242, 0, -6242, 0, -6210, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6243, 0, -6243, 0, -6211, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6236, 0, -6236, 0, -6204, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -6181, 0, -6181, 0, -6180, 18, 0, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 199, 1, 199, 1, 711, 18, 0, 0, 10, 6, 12, 5 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 67 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 21, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 2 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 2 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 1 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 2 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 8, 4, 4, 21, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 6, 12, 5 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 10, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 10, 6, 12, 4 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 201, 1, 201, 0, 0, 8, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 3814, 0, 3814, 0, 0, 8, 0, 0, 10, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 6, 12, 4 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 234, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 214, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 1 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 506, 1, 506, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 509, 1, 509, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 512, 1, 512, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 515, 1, 515, 0, 0, 1, 17, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 518, 1, 518, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -59, 0, -59, 0, -58, 2, 81, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -7615, 0, 0, 0, 0, 0, -7615, 10, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 10, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 10, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 8, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -8, 0, 0, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 521, 1, 521, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 524, 1, 524, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 528, 1, 528, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 532, 1, 532, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 74, 0, 74, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 74, 0, 74, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 86, 0, 86, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 86, 0, 86, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 100, 0, 100, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 100, 0, 100, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 128, 0, 128, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 128, 0, 128, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 112, 0, 112, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 112, 0, 112, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 126, 0, 126, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 126, 0, 126, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 570, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 573, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 576, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 579, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 582, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 585, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 588, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 591, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 570, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 573, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 576, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 579, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 582, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 585, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 588, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 591, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 594, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 597, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 600, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 603, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 606, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 609, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 612, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 615, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 594, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 597, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 600, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 603, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 606, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 609, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 612, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 615, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 618, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 621, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 624, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 627, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 630, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 633, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 636, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 639, 0, 8, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 618, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 621, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 624, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 627, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 630, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 633, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 636, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -8, 1, 639, 0, 0, 0, -8, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 654, 1, 651, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 642, 0, 9, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 660, 1, 657, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 536, 1, 536, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 691, 1, 687, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -74, 0, 0, 0, 0, 0, -74, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -74, 0, 0, 0, 0, 0, -74, 1, 85, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -9, 1, 642, 0, 0, 0, -9, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -7205, 0, -7205, 0, -7173, 1, 85, 0, 10, 6, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 666, 1, 663, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 645, 0, 9, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 672, 1, 669, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 539, 1, 539, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 699, 1, 695, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -86, 0, 0, 0, 0, 0, -86, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -86, 0, 0, 0, 0, 0, -86, 1, 85, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -9, 1, 645, 0, 0, 0, -9, 1, 17, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 542, 1, 542, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 495, 1, 495, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 546, 1, 546, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 549, 1, 549, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -100, 0, 0, 0, 0, 0, -100, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -100, 0, 0, 0, 0, 0, -100, 1, 85, 0, 10, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 553, 1, 553, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 499, 1, 499, 0, 0, 1, 85, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 557, 1, 557, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 7, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 560, 1, 560, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 563, 1, 563, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -112, 0, 0, 0, 0, 0, -112, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -112, 0, 0, 0, 0, 0, -112, 1, 85, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -7, 0, 0, 0, 0, 0, -7, 1, 17, 0, 10, 7, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 678, 1, 675, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 648, 0, 9, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 684, 1, 681, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 567, 1, 567, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 707, 1, 703, 0, 0, 1, 17, 0, 10, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -128, 0, 0, 0, 0, 0, -128, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -128, 0, 0, 0, 0, 0, -128, 1, 85, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -126, 0, 0, 0, 0, 0, -126, 1, 17, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, -126, 0, 0, 0, 0, 0, -126, 1, 85, 0, 10, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, 0, -9, 1, 648, 0, 0, 0, -9, 1, 17, 0, 10, 7, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0, 18, 4 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 5, 17, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 17, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 4, 20, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 10, 18, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 5, 4, 32, 1 },
- { 10, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 10, 1, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 4, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 19, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 13, 3, 2 },
- { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 13, 3, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
- { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 13, 10, 15, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 15, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 0, 17, 2 },
- { 7, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 38, 2 },
- { 8, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 38, 2 },
- { 10, 11, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 10, 14, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 10, 16, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 10, 12, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 10, 15, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 17, 5, 4, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
- { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 5, 2 },
- { 26, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 0, 8, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 12, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 12, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 17, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 12, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 5, 17, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 6, 4, 22, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 6, 4, 12, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 3, 6, 4, 12, 2 },
- { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 },
- { 10, 19, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 6, 4, 21, 2 },
- { 10, 20, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 6, 4, 21, 2 },
- { 10, 21, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 6, 4, 21, 2 },
- { 10, 22, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 6, 4, 21, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 21, 2 },
- { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 10, 6, 12, 3 },
- { 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 10, 6, 12, 3 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 10, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 10, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 10, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 9, 2 },
- { 13, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0 },
- { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 7, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 6, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 9, 2 },
- { 14, 0, 0, 0, -1, 0, 0, -7517, 0, 0, 0, 0, 0, -7517, 1, 85, 0, 10, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 203, 0, 0, 0, 0, 1, 203, 1, 85, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 205, 0, 0, 0, 0, 1, 205, 1, 85, 0, 10, 7, 12, 3 },
- { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 28, 0, 0, 0, 0, 0, 28, 1, 0, 0, 10, 7, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 8, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 10, 6, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 6, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 10, 6, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 10, 7, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -28, 0, -28, 0, 0, 9, 0, 0, 10, 6, 12, 3 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 16, 0, 0, 0, 0, 0, 16, 1, 80, 0, 10, 7, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, -16, 0, -16, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 3 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2016, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 138, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1824, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2104, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2108, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2106, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -138, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 15, 2 },
- { 26, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 13, 1, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 26, 0, 0, 0, 0, 0, 26, 1, 80, 0, 10, 7, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, -26, 0, -26, 0, 0, 1, 80, 0, 10, 6, 12, 2 },
- { 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 14, 18, 0, 30, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 16, 20, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 16, 20, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 14, 18, 0, 30, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 16, 20, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 14, 18, 0, 30, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 13, 3, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 1, 2 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 1, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 1, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 54 },
- { 21, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 1, 2 },
- { 21, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 1, 2 },
- { 26, 10, 0, 0, -1, -1824, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2016, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 85, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2104, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2106, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2108, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 48, 0, 0, 0, 0, 0, 48, 8, 0, 0, 10, 7, 12, 57 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -48, 0, -48, 0, 0, 8, 0, 0, 10, 6, 12, 57 },
- { 14, 0, 0, 0, -1, 0, 1, 207, 0, 0, 0, 0, 1, 207, 9, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, -3814, 0, 0, 0, 0, 0, -3814, 9, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 209, 0, 0, 0, 0, 1, 209, 9, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 211, 1, 211, 0, 0, 9, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 213, 1, 213, 0, 0, 9, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 215, 0, 0, 0, 0, 1, 215, 10, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 217, 0, 0, 0, 0, 1, 217, 10, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 219, 0, 0, 0, 0, 1, 219, 10, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 221, 0, 0, 0, 0, 1, 221, 11, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 80, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 223, 0, 0, 0, 0, 1, 223, 11, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 225, 0, 0, 0, 0, 1, 225, 11, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 8, 0, 0, 10, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 8, 0, 0, 10, 6, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 6, 12, 46 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 46 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 11, 0, 0, 10, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 11, 0, 0, 10, 6, 12, 46 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 46 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 13, 0, 0, 10, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 13, 0, 0, 10, 6, 12, 46 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 46 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 46 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -7264, 0, -7264, 0, 0, 8, 0, 0, 10, 6, 12, 25 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -7264, 0, -7264, 0, 0, 13, 0, 0, 10, 6, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 58 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 58 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 8, 12, 58 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 17, 58 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 58 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
- { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
- { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 6, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 19, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 17, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 13, 0, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 17, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 37 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 0, 14, 37 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 5, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 37 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
- { 0, 17, 218, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 222, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 1, 0, 224, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 26 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 14, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 21, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 8, 14, 37 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 5, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 14, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 5, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 8, 14, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 8, 5, 34 },
- { 0, 17, 8, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 0, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 5, 34 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 8, 5, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 8, 14, 34 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 0, 5, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 5, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 8, 8, 14, 35 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 5, 35 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 8, 8, 5, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 8, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 8, 14, 26 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 5, 35 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 26 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 14, 26 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 14, 2 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 14, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 14, 26 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 0, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 14, 37 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 14, 38 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 10, 8, 5, 38 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 38 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 14, 38 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 83 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 83 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 83 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 83 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 70 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 70 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 70 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 6, 70 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 70 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 70 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 5 },
- { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 5 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 5 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 5 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 80, 0, 10, 6, 12, 5 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 5 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 84 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 84 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 84 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 84 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 84 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 84 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 1, 227, 0, 0, 0, 0, 1, 227, 10, 0, 0, 10, 7, 12, 3 },
- { 28, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 1, 229, 0, 0, 0, 0, 1, 229, 12, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 6, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 12, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 12, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 13, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 13, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 16, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 16, 0, 0, 10, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 231, 0, 0, 0, 0, 1, 231, 13, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 233, 0, 0, 0, 0, 1, 233, 16, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 235, 0, 0, 0, 0, 1, 235, 16, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 237, 0, 0, 0, 0, 1, 237, 16, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 239, 0, 0, 0, 0, 1, 239, 18, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 241, 0, 0, 0, 0, 1, 241, 16, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 243, 0, 0, 0, 0, 1, 243, 16, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 245, 0, 0, 0, 0, 1, 245, 17, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 928, 0, 0, 0, 0, 0, 928, 17, 0, 0, 10, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 17, 0, 0, 10, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 17, 0, 0, 10, 6, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 10, 6, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 59 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 8, 4, 4, 21, 59 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 59 },
- { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 65 },
- { 18, 0, 0, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 65 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 65 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 18, 65 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 6, 65 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 71 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 71 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 71 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 71 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 71 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 71 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 18, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 11 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 72 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 72 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 2 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 72 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 73 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 73 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 73 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 73 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 73 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 21, 85 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 85 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 21, 85 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 85 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 85 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 85 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 2 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 85 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 8, 33, 24 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 33, 24 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 8, 33, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 24 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 77 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 77 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 8, 4, 4, 21, 77 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 16, 9, 11, 77 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 77 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 77 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 24 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 24 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 33, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 4, 4, 33, 24 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 79 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 33, 79 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 33, 79 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 33, 79 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 33, 79 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 86 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 86 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 86 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 86 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 27 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -928, 0, -928, 0, 0, 16, 0, 0, 10, 6, 12, 3 },
- { 28, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 247, 1, 247, 1, 247, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 249, 1, 249, 1, 249, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 251, 1, 251, 1, 251, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 253, 1, 253, 1, 253, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 255, 1, 255, 1, 255, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 257, 1, 257, 1, 257, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 259, 1, 259, 1, 259, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 261, 1, 261, 1, 261, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 263, 1, 263, 1, 263, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 265, 1, 265, 1, 265, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 267, 1, 267, 1, 267, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 269, 1, 269, 1, 269, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 271, 1, 271, 1, 271, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 273, 1, 273, 1, 273, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 275, 1, 275, 1, 275, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 277, 1, 277, 1, 277, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 279, 1, 279, 1, 279, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 281, 1, 281, 1, 281, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 283, 1, 283, 1, 283, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 285, 1, 285, 1, 285, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 287, 1, 287, 1, 287, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 289, 1, 289, 1, 289, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 291, 1, 291, 1, 291, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 293, 1, 293, 1, 293, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 295, 1, 295, 1, 295, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 297, 1, 297, 1, 297, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 299, 1, 299, 1, 299, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 301, 1, 301, 1, 301, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 303, 1, 303, 1, 303, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 305, 1, 305, 1, 305, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 307, 1, 307, 1, 307, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 309, 1, 309, 1, 309, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 311, 1, 311, 1, 311, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 313, 1, 313, 1, 313, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 315, 1, 315, 1, 315, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 317, 1, 317, 1, 317, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 319, 1, 319, 1, 319, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 321, 1, 321, 1, 321, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 323, 1, 323, 1, 323, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 325, 1, 325, 1, 325, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 327, 1, 327, 1, 327, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 329, 1, 329, 1, 329, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 331, 1, 331, 1, 331, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 333, 1, 333, 1, 333, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 335, 1, 335, 1, 335, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 337, 1, 337, 1, 337, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 339, 1, 339, 1, 339, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 341, 1, 341, 1, 341, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 343, 1, 343, 1, 343, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 345, 1, 345, 1, 345, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 347, 1, 347, 1, 347, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 349, 1, 349, 1, 349, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 351, 1, 351, 1, 351, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 353, 1, 353, 1, 353, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 355, 1, 355, 1, 355, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 357, 1, 357, 1, 357, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 359, 1, 359, 1, 359, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 361, 1, 361, 1, 361, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 363, 1, 363, 1, 363, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 365, 1, 365, 1, 365, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 367, 1, 367, 1, 367, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 369, 1, 369, 1, 369, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 371, 1, 371, 1, 371, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 373, 1, 373, 1, 373, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 375, 1, 375, 1, 375, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 377, 1, 377, 1, 377, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 379, 1, 379, 1, 379, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 381, 1, 381, 1, 381, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 383, 1, 383, 1, 383, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 385, 1, 385, 1, 385, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 387, 1, 387, 1, 387, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 389, 1, 389, 1, 389, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 391, 1, 391, 1, 391, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 393, 1, 393, 1, 393, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 395, 1, 395, 1, 395, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 397, 1, 397, 1, 397, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 399, 1, 399, 1, 399, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 401, 1, 401, 1, 401, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 403, 1, 403, 1, 403, 17, 0, 0, 10, 6, 12, 28 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 405, 1, 405, 1, 405, 17, 0, 0, 10, 6, 12, 28 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 86 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 21, 86 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 86 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 16, 9, 11, 86 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 12, 10, 8, 23, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 13, 10, 8, 24, 26 },
- { 11, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 34, 0 },
- { 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 85, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 85, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 85, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 85, 0, 0, 8, 14, 37 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 419, 1, 416, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 425, 1, 422, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 431, 1, 428, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 438, 1, 434, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 446, 1, 442, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 453, 1, 450, 0, 0, 1, 80, 0, 10, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 465, 1, 462, 0, 0, 1, 80, 0, 10, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 471, 1, 468, 0, 0, 1, 80, 0, 10, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 477, 1, 474, 0, 0, 1, 80, 0, 10, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 483, 1, 480, 0, 0, 1, 80, 0, 10, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 1, 489, 1, 486, 0, 0, 1, 80, 0, 10, 6, 12, 6 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 85, 0, 9, 8, 13, 7 },
- { 0, 17, 26, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 9, 8, 13, 7 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 9, 8, 13, 7 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 7 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 8, 12, 8 },
- { 28, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 8 },
- { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 0 },
- { 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 10, 8 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 15, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 14, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 15, 0, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 6, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 15, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 17, 0, 14, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 13, 1, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 15, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 13, 10, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 15, 0, 5, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 14, 11, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 6, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 8, 12, 8 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 6, 4, 22, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 13, 0, 14, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 1, 80, 0, 10, 7, 14, 3 },
- { 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 1, 80, 0, 10, 6, 14, 3 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 5, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 5, 35 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 4, 4, 4, 5, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
- { 10, 10, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 6, 4, 21, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 29, 2 },
- { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 49 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 2 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 4, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 4 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 4 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 4 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 4 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 4 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 4 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 74 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 75 },
- { 5, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 10, 8, 12, 39 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 39 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 39 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 39 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 10, 8, 12, 40 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 10, 8, 12, 40 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 120 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 120 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 50 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 50 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 60 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 60 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 60 },
- { 14, 0, 0, 0, -1, 0, 0, 40, 0, 0, 0, 0, 0, 40, 5, 0, 0, 10, 7, 12, 41 },
- { 14, 0, 0, 0, -1, 0, 0, 40, 0, 0, 0, 0, 0, 40, 7, 0, 0, 10, 7, 12, 41 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -40, 0, -40, 0, 0, 5, 0, 0, 10, 6, 12, 41 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -40, 0, -40, 0, 0, 7, 0, 0, 10, 6, 12, 41 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 51 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 52 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 16, 9, 11, 52 },
- { 14, 0, 0, 0, -1, 0, 0, 40, 0, 0, 0, 0, 0, 40, 18, 0, 0, 10, 7, 12, 136 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -40, 0, -40, 0, 0, 18, 0, 0, 10, 6, 12, 136 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 106 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 103 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 103 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 110 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 8, 12, 53 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 87 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 87 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 87 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 118 },
- { 29, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 118 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 118 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 117 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 117 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 128 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 128 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 64 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 64 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 64 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 64 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 8, 12, 76 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 76 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 98 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 97 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 97 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 10, 8, 12, 61 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 5, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 61 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 17, 61 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 88 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 88 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 88 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 116 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 116 },
- { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 112 },
- { 18, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 112 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 112 },
- { 29, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 112 },
- { 18, 1, 0, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 112 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 112 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 112 },
- { 5, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 112 },
- { 5, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 112 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 17, 112 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 15, 112 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 80 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 80 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 89 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 89 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 90 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 90 },
- { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 121 },
- { 18, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 121 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 121 },
- { 5, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 121 },
- { 5, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 121 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 121 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 91 },
- { 14, 1, 0, 0, -1, 0, 0, 64, 0, 0, 0, 0, 0, 64, 17, 0, 0, 10, 7, 12, 130 },
- { 15, 1, 0, 0, -1, 0, 0, 0, 0, -64, 0, -64, 0, 0, 17, 0, 0, 10, 6, 12, 130 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 130 },
- { 5, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 8, 4, 4, 21, 94 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 94 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 17, 94 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 16, 9, 11, 94 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 94 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 4, 4, 21, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 17, 0, 10, 8, 12, 92 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 204, 4, 4, 4, 21, 92 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 92 },
- { 10, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 6, 4, 12, 92 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 101 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 101 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 96 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 204, 4, 4, 4, 21, 96 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 96 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 17, 4, 4, 4, 21, 96 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 96 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 96 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 96 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 111 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 111 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 111 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 18, 111 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 100 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 100 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 10, 8, 12, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 100 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 100 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 12, 100 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 18, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 17, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12, 17, 100 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 20 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 109 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 109 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 109 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 109 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 109 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 109 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 109 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 109 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 129 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12, 17, 129 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 123 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 123 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 123 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 123 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 123 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 123 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 107 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 107 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 107 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 107 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 107 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 204, 4, 4, 4, 21, 107 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 8, 4, 4, 21, 107 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 107 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 107 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 107 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 135 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 8, 4, 4, 21, 135 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 135 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 135 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 135 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 12, 17, 135 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 17, 135 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 135 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 135 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 124 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 204, 4, 4, 4, 21, 124 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 124 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 124 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 204, 4, 4, 4, 21, 124 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 8, 4, 4, 21, 124 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 124 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 124 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 124 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 124 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 122 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 204, 4, 4, 4, 21, 122 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 122 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 122 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 8, 4, 4, 21, 122 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 122 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 122 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 18, 122 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 122 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 6, 122 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 122 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12, 17, 122 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 122 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 122 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 114 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 8, 4, 4, 21, 114 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 114 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 114 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 114 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 114 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 114 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 18, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 102 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 102 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 102 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 16, 9, 11, 102 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 8, 33, 126 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 33, 126 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 8, 4, 4, 33, 126 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 33, 126 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 16, 9, 11, 126 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 33, 126 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12, 17, 126 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 33, 126 },
- { 14, 0, 0, 0, -1, 0, 0, 32, 0, 0, 0, 0, 0, 32, 16, 0, 0, 10, 7, 12, 125 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, -32, 0, -32, 0, 0, 16, 0, 0, 10, 6, 12, 125 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 125 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 125 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 125 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 141 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 141 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 8, 4, 4, 21, 141 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 141 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 7, 10, 8, 12, 141 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 18, 141 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 12, 141 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 17, 141 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 12, 17, 141 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 140 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 140 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 8, 4, 4, 21, 140 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 7, 10, 8, 12, 140 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 140 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 17, 140 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 12, 17, 140 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 18, 140 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 119 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 133 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 8, 4, 4, 21, 133 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 133 },
- { 0, 0, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 133 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 12, 17, 133 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 17, 133 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 133 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 133 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 18, 134 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 6, 134 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 12, 134 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 134 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 8, 4, 4, 21, 134 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 12, 138 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 138 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 138 },
- { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 4, 4, 21, 138 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 7, 10, 8, 12, 138 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 16, 9, 11, 138 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 63 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 63 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 63 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 8, 12, 63 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 63 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 63 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 17, 63 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 12, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 0, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 8, 1, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 12, 127 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 0, 127 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 10, 8, 1, 127 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 8, 12, 84 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 115 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 115 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 115 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 104 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 104 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 104 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 108 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 108 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 108 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 17, 108 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 108 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 108 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 108 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 9, 11, 108 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 108 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 99 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 8, 4, 4, 21, 99 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 99 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 10, 8, 12, 99 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, 8, 5, 137 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 10, 8, 5, 139 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 8, 14, 137 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 14, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 8, 14, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 8, 14, 139 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 105 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 105 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 105 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 105 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 17, 105 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 3, 6, 4, 21, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 85, 0, 0, 0, 12, 2 },
- { 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 2 },
- { 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 8, 4, 4, 21, 2 },
- { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
- { 1, 0, 226, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 8, 4, 4, 21, 2 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 3, 6, 4, 21, 2 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 2 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 4 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 10, 7, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 10, 6, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 10, 6, 12, 2 },
- { 26, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 10, 7, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 10, 6, 12, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 16, 9, 11, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 131 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 4, 4, 4, 21, 131 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 17, 131 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12, 17, 131 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 12, 131 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 57 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 10, 8, 12, 113 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 113 },
- { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 4, 4, 21, 113 },
- { 14, 1, 0, 2, -1, 0, 0, 34, 0, 0, 0, 0, 0, 34, 18, 0, 0, 10, 7, 12, 132 },
- { 15, 1, 0, 2, -1, 0, 0, 0, 0, -34, 0, -34, 0, 0, 18, 0, 0, 10, 6, 12, 132 },
- { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 132 },
- { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 4, 4, 4, 21, 132 },
- { 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 3, 1, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 16, 9, 11, 132 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 132 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 10, 8, 12, 8 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 8 },
- { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 10, 7, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 10, 7, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 10, 7, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 10, 7, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 6, 7, 0, 28, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 14, 34 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 0, 0, 14, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 80, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 16, 20, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 14, 18, 0, 30, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 15, 19, 0, 31, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 17, 21, 0, 30, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 14, 18, 0, 30, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 20, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 13, 3, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 5, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 14, 18, 0, 30, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 14, 18, 0, 30, 2 },
- { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 85, 0, 0, 8, 14, 37 },
- { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 2 },
- { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
- { 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 }
+ { 9, 18, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 21, 0, 2 },
+ { 9, 8, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 17, 5, 2 },
+ { 9, 7, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 2, 2, 37, 2, 2 },
+ { 9, 8, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 3, 38, 5, 2 },
+ { 9, 9, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 3, 38, 5, 2 },
+ { 9, 7, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 1, 1, 36, 1, 2 },
+ { 9, 7, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 21, 0, 2 },
+ { 9, 8, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 21, 0, 2 },
+ { 6, 9, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 35, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 12, 3, 13, 2 },
+ { 25, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 25, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 11, 3, 13, 2 },
+ { 21, 10, 0, 0, -1, 1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 2, 13, 2 },
+ { 26, 3, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 11, 2 },
+ { 20, 3, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 16, 11, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 10, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 7, 0, 2 },
+ { 3, 2, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 8, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 0, 2 },
+ { 26, 10, 0, 0, -1, 2, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -2, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 3 },
+ { 21, 10, 0, 0, -1, 2, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 22, 10, 0, 0, -1, -2, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 2, 13, 2 },
+ { 28, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 19, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 17, 12, 0, 2 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 26, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 22, 10, 0, 0, -1, -2, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 9, 7, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 3, 38, 3, 2 },
+ { 6, 6, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 4, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 28, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 23, 10, 0, 0, -1, 16, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 10, 18, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 17, 4, 2 },
+ { 29, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 26, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 5, 2, 0, 0, 2, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 3, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 28, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 2 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 743}, {0, 743}, {0, 775} }, 0, 10, 12, 6, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 14, 12, 0, 2 },
+ { 5, 2, 0, 0, 1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 24, 10, 0, 0, -1, -16, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 5, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 410}, {1, 407}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 121}, {0, 121}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {1, 413}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -232}, {0, -232}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 80, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 492}, {1, 492}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -121}, {0, 0}, {0, 0}, {0, -121} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -300}, {0, -300}, {0, -268} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 195}, {0, 195}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 210}, {0, 0}, {0, 0}, {0, 210} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 206}, {0, 0}, {0, 0}, {0, 206} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 205}, {0, 0}, {0, 0}, {0, 205} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 79}, {0, 0}, {0, 0}, {0, 79} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 202}, {0, 0}, {0, 0}, {0, 202} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 203}, {0, 0}, {0, 0}, {0, 203} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 207}, {0, 0}, {0, 0}, {0, 207} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 97}, {0, 97}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 211}, {0, 0}, {0, 0}, {0, 211} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 209}, {0, 0}, {0, 0}, {0, 209} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 163}, {0, 163}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 213}, {0, 0}, {0, 0}, {0, 213} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 130}, {0, 130}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 214}, {0, 0}, {0, 0}, {0, 214} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 218}, {0, 0}, {0, 0}, {0, 218} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 217}, {0, 0}, {0, 0}, {0, 217} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 219}, {0, 0}, {0, 0}, {0, 219} }, 0, 10, 12, 7, 3 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 56}, {0, 56}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 80, { {0, 2}, {0, 0}, {0, 1}, {0, 2} }, 0, 10, 12, 7, 3 },
+ { 16, 0, 0, 0, -1, 0, 1, 80, { {0, 1}, {0, -1}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -2}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -79}, {0, -79}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 503}, {1, 503}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {0, -97}, {0, 0}, {0, 0}, {0, -97} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {0, -56}, {0, 0}, {0, 0}, {0, -56} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 4, 17, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 4, 17, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 6, 0, { {0, -130}, {0, 0}, {0, 0}, {0, -130} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {1, 1}, {0, 0}, {0, 0}, {1, 1} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {0, -163}, {0, 0}, {0, 0}, {0, -163} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {1, 3}, {0, 0}, {0, 0}, {1, 3} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {1, 5}, {1, 5}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {1, 7}, {1, 7}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {0, -195}, {0, 0}, {0, 0}, {0, -195} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {0, 69}, {0, 0}, {0, 0}, {0, 69} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {0, 71}, {0, 0}, {0, 0}, {0, 71} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 9}, {1, 9}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 11}, {1, 11}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 13}, {1, 13}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -210}, {0, -210}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -206}, {0, -206}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -205}, {0, -205}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -202}, {0, -202}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -203}, {0, -203}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 15}, {1, 15}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 17}, {1, 17}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -207}, {0, -207}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 19}, {1, 19}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 21}, {1, 21}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -209}, {0, -209}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -211}, {0, -211}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 23}, {1, 23}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 25}, {1, 25}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 27}, {1, 27}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 29}, {1, 29}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -213}, {0, -213}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -214}, {0, -214}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 31}, {1, 31}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -218}, {0, -218}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 33}, {1, 33}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -69}, {0, -69}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -217}, {0, -217}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -71}, {0, -71}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -219}, {0, -219}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 35}, {1, 35}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {1, 37}, {1, 37}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 28, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 0, 2 },
+ { 17, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 18, 8, 2 },
+ { 28, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 18, 0, 2 },
+ { 28, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 36 },
+ { 17, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 28, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 28, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 0, 2 },
+ { 0, 17, 230, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 232, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 216, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 202, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 202, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 1, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 1, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 240, 5, -1, 0, 1, 204, { {0, 0}, {0, 84}, {0, 84}, {0, 116} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 4, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 232, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 233, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 4, 4, 1 },
+ { 0, 17, 234, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 4, 4, 1 },
+ { 0, 17, 233, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 4, 4, 1 },
+ { 0, 17, 234, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 4, 4, 1 },
+ { 0, 17, 233, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 4, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 17, 10, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 28, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 17, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 130}, {0, 130}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 25, 10, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {0, 116}, {0, 0}, {0, 0}, {0, 116} }, 0, 10, 12, 7, 4 },
+ { 28, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 28, 10, 0, 0, -1, 0, 1, 81, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 38}, {0, 0}, {0, 0}, {0, 38} }, 0, 10, 12, 7, 4 },
+ { 25, 10, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 14, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 37}, {0, 0}, {0, 0}, {0, 37} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 64}, {0, 0}, {0, 0}, {0, 64} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 63}, {0, 0}, {0, 0}, {0, 63} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 495}, {1, 495}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -38}, {0, -38}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -37}, {0, -37}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 499}, {1, 499}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -31}, {0, -31}, {0, 1} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -64}, {0, -64}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -63}, {0, -63}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {0, 8}, {0, 0}, {0, 0}, {0, 8} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -62}, {0, -62}, {0, -30} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -57}, {0, -57}, {0, -25} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 81, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -47}, {0, -47}, {0, -15} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -54}, {0, -54}, {0, -22} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, -8}, {0, -8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 6, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 46 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 46 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -86}, {0, -86}, {0, -54} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -80}, {0, -80}, {0, -48} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 7}, {0, 7}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -116}, {0, -116}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 5, 80, { {0, -60}, {0, 0}, {0, 0}, {0, -60} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 5, 80, { {0, 0}, {0, -96}, {0, -96}, {0, -64} }, 0, 10, 12, 6, 4 },
+ { 26, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 14, 0, 0, 0, -1, 0, 7, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 7, 80, { {0, -7}, {0, 0}, {0, 0}, {0, -7} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {0, -130}, {0, 0}, {0, 0}, {0, -130} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 4, 17, { {0, 80}, {0, 0}, {0, 0}, {0, 80} }, 0, 10, 12, 7, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 80}, {0, 0}, {0, 0}, {0, 80} }, 0, 10, 12, 7, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 80}, {0, 0}, {0, 0}, {0, 80} }, 0, 10, 12, 7, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 4, 17, { {0, 0}, {0, -80}, {0, -80}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -80}, {0, -80}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -80}, {0, -80}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 29, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 5 },
+ { 0, 17, 230, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 5 },
+ { 0, 17, 230, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 5 },
+ { 2, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 5 },
+ { 14, 0, 0, 0, -1, 0, 6, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 15}, {0, 0}, {0, 0}, {0, 15} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, -15}, {0, -15}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 4, 17, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 4, 17, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 12, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 5 },
+ { 15, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 48}, {0, 0}, {0, 0}, {0, 48} }, 0, 10, 12, 7, 6 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 6 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 6 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 11, 6 },
+ { 15, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, -48}, {0, -48}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 459}, {1, 456}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 12, 2 },
+ { 20, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 6 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 6 },
+ { 27, 4, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 6 },
+ { 13, 1, 0, 0, -1, 0, 0, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 0, 17, 220, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 230, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 222, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 220, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 228, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 10, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 11, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 12, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 13, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 14, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 15, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 16, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 17, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 18, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 19, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 19, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 20, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 21, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 22, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 20, 1, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 7 },
+ { 0, 17, 23, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 25, 1, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 7 },
+ { 0, 17, 24, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 0, 17, 25, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 25, 1, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 7 },
+ { 0, 17, 18, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 18, 1, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 9, 13, 8, 7 },
+ { 25, 1, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 7 },
+ { 25, 1, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 14, 12, 0, 7 },
+ { 10, 5, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 8 },
+ { 10, 5, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 8 },
+ { 10, 5, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 2 },
+ { 26, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 26, 13, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 25, 4, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 8 },
+ { 27, 13, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 8 },
+ { 25, 13, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 11, 8 },
+ { 29, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 0, 17, 230, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 230, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 30, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 31, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 32, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 25, 13, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 2 },
+ { 10, 13, 0, 5, -1, 0, 15, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 8 },
+ { 13, 13, 0, 0, -1, 0, 0, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 25, 13, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 8 },
+ { 25, 13, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 2 },
+ { 18, 13, 0, 2, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 17, 13, 0, 1, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 0, 17, 27, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 28, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 29, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 30, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 31, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 32, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 33, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 34, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 4, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 4, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 230, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 220, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 220, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 3, 5, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 5, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 25, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 8 },
+ { 25, 5, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 25, 5, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 11, 9, 8 },
+ { 25, 13, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 18, 13, 0, 2, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 0, 17, 35, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 18, 13, 0, 3, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 25, 13, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 8 },
+ { 0, 17, 230, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 10, 5, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 0, 17, 220, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 17, 13, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 3, 2, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 3, 2, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 8 },
+ { 29, 13, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 18, 13, 0, 2, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 25, 13, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 12, 9 },
+ { 25, 13, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 9 },
+ { 10, 13, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 9 },
+ { 18, 13, 0, 3, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 0, 17, 36, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 9 },
+ { 18, 13, 0, 2, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 18, 13, 0, 2, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 18, 13, 0, 3, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 0, 17, 230, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 9 },
+ { 0, 17, 220, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 9 },
+ { 18, 13, 0, 2, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 10 },
+ { 0, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 10 },
+ { 18, 13, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 10 },
+ { 3, 1, 0, 0, 0, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 2, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 3, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 4, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 5, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 6, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 7, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 8, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 3, 1, 0, 0, 9, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 66 },
+ { 18, 1, 0, 2, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 66 },
+ { 0, 17, 230, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 66 },
+ { 0, 17, 220, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 66 },
+ { 17, 1, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 66 },
+ { 29, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 66 },
+ { 25, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 66 },
+ { 25, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 11, 66 },
+ { 25, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 66 },
+ { 17, 1, 0, 1, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 66 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 82 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 82 },
+ { 17, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 82 },
+ { 25, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 82 },
+ { 18, 1, 0, 3, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 95 },
+ { 18, 1, 0, 2, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 95 },
+ { 18, 1, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 95 },
+ { 0, 17, 220, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 95 },
+ { 25, 1, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 95 },
+ { 18, 13, 0, 2, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 18, 13, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 18, 13, 0, 3, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 9 },
+ { 18, 13, 0, 2, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 2, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 18, 13, 0, 3, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 0, 17, 230, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 10, 5, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 2 },
+ { 0, 17, 220, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 230, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 220, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 27, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 28, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 29, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 230, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 8 },
+ { 0, 17, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 11 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 0, 17, 0, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 1, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 11 },
+ { 0, 17, 7, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 11 },
+ { 0, 17, 230, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 18, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 2 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 11 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 11 },
+ { 17, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 12 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 12 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 12 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 12 },
+ { 0, 17, 7, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 12 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 12 },
+ { 1, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 12 },
+ { 1, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 12 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 12 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 12 },
+ { 18, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 12 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 12 },
+ { 27, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 12 },
+ { 5, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 12 },
+ { 5, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 12 },
+ { 29, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 12 },
+ { 27, 4, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 12 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 12 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 12 },
+ { 0, 17, 0, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 13 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 13 },
+ { 1, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 13 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 13 },
+ { 18, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 13 },
+ { 0, 17, 7, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 13 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 13 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 13 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 13 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 13 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 14 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 14 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 14 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 14 },
+ { 0, 17, 7, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 14 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 14 },
+ { 0, 17, 0, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 14 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 14 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 14 },
+ { 27, 4, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 14 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 14 },
+ { 0, 17, 0, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 14 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 15 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 15 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 15 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 15 },
+ { 0, 17, 7, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 15 },
+ { 1, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 15 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 15 },
+ { 1, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 15 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 15 },
+ { 0, 17, 0, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 15 },
+ { 18, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 15 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 15 },
+ { 29, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 15 },
+ { 5, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 15 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 16 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 16 },
+ { 18, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 16 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 16 },
+ { 1, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 16 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 16 },
+ { 1, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 16 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 16 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 16 },
+ { 3, 0, 0, 0, 0, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 16 },
+ { 5, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 16 },
+ { 29, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 16 },
+ { 27, 4, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 16 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 17 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 17 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 17 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 17 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 0, 17, 0, 5, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 0, 17, 84, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 0, 17, 91, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 17 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 17 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 17 },
+ { 5, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 17 },
+ { 29, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 17 },
+ { 18, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 18 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 18 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 18 },
+ { 0, 17, 7, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 18 },
+ { 0, 0, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 1, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 18 },
+ { 1, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 0, 17, 0, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 18 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 18 },
+ { 18, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 18 },
+ { 0, 17, 0, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 1, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 19 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 19 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 19 },
+ { 0, 17, 9, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 19 },
+ { 1, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 1, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 19 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 19 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 10, 12, 8, 19 },
+ { 29, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 19 },
+ { 18, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 19 },
+ { 5, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 19 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 19 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 19 },
+ { 5, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 19 },
+ { 29, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 19 },
+ { 1, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 20 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 20 },
+ { 0, 17, 9, 5, -1, 0, 4, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 20 },
+ { 1, 0, 0, 0, -1, 0, 4, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 20 },
+ { 0, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 20 },
+ { 1, 0, 0, 0, -1, 0, 4, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 20 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 20 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 20 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 21 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 21 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 0, 33, 8, 21 },
+ { 0, 17, 103, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 21 },
+ { 0, 17, 9, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 21 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 21 },
+ { 0, 17, 107, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 21 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 21 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 21 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 21 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 22 },
+ { 0, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 22 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 0, 33, 8, 22 },
+ { 0, 17, 118, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 22 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 22 },
+ { 0, 17, 122, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 22 },
+ { 3, 0, 0, 0, 0, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 3, 0, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 22 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 22 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 22 },
+ { 18, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 23 },
+ { 29, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 4, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 2, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 4, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 23 },
+ { 29, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 23 },
+ { 0, 17, 220, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 3, 0, 0, 0, 0, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 2, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 3, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 4, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 5, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 6, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 7, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 8, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 3, 0, 0, 0, 9, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 23 },
+ { 5, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 23 },
+ { 29, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 23 },
+ { 0, 17, 216, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 21, 10, 0, 0, -1, 1, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 23 },
+ { 22, 10, 0, 0, -1, -1, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 23 },
+ { 1, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 23 },
+ { 18, 0, 0, 0, -1, 0, 2, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 23 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 23 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 23 },
+ { 0, 17, 129, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 130, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 0, 5, -1, 0, 2, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 132, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 0, 5, -1, 0, 2, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 0, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 1, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 17, 4, 23 },
+ { 0, 17, 230, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 9, 5, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 23 },
+ { 0, 17, 0, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 0, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 29, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 23 },
+ { 29, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 23 },
+ { 0, 17, 220, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 23 },
+ { 29, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 23 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 23 },
+ { 29, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 4, 0, 23 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 18, 0, 0, 0, -1, 0, 4, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 4, 33, 4, 24 },
+ { 1, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 4, 33, 4, 24 },
+ { 0, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 0, 17, 0, 5, -1, 0, 4, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 1, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 33, 4, 24 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 0, 17, 7, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 0, 17, 9, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 0, 17, 9, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 33, 4, 24 },
+ { 3, 0, 0, 0, 0, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 2, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 3, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 4, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 5, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 6, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 7, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 8, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 9, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 24 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 24 },
+ { 0, 17, 220, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 4, 33, 4, 24 },
+ { 0, 17, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 29, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 24 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 7264}, {0, 0}, {0, 0}, {0, 7264} }, 0, 10, 12, 7, 25 },
+ { 14, 0, 0, 0, -1, 0, 13, 0, { {0, 7264}, {0, 0}, {0, 0}, {0, 7264} }, 0, 10, 12, 7, 25 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 25 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 25 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 25 },
+ { 25, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 25 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 25 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 9, 10, 25, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 9, 10, 25, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 10, 10, 26, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 10, 10, 26, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 10, 10, 26, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 11, 10, 27, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 11, 10, 27, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 11, 10, 27, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 27 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 27 },
+ { 0, 17, 230, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 27 },
+ { 0, 17, 230, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 27 },
+ { 25, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 27 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 12, 27 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 2, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 3, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 4, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 5, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 6, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 7, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 8, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, 9, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 5, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 27 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 39}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 41}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 43}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 45}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 47}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 49}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 51}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 53}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 55}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 57}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 59}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 61}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 63}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 65}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 67}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 69}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 71}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 73}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 75}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 77}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 79}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 81}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 83}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 85}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 87}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 89}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 91}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 93}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 95}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 97}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 99}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 101}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 103}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 105}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 107}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 109}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 111}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 113}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 115}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 117}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 119}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 121}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 123}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 125}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 127}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 129}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 131}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 133}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 135}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 137}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 139}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 141}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 143}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 145}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 147}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 149}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 151}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 153}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 155}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 157}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 159}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 161}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 163}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 165}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 167}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 169}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 171}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 173}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 175}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 177}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 179}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 181}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 183}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 185}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 187}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 189}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 191}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 193}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 195}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {1, 197}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 4, 0, { {0, 8}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 14, 0, 0, 0, -1, 0, 17, 0, { {0, 8}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, -8}, {0, -8}, {0, -8} }, 0, 10, 12, 6, 28 },
+ { 20, 10, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 29 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 29 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 29 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 12, 29 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 29 },
+ { 6, 9, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 5, 30 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 30 },
+ { 21, 10, 0, 0, -1, 1, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 30 },
+ { 22, 10, 0, 0, -1, -1, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 30 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 31 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 4, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 31 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 31 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 42 },
+ { 0, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 42 },
+ { 0, 17, 9, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 42 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 43 },
+ { 0, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 43 },
+ { 0, 17, 9, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 43 },
+ { 25, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 2 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 44 },
+ { 0, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 44 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 45 },
+ { 0, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 45 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 32 },
+ { 0, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 32 },
+ { 1, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 33, 4, 32 },
+ { 0, 17, 9, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 32 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 32 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 0, 32 },
+ { 17, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 32 },
+ { 25, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 32 },
+ { 27, 4, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 32 },
+ { 0, 17, 230, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 32 },
+ { 3, 0, 0, 0, 0, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 2, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 3, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 4, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 5, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 6, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 7, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 8, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 3, 0, 0, 0, 9, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 32 },
+ { 5, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 32 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 33 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 33 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 33 },
+ { 25, 10, 0, 2, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 33 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 11, 33 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 33 },
+ { 25, 10, 0, 1, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 33 },
+ { 0, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 33 },
+ { 10, 18, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 4, 4, 33 },
+ { 3, 0, 0, 0, 0, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 2, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 3, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 4, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 5, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 6, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 7, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 8, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 3, 0, 0, 0, 9, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 33 },
+ { 18, 0, 0, 2, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 33 },
+ { 17, 0, 0, 2, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 33 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 33 },
+ { 0, 17, 228, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 33 },
+ { 18, 0, 0, 2, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 33 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 47 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 47 },
+ { 0, 17, 0, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 47 },
+ { 1, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 47 },
+ { 0, 17, 222, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 47 },
+ { 0, 17, 230, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 47 },
+ { 0, 17, 220, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 47 },
+ { 29, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 47 },
+ { 25, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 47 },
+ { 3, 0, 0, 0, 0, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 2, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 3, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 4, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 5, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 6, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 7, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 8, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 3, 0, 0, 0, 9, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 47 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 48 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 56 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 56 },
+ { 3, 0, 0, 0, 0, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 2, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 3, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 4, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 5, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 6, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 7, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 8, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 3, 0, 0, 0, 9, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 56 },
+ { 5, 0, 0, 0, 1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 56 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 56 },
+ { 29, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 32 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 55 },
+ { 0, 17, 230, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 55 },
+ { 0, 17, 220, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 55 },
+ { 1, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 55 },
+ { 0, 17, 0, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 55 },
+ { 25, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 55 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 78 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 33, 4, 78 },
+ { 0, 17, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 78 },
+ { 0, 17, 9, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 78 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 4, 33, 4, 78 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 78 },
+ { 0, 17, 220, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 78 },
+ { 3, 0, 0, 0, 0, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 2, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 3, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 4, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 5, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 6, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 7, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 8, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 3, 0, 0, 0, 9, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 78 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 78 },
+ { 17, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 78 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 12, 78 },
+ { 0, 17, 230, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 2, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 0, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 62 },
+ { 1, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 62 },
+ { 18, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 62 },
+ { 18, 0, 0, 0, -1, 0, 9, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 62 },
+ { 0, 17, 7, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 62 },
+ { 1, 0, 0, 0, -1, 0, 9, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 62 },
+ { 1, 0, 0, 0, -1, 0, 9, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 62 },
+ { 1, 0, 9, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 62 },
+ { 3, 0, 0, 0, 0, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 2, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 3, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 4, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 5, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 6, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 7, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 8, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 3, 0, 0, 0, 9, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 62 },
+ { 25, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 62 },
+ { 25, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 62 },
+ { 25, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 62 },
+ { 29, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 62 },
+ { 0, 17, 230, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 62 },
+ { 0, 17, 220, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 62 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 67 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 67 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 67 },
+ { 1, 0, 9, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 67 },
+ { 0, 17, 9, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 67 },
+ { 0, 17, 0, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 67 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 67 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 67 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 93 },
+ { 0, 17, 7, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 93 },
+ { 1, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 93 },
+ { 0, 17, 0, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 93 },
+ { 1, 0, 9, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 93 },
+ { 25, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 93 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 68 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 68 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 68 },
+ { 0, 17, 7, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 68 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 68 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 68 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 68 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 69 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 69 },
+ { 17, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 69 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 69 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6254}, {0, -6254}, {0, -6222} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6253}, {0, -6253}, {0, -6221} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6244}, {0, -6244}, {0, -6212} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6242}, {0, -6242}, {0, -6210} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6243}, {0, -6243}, {0, -6211} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6236}, {0, -6236}, {0, -6204} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -6181}, {0, -6181}, {0, -6180} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {1, 199}, {1, 199}, {1, 711} }, 0, 10, 12, 6, 5 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 67 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 0, 17, 1, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 2 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 1, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 2 },
+ { 0, 17, 230, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 1, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 2 },
+ { 15, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 17, 0, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 0, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 17, 0, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {1, 201}, {1, 201}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 3814}, {0, 3814}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 0, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 0, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 0, 17, 230, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 234, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 214, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 202, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 232, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 228, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 233, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 506}, {1, 506}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 509}, {1, 509}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 512}, {1, 512}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 515}, {1, 515}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 518}, {1, 518}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 2, 81, { {0, 0}, {0, -59}, {0, -59}, {0, -58} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {0, -7615}, {0, 0}, {0, 0}, {0, -7615} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 8}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {0, 0}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 521}, {1, 521}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 524}, {1, 524}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 528}, {1, 528}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 532}, {1, 532}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 74}, {0, 74}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 74}, {0, 74}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 86}, {0, 86}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 86}, {0, 86}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 100}, {0, 100}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 100}, {0, 100}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 128}, {0, 128}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 128}, {0, 128}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 112}, {0, 112}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 112}, {0, 112}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 126}, {0, 126}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 126}, {0, 126}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 570}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 573}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 576}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 579}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 582}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 585}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 588}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 591}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 570}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 573}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 576}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 579}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 582}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 585}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 588}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 591}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 594}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 597}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 600}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 603}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 606}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 609}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 612}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 615}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 594}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 597}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 600}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 603}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 606}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 609}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 612}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 615}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 618}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 621}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 624}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 627}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 630}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 633}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 636}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 639}, {0, 8}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 618}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 621}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 624}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 627}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 630}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 633}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 636}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -8}, {1, 639}, {0, 0}, {0, -8} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 654}, {1, 651}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 642}, {0, 9}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 660}, {1, 657}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 536}, {1, 536}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 691}, {1, 687}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -74}, {0, 0}, {0, 0}, {0, -74} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -74}, {0, 0}, {0, 0}, {0, -74} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -9}, {1, 642}, {0, 0}, {0, -9} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, -7205}, {0, -7205}, {0, -7173} }, 0, 10, 12, 6, 4 },
+ { 28, 10, 0, 0, -1, 0, 1, 81, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 666}, {1, 663}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 645}, {0, 9}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 672}, {1, 669}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 539}, {1, 539}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 699}, {1, 695}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -86}, {0, 0}, {0, 0}, {0, -86} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -86}, {0, 0}, {0, 0}, {0, -86} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -9}, {1, 645}, {0, 0}, {0, -9} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 542}, {1, 542}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {1, 495}, {1, 495}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 546}, {1, 546}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 549}, {1, 549}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -100}, {0, 0}, {0, 0}, {0, -100} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -100}, {0, 0}, {0, 0}, {0, -100} }, 0, 10, 12, 7, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 553}, {1, 553}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {1, 499}, {1, 499}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 557}, {1, 557}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 7}, {0, 7}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 560}, {1, 560}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 563}, {1, 563}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -112}, {0, 0}, {0, 0}, {0, -112} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -112}, {0, 0}, {0, 0}, {0, -112} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -7}, {0, 0}, {0, 0}, {0, -7} }, 0, 10, 12, 7, 4 },
+ { 28, 10, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 678}, {1, 675}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 648}, {0, 9}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 684}, {1, 681}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 567}, {1, 567}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {1, 707}, {1, 703}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -128}, {0, 0}, {0, 0}, {0, -128} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -128}, {0, 0}, {0, 0}, {0, -128} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 17, { {0, -126}, {0, 0}, {0, 0}, {0, -126} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -126}, {0, 0}, {0, 0}, {0, -126} }, 0, 10, 12, 7, 4 },
+ { 16, 0, 0, 0, -1, 0, 1, 17, { {0, -9}, {1, 648}, {0, 0}, {0, -9} }, 0, 10, 12, 7, 4 },
+ { 28, 10, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 4 },
+ { 6, 9, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 5, 2 },
+ { 6, 9, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 5, 2 },
+ { 6, 9, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 4, 5, 2 },
+ { 10, 18, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 20, 4, 2 },
+ { 10, 18, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 10, 18, 0, 1, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 5, 5, 32, 4, 1 },
+ { 10, 0, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 1, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 20, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 4, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 11, 2 },
+ { 20, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 19, 11, 2 },
+ { 20, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 23, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 13, 3, 13, 2 },
+ { 24, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 13, 3, 13, 2 },
+ { 21, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 23, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 24, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 13, 15, 10, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 15, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 14, 17, 0, 2 },
+ { 7, 9, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 3, 38, 3, 2 },
+ { 8, 7, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 3, 38, 3, 2 },
+ { 10, 11, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 14, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 16, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 12, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 15, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 6, 6, 0, 0, -1, 0, 4, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 17, 4, 5, 2 },
+ { 25, 4, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 23, 10, 0, 0, -1, 1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 24, 10, 0, 0, -1, -1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 12, 2 },
+ { 26, 6, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 4, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 19, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 17, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 6, 9, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 5, 2 },
+ { 10, 18, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 22, 4, 2 },
+ { 10, 18, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 12, 4, 2 },
+ { 10, 18, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 12, 4, 2 },
+ { 13, 18, 0, 0, -1, 0, 0, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 12, 0, 0 },
+ { 10, 19, 0, 0, -1, 0, 15, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 20, 0, 0, -1, 0, 15, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 21, 0, 0, -1, 0, 15, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 22, 0, 0, -1, 0, 15, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 10, 18, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 5, 2, 0, 0, 0, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 5, 2, 0, 0, 4, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 5, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 6, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 7, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 8, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 9, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 3, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 21, 10, 0, 0, -1, 1, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 17, 0, 0, 0, -1, 0, 12, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 27, 4, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 3, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 14, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 13, 4, 0, 0, -1, 0, 0, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 0 },
+ { 2, 17, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 2, 17, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 2, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 1, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 220, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 1, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 29, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 9, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {0, -7517}, {0, 0}, {0, 0}, {0, -7517} }, 0, 10, 12, 7, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {1, 203}, {0, 0}, {0, 0}, {1, 203} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 85, { {1, 205}, {0, 0}, {0, 0}, {1, 205} }, 0, 10, 12, 7, 3 },
+ { 29, 4, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, { {0, 28}, {0, 0}, {0, 0}, {0, 28} }, 0, 10, 12, 7, 3 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 15, 0, 0, 0, -1, 0, 4, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 29, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 15, 0, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 15, 0, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 14, 0, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 26, 10, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, -28}, {0, -28}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 29, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, -1, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 4, 0, 0, 0, -1, 0, 1, 80, { {0, 16}, {0, 0}, {0, 0}, {0, 16} }, 0, 10, 12, 7, 3 },
+ { 4, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -16}, {0, -16}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 4, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 3 },
+ { 4, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 3 },
+ { 29, 10, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 3, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 3, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -3, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -3, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 2016, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -1, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 138, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 1, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -1, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 1824, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 2104, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 2108, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 2106, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -138, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 15, 0, 2 },
+ { 26, 10, 0, 0, -1, 8, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 7, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -8, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -7, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 21, 10, 0, 0, -1, 1, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 29, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 2, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 3, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 4, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 5, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 6, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 7, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 8, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 9, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 1, 80, { {0, 26}, {0, 0}, {0, 0}, {0, 26} }, 0, 10, 12, 7, 2 },
+ { 29, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -26}, {0, -26}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 5, 10, 0, 0, 0, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 2, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 3, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 4, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 5, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 6, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 7, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 8, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 9, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 0, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 16, 20, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 16, 20, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 16, 20, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 29, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 2 },
+ { 21, 10, 0, 0, -1, 1, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 5, 10, 0, 0, 1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 2, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 3, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 4, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 5, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 6, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 7, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 8, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, 9, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 1, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -1, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 21, 10, 0, 0, -1, 1, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 26, 10, 0, 0, -1, 1, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -1, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 2, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -2, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 1, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -1, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 21, 10, 0, 0, -1, 1, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 29, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 54 },
+ { 21, 10, 0, 0, -1, 3, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, 1, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 21, 10, 0, 0, -1, -1, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -3, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 26, 10, 0, 0, -1, -1824, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -2016, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 6, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -2104, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -2106, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, -2108, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {0, 48}, {0, 0}, {0, 0}, {0, 48} }, 0, 10, 12, 7, 57 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, -48}, {0, -48}, {0, 0} }, 0, 10, 12, 6, 57 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {1, 207}, {0, 0}, {0, 0}, {1, 207} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {0, -3814}, {0, 0}, {0, 0}, {0, -3814} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, { {1, 209}, {0, 0}, {0, 0}, {1, 209} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {1, 211}, {1, 211}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {1, 213}, {1, 213}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {1, 215}, {0, 0}, {0, 0}, {1, 215} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {1, 217}, {0, 0}, {0, 0}, {1, 217} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {1, 219}, {0, 0}, {0, 0}, {1, 219} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, { {1, 221}, {0, 0}, {0, 0}, {1, 221} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 17, 0, 0, 0, -1, 0, 10, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, { {1, 223}, {0, 0}, {0, 0}, {1, 223} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, { {1, 225}, {0, 0}, {0, 0}, {1, 225} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 46 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 46 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 46 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 46 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 46 },
+ { 15, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 46 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 46 },
+ { 14, 0, 0, 0, -1, 0, 13, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 46 },
+ { 15, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 46 },
+ { 25, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 46 },
+ { 25, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 46 },
+ { 5, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 46 },
+ { 15, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, -7264}, {0, -7264}, {0, 0} }, 0, 10, 12, 6, 25 },
+ { 15, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, -7264}, {0, -7264}, {0, 0} }, 0, 10, 12, 6, 25 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 58 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 58 },
+ { 17, 0, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 58 },
+ { 25, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 58 },
+ { 0, 17, 9, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 58 },
+ { 25, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 23, 10, 0, 0, -1, 1, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 24, 10, 0, 0, -1, -1, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 20, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 23, 10, 0, 0, -1, 1, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 24, 10, 0, 0, -1, -1, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 19, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 21, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 37 },
+ { 29, 10, 0, 0, -1, 0, 4, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 37 },
+ { 29, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 5, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 2 },
+ { 4, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 20, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 0, 2 },
+ { 22, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 0, 17, 218, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 228, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 222, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 1, 0, 224, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 26 },
+ { 20, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 8, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 21, 8, 2 },
+ { 29, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 4, 0, 0, 0, -1, 0, 4, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 17, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 5, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 5, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 8, 34 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 34 },
+ { 18, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 34 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 8, 34 },
+ { 0, 17, 8, 5, -1, 0, 1, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 28, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 8, 34 },
+ { 17, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 8, 34 },
+ { 18, 0, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 34 },
+ { 20, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 0, 2 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 35 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 8, 35 },
+ { 18, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 8, 35 },
+ { 25, 10, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 35 },
+ { 17, 0, 0, 0, -1, 0, 1, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 35 },
+ { 18, 0, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 8, 35 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 36 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 36 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 36 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 26 },
+ { 29, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 5, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 36 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 36 },
+ { 18, 0, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 35 },
+ { 29, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 26 },
+ { 29, 10, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 26 },
+ { 29, 0, 0, 0, -1, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 5, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 5, 10, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 26 },
+ { 29, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 0, 35 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 0 },
+ { 18, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 14, 8, 38 },
+ { 17, 0, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 5, 8, 38 },
+ { 29, 10, 0, 0, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 38 },
+ { 29, 10, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 38 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 83 },
+ { 17, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 83 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 83 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 83 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 70 },
+ { 17, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 70 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 70 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 70 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 70 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 70 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 5 },
+ { 2, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 5 },
+ { 25, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 5 },
+ { 0, 17, 230, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 5 },
+ { 17, 10, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 5 },
+ { 17, 0, 0, 0, -1, 0, 16, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 5 },
+ { 0, 17, 230, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 5 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 84 },
+ { 4, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 84 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 84 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 84 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 84 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 84 },
+ { 28, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 17, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 28, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 10, 0, { {1, 227}, {0, 0}, {0, 0}, {1, 227} }, 0, 10, 12, 7, 3 },
+ { 28, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 12, 0, { {1, 229}, {0, 0}, {0, 0}, {1, 229} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 3 },
+ { 14, 0, 0, 0, -1, 0, 12, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 13, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 14, 0, 0, 0, -1, 0, 13, 0, { {1, 231}, {0, 0}, {0, 0}, {1, 231} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {1, 233}, {0, 0}, {0, 0}, {1, 233} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {1, 235}, {0, 0}, {0, 0}, {1, 235} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {1, 237}, {0, 0}, {0, 0}, {1, 237} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 18, 0, { {1, 239}, {0, 0}, {0, 0}, {1, 239} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {1, 241}, {0, 0}, {0, 0}, {1, 241} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {1, 243}, {0, 0}, {0, 0}, {1, 243} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 17, 0, { {1, 245}, {0, 0}, {0, 0}, {1, 245} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 17, 0, { {0, 928}, {0, 0}, {0, 0}, {0, 928} }, 0, 10, 12, 7, 3 },
+ { 14, 0, 0, 0, -1, 0, 17, 0, { {0, 1}, {0, 0}, {0, 0}, {0, 1} }, 0, 10, 12, 7, 3 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, -1}, {0, -1}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 3 },
+ { 17, 0, 0, 0, -1, 0, 13, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 3 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 59 },
+ { 0, 17, 0, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 59 },
+ { 0, 17, 9, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 59 },
+ { 1, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 59 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 59 },
+ { 29, 4, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 18, 0, 0, 2, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 65 },
+ { 18, 0, 0, 4, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 65 },
+ { 18, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 65 },
+ { 25, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 65 },
+ { 25, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 65 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 71 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 71 },
+ { 0, 17, 9, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 71 },
+ { 0, 17, 0, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 71 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 71 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 71 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 11 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 11 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 11 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 11 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 72 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 72 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 72 },
+ { 0, 17, 220, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 72 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 72 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 73 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 73 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 73 },
+ { 1, 0, 9, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 73 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 73 },
+ { 0, 17, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 85 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 85 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 85 },
+ { 0, 17, 7, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 85 },
+ { 1, 0, 9, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 85 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 85 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 85 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 85 },
+ { 17, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 2 },
+ { 3, 0, 0, 0, 0, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 2, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 3, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 4, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 5, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 6, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 7, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 8, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 3, 0, 0, 0, 9, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 85 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 24 },
+ { 17, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 24 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 77 },
+ { 0, 17, 0, 5, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 77 },
+ { 1, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 77 },
+ { 3, 0, 0, 0, 0, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 2, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 3, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 4, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 5, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 6, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 7, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 8, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 3, 0, 0, 0, 9, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 77 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 77 },
+ { 25, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 77 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 17, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 24 },
+ { 29, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 24 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 4, 33, 4, 24 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 79 },
+ { 0, 17, 230, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 79 },
+ { 0, 17, 220, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 79 },
+ { 17, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 79 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 79 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 86 },
+ { 1, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 86 },
+ { 0, 17, 0, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 86 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 86 },
+ { 17, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 86 },
+ { 0, 17, 9, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 86 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 27 },
+ { 15, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, -928}, {0, -928}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 28, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 0, 2 },
+ { 17, 0, 0, 0, -1, 0, 16, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 4 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 247}, {1, 247}, {1, 247} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 249}, {1, 249}, {1, 249} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 251}, {1, 251}, {1, 251} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 253}, {1, 253}, {1, 253} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 255}, {1, 255}, {1, 255} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 257}, {1, 257}, {1, 257} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 259}, {1, 259}, {1, 259} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 261}, {1, 261}, {1, 261} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 263}, {1, 263}, {1, 263} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 265}, {1, 265}, {1, 265} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 267}, {1, 267}, {1, 267} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 269}, {1, 269}, {1, 269} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 271}, {1, 271}, {1, 271} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 273}, {1, 273}, {1, 273} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 275}, {1, 275}, {1, 275} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 277}, {1, 277}, {1, 277} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 279}, {1, 279}, {1, 279} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 281}, {1, 281}, {1, 281} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 283}, {1, 283}, {1, 283} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 285}, {1, 285}, {1, 285} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 287}, {1, 287}, {1, 287} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 289}, {1, 289}, {1, 289} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 291}, {1, 291}, {1, 291} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 293}, {1, 293}, {1, 293} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 295}, {1, 295}, {1, 295} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 297}, {1, 297}, {1, 297} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 299}, {1, 299}, {1, 299} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 301}, {1, 301}, {1, 301} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 303}, {1, 303}, {1, 303} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 305}, {1, 305}, {1, 305} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 307}, {1, 307}, {1, 307} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 309}, {1, 309}, {1, 309} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 311}, {1, 311}, {1, 311} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 313}, {1, 313}, {1, 313} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 315}, {1, 315}, {1, 315} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 317}, {1, 317}, {1, 317} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 319}, {1, 319}, {1, 319} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 321}, {1, 321}, {1, 321} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 323}, {1, 323}, {1, 323} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 325}, {1, 325}, {1, 325} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 327}, {1, 327}, {1, 327} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 329}, {1, 329}, {1, 329} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 331}, {1, 331}, {1, 331} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 333}, {1, 333}, {1, 333} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 335}, {1, 335}, {1, 335} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 337}, {1, 337}, {1, 337} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 339}, {1, 339}, {1, 339} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 341}, {1, 341}, {1, 341} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 343}, {1, 343}, {1, 343} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 345}, {1, 345}, {1, 345} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 347}, {1, 347}, {1, 347} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 349}, {1, 349}, {1, 349} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 351}, {1, 351}, {1, 351} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 353}, {1, 353}, {1, 353} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 355}, {1, 355}, {1, 355} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 357}, {1, 357}, {1, 357} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 359}, {1, 359}, {1, 359} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 361}, {1, 361}, {1, 361} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 363}, {1, 363}, {1, 363} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 365}, {1, 365}, {1, 365} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 367}, {1, 367}, {1, 367} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 369}, {1, 369}, {1, 369} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 371}, {1, 371}, {1, 371} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 373}, {1, 373}, {1, 373} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 375}, {1, 375}, {1, 375} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 377}, {1, 377}, {1, 377} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 379}, {1, 379}, {1, 379} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 381}, {1, 381}, {1, 381} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 383}, {1, 383}, {1, 383} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 385}, {1, 385}, {1, 385} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 387}, {1, 387}, {1, 387} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 389}, {1, 389}, {1, 389} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 391}, {1, 391}, {1, 391} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 393}, {1, 393}, {1, 393} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 395}, {1, 395}, {1, 395} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 397}, {1, 397}, {1, 397} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 399}, {1, 399}, {1, 399} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 401}, {1, 401}, {1, 401} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 403}, {1, 403}, {1, 403} }, 0, 10, 12, 6, 28 },
+ { 15, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {1, 405}, {1, 405}, {1, 405} }, 0, 10, 12, 6, 28 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 86 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 86 },
+ { 0, 17, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 86 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 86 },
+ { 0, 17, 9, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 86 },
+ { 3, 0, 0, 0, 0, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 2, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 3, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 4, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 5, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 6, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 7, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 8, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 3, 0, 0, 0, 9, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 86 },
+ { 18, 0, 0, 0, -1, 0, 2, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 12, 10, 23, 8, 26 },
+ { 18, 0, 0, 0, -1, 0, 2, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 13, 10, 24, 8, 26 },
+ { 11, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 0, 34, 0, 0 },
+ { 12, 0, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 18, 0, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 13, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 6, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 11, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 8, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 419}, {1, 416}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 425}, {1, 422}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 431}, {1, 428}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 438}, {1, 434}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 446}, {1, 442}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 453}, {1, 450}, {0, 0} }, 0, 10, 12, 6, 3 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 465}, {1, 462}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 471}, {1, 468}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 477}, {1, 474}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 483}, {1, 480}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {1, 489}, {1, 486}, {0, 0} }, 0, 10, 12, 6, 6 },
+ { 18, 1, 0, 0, -1, 0, 4, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 9, 13, 8, 7 },
+ { 0, 17, 26, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 7 },
+ { 18, 1, 0, 0, -1, 0, 1, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 9, 13, 8, 7 },
+ { 18, 1, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 9, 13, 8, 7 },
+ { 26, 3, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 7 },
+ { 18, 13, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 28, 13, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 13, 18, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 27, 13, 0, 0, -1, 0, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 8 },
+ { 0, 17, 0, 5, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 14, 8, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 8, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 2 },
+ { 21, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 8, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 15, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 20, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 11, 2 },
+ { 19, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 17, 14, 0, 2 },
+ { 21, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 21, 10, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 1, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 11, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 13, 1, 10, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 15, 5, 0, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 14, 5, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 12, 2 },
+ { 25, 4, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 26, 3, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 20, 3, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 11, 2 },
+ { 26, 10, 0, 0, -1, 1, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 26, 10, 0, 0, -1, -1, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 18, 13, 0, 0, -1, 0, 6, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 10, 18, 0, 5, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 22, 4, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 13, 14, 0, 2 },
+ { 25, 6, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 0, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 2, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 3, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 4, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 5, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 6, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 7, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 8, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 3, 2, 0, 0, 9, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 26, 10, 0, 0, -1, 2, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 26, 10, 0, 0, -1, -2, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 1, 80, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 14, 7, 3 },
+ { 21, 10, 0, 0, -1, 2, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -2, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 28, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 15, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 14, 6, 3 },
+ { 21, 10, 0, 0, -1, 1, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 13, 2 },
+ { 22, 10, 0, 0, -1, -1, 6, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 13, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 1, 11, 2 },
+ { 25, 10, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 0, 2 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 8, 35 },
+ { 18, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 35 },
+ { 17, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 5, 8, 2 },
+ { 17, 0, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 5, 4, 2 },
+ { 27, 4, 0, 0, -1, 0, 1, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 10, 0, 2 },
+ { 10, 10, 0, 5, -1, 0, 4, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 29, 10, 0, 0, -1, 0, 3, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 29, 0, 2 },
+ { 13, 18, 0, 0, -1, 0, 1, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 49 },
+ { 25, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 2 },
+ { 5, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 4, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 4 },
+ { 5, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 29, 10, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 5, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 29, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 4 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 74 },
+ { 18, 0, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 75 },
+ { 5, 2, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 18, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 39 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 39 },
+ { 5, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 39 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 39 },
+ { 18, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 40 },
+ { 4, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 40 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 120 },
+ { 0, 17, 230, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 120 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 50 },
+ { 25, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 50 },
+ { 18, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 60 },
+ { 25, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 60 },
+ { 4, 0, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 60 },
+ { 14, 0, 0, 0, -1, 0, 5, 0, { {0, 40}, {0, 0}, {0, 0}, {0, 40} }, 0, 10, 12, 7, 41 },
+ { 14, 0, 0, 0, -1, 0, 7, 0, { {0, 40}, {0, 0}, {0, 0}, {0, 40} }, 0, 10, 12, 7, 41 },
+ { 15, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, -40}, {0, -40}, {0, 0} }, 0, 10, 12, 6, 41 },
+ { 15, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, -40}, {0, -40}, {0, 0} }, 0, 10, 12, 6, 41 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 51 },
+ { 18, 0, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 52 },
+ { 3, 0, 0, 0, 0, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 2, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 3, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 4, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 5, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 6, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 7, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 8, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 3, 0, 0, 0, 9, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 52 },
+ { 14, 0, 0, 0, -1, 0, 18, 0, { {0, 40}, {0, 0}, {0, 0}, {0, 40} }, 0, 10, 12, 7, 136 },
+ { 15, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, -40}, {0, -40}, {0, 0} }, 0, 10, 12, 6, 136 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 106 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 103 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 103 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 110 },
+ { 18, 1, 0, 0, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 53 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 87 },
+ { 25, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 87 },
+ { 5, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 87 },
+ { 18, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 118 },
+ { 29, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 118 },
+ { 5, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 118 },
+ { 18, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 117 },
+ { 5, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 117 },
+ { 18, 1, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 128 },
+ { 5, 1, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 128 },
+ { 18, 1, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 64 },
+ { 5, 1, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 64 },
+ { 5, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 64 },
+ { 25, 10, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 64 },
+ { 18, 1, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 76 },
+ { 25, 1, 0, 0, -1, 0, 10, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 76 },
+ { 18, 1, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 98 },
+ { 18, 1, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 97 },
+ { 5, 1, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 97 },
+ { 18, 1, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 61 },
+ { 0, 17, 0, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 61 },
+ { 0, 17, 220, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 61 },
+ { 0, 17, 230, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 61 },
+ { 0, 17, 1, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 61 },
+ { 0, 17, 9, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 61 },
+ { 5, 1, 0, 0, 1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 61 },
+ { 5, 1, 0, 0, 2, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 61 },
+ { 5, 1, 0, 0, 3, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 61 },
+ { 5, 1, 0, 0, 4, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 61 },
+ { 5, 1, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 61 },
+ { 25, 1, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 61 },
+ { 25, 1, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 61 },
+ { 25, 1, 0, 0, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 61 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 88 },
+ { 5, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 88 },
+ { 25, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 88 },
+ { 18, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 116 },
+ { 5, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 116 },
+ { 18, 1, 0, 2, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 112 },
+ { 18, 1, 0, 3, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 112 },
+ { 18, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 112 },
+ { 29, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 112 },
+ { 18, 1, 0, 4, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 112 },
+ { 0, 17, 230, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 112 },
+ { 0, 17, 220, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 112 },
+ { 5, 1, 0, 2, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 112 },
+ { 5, 1, 0, 3, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 112 },
+ { 25, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 112 },
+ { 25, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 15, 0, 112 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 80 },
+ { 25, 10, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 80 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 89 },
+ { 5, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 89 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 90 },
+ { 5, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 90 },
+ { 18, 1, 0, 2, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 121 },
+ { 18, 1, 0, 3, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 121 },
+ { 25, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 121 },
+ { 5, 1, 0, 3, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 121 },
+ { 5, 1, 0, 2, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 121 },
+ { 5, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 121 },
+ { 18, 1, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 91 },
+ { 14, 1, 0, 0, -1, 0, 17, 0, { {0, 64}, {0, 0}, {0, 0}, {0, 64} }, 0, 10, 12, 7, 130 },
+ { 15, 1, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, -64}, {0, -64}, {0, 0} }, 0, 10, 12, 6, 130 },
+ { 5, 1, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 130 },
+ { 5, 5, 0, 0, 1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 2, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 3, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 4, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 5, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 6, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 7, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 8, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, 9, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 5, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 1, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 94 },
+ { 0, 17, 0, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 94 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 94 },
+ { 0, 17, 9, 5, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 94 },
+ { 25, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 94 },
+ { 25, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 2, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 3, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 4, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 5, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 6, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 7, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 8, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, 9, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 5, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 94 },
+ { 3, 0, 0, 0, 0, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 2, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 3, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 4, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 5, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 6, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 7, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 8, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 3, 0, 0, 0, 9, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 94 },
+ { 0, 17, 9, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 94 },
+ { 0, 17, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 92 },
+ { 1, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 92 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 92 },
+ { 18, 0, 0, 0, -1, 0, 11, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 92 },
+ { 0, 17, 9, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 92 },
+ { 0, 17, 7, 5, -1, 0, 11, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 92 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 92 },
+ { 10, 0, 0, 5, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 6, 12, 4, 92 },
+ { 25, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 92 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 101 },
+ { 3, 0, 0, 0, 0, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 2, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 3, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 4, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 5, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 6, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 7, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 8, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 3, 0, 0, 0, 9, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 101 },
+ { 0, 17, 230, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 96 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 96 },
+ { 0, 17, 0, 5, -1, 0, 13, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 96 },
+ { 0, 17, 0, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 96 },
+ { 1, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 96 },
+ { 0, 17, 0, 5, -1, 0, 13, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 96 },
+ { 0, 17, 9, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 96 },
+ { 3, 0, 0, 0, 0, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 2, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 3, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 4, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 5, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 6, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 7, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 8, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 3, 0, 0, 0, 9, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 96 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 96 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 96 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 111 },
+ { 0, 17, 7, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 111 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 111 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 111 },
+ { 0, 17, 0, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 100 },
+ { 1, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 100 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 100 },
+ { 1, 0, 9, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 100 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 10, 12, 8, 100 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 100 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 100 },
+ { 25, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 100 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 100 },
+ { 0, 17, 7, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 100 },
+ { 0, 17, 0, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 100 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 12, 100 },
+ { 3, 0, 0, 0, 0, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 2, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 3, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 4, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 5, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 6, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 7, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 8, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 3, 0, 0, 0, 9, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 100 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 100 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 100 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 100 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 100 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 100 },
+ { 5, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 20 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 109 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 109 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 109 },
+ { 1, 0, 9, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 109 },
+ { 0, 17, 7, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 109 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 109 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 109 },
+ { 0, 17, 0, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 109 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 129 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 129 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 123 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 123 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 123 },
+ { 0, 17, 7, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 123 },
+ { 0, 17, 9, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 123 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 123 },
+ { 0, 17, 0, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 107 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 107 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 107 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 107 },
+ { 0, 17, 7, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 107 },
+ { 1, 0, 0, 0, -1, 0, 16, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 107 },
+ { 1, 0, 0, 0, -1, 0, 16, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 107 },
+ { 1, 0, 9, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 107 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 107 },
+ { 0, 17, 230, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 107 },
+ { 18, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 135 },
+ { 1, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 135 },
+ { 0, 17, 0, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 135 },
+ { 0, 17, 9, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 135 },
+ { 0, 17, 7, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 135 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 135 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 135 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 135 },
+ { 3, 0, 0, 0, 0, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 2, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 3, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 4, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 5, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 6, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 7, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 8, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 3, 0, 0, 0, 9, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 135 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 124 },
+ { 1, 0, 0, 0, -1, 0, 16, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 124 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 124 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 124 },
+ { 0, 17, 0, 5, -1, 0, 16, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 124 },
+ { 1, 0, 0, 0, -1, 0, 16, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 124 },
+ { 0, 17, 9, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 124 },
+ { 0, 17, 7, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 124 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 124 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 124 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 122 },
+ { 1, 0, 0, 0, -1, 0, 16, 204, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 122 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 122 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 122 },
+ { 1, 0, 0, 0, -1, 0, 16, 17, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 122 },
+ { 0, 17, 9, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 122 },
+ { 0, 17, 7, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 122 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 122 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 122 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 122 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 122 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 122 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 122 },
+ { 0, 17, 0, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 122 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 114 },
+ { 1, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 114 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 114 },
+ { 0, 17, 9, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 114 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 114 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 114 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 114 },
+ { 25, 10, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 33 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 102 },
+ { 0, 17, 0, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 102 },
+ { 1, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 102 },
+ { 1, 0, 9, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 102 },
+ { 0, 17, 7, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 102 },
+ { 3, 0, 0, 0, 0, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 2, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 3, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 4, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 5, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 6, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 7, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 8, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 3, 0, 0, 0, 9, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 102 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 8, 126 },
+ { 0, 17, 0, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 126 },
+ { 1, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 33, 4, 126 },
+ { 0, 17, 9, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 33, 4, 126 },
+ { 3, 0, 0, 0, 0, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 2, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 3, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 4, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 5, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 6, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 7, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 8, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 3, 0, 0, 0, 9, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 126 },
+ { 5, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 126 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 126 },
+ { 29, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 33, 0, 126 },
+ { 14, 0, 0, 0, -1, 0, 16, 0, { {0, 32}, {0, 0}, {0, 0}, {0, 32} }, 0, 10, 12, 7, 125 },
+ { 15, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, -32}, {0, -32}, {0, 0} }, 0, 10, 12, 6, 125 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 125 },
+ { 5, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 125 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 125 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 141 },
+ { 0, 17, 0, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 141 },
+ { 1, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 141 },
+ { 0, 17, 9, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 141 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 10, 12, 8, 141 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 141 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 141 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 141 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 141 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 140 },
+ { 0, 17, 0, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 140 },
+ { 1, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 140 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 10, 12, 8, 140 },
+ { 0, 17, 9, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 140 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 140 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 140 },
+ { 25, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 140 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 119 },
+ { 18, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 133 },
+ { 1, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 133 },
+ { 0, 17, 0, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 133 },
+ { 0, 0, 9, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 133 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 133 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 133 },
+ { 3, 0, 0, 0, 0, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 2, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 3, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 4, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 5, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 6, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 7, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 8, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 3, 0, 0, 0, 9, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 133 },
+ { 5, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 133 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 18, 0, 134 },
+ { 25, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 6, 0, 134 },
+ { 18, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 134 },
+ { 0, 17, 0, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 134 },
+ { 1, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 134 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 138 },
+ { 0, 17, 0, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 138 },
+ { 0, 17, 7, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 138 },
+ { 0, 17, 9, 5, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 138 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 7, 10, 12, 8, 138 },
+ { 3, 0, 0, 0, 0, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 2, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 3, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 4, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 5, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 6, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 7, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 8, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 3, 0, 0, 0, 9, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 138 },
+ { 18, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 63 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 63 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 63 },
+ { 4, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 63 },
+ { 4, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 63 },
+ { 25, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 63 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 63 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 81 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 0, 8, 81 },
+ { 18, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 1, 8, 81 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 127 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 0, 8, 127 },
+ { 18, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 1, 8, 127 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 84 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 115 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 115 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 115 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 104 },
+ { 0, 17, 1, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 104 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 104 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 108 },
+ { 0, 17, 230, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 108 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 108 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 108 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 108 },
+ { 29, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 108 },
+ { 17, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 108 },
+ { 3, 0, 0, 0, 0, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 2, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 3, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 4, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 5, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 6, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 7, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 8, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 3, 0, 0, 0, 9, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 108 },
+ { 5, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 108 },
+ { 18, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 99 },
+ { 1, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 99 },
+ { 0, 17, 0, 5, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 99 },
+ { 17, 0, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 99 },
+ { 17, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 5, 8, 137 },
+ { 17, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 5, 8, 139 },
+ { 18, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 137 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 8, 14, 8, 35 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 34 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 34 },
+ { 18, 0, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 139 },
+ { 18, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 105 },
+ { 29, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 105 },
+ { 0, 17, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 105 },
+ { 0, 17, 1, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 105 },
+ { 25, 0, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 105 },
+ { 10, 18, 0, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 29, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 5, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 1, 0, 216, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 2 },
+ { 1, 0, 216, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 2 },
+ { 0, 17, 1, 5, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 1, 0, 226, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 8, 4, 21, 4, 2 },
+ { 10, 18, 0, 5, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 3, 6, 21, 4, 2 },
+ { 0, 17, 220, 5, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 29, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 0, 17, 230, 5, -1, 0, 8, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 4 },
+ { 5, 0, 0, 0, -1, 0, 9, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 15, 0, 0, 0, -1, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 15, 0, 0, 0, -1, 0, 7, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 26, 0, 0, 0, -1, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 26, 10, 0, 0, -1, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 14, 0, 0, 0, -1, 0, 9, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 15, 0, 0, 0, -1, 0, 9, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 6, 2 },
+ { 3, 2, 0, 0, 0, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 1, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 2, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 3, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 4, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 5, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 6, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 7, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 8, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 3, 2, 0, 0, 9, 0, 5, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 2 },
+ { 29, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 131 },
+ { 0, 17, 0, 5, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 131 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 0, 131 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 17, 12, 131 },
+ { 25, 0, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 131 },
+ { 0, 17, 230, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 57 },
+ { 18, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 113 },
+ { 5, 1, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 113 },
+ { 0, 17, 220, 5, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 113 },
+ { 14, 1, 0, 2, -1, 0, 18, 0, { {0, 34}, {0, 0}, {0, 0}, {0, 34} }, 0, 10, 12, 7, 132 },
+ { 15, 1, 0, 2, -1, 0, 18, 0, { {0, 0}, {0, -34}, {0, -34}, {0, 0} }, 0, 10, 12, 6, 132 },
+ { 0, 17, 230, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 132 },
+ { 0, 17, 7, 5, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 132 },
+ { 3, 1, 0, 0, 0, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 2, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 3, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 4, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 5, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 6, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 7, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 8, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 3, 1, 0, 0, 9, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 16, 11, 9, 132 },
+ { 25, 1, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 0, 0, 132 },
+ { 18, 13, 0, 0, -1, 0, 13, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 8, 8 },
+ { 26, 10, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 8 },
+ { 5, 2, 0, 0, 0, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 1, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 2, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 3, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 4, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 5, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 6, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 7, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 8, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 2, 0, 0, 9, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 5, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 12, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 29, 0, 0, 0, -1, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 29, 0, 0, 0, -1, 0, 12, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 29, 0, 0, 0, -1, 0, 11, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 10, 12, 7, 2 },
+ { 29, 10, 0, 0, -1, 0, 13, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 6, 7, 28, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 11, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 34 },
+ { 29, 0, 0, 0, -1, 0, 12, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 0, 0, 0, -1, 0, 18, 80, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 16, 20, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 28, 10, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 15, 19, 31, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 17, 21, 30, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 18, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 16, 20, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 13, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 3, 13, 2 },
+ { 29, 10, 0, 0, -1, 0, 16, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 5, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 17, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 29, 10, 0, 0, -1, 0, 19, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 14, 18, 30, 0, 2 },
+ { 13, 18, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 },
+ { 18, 0, 0, 0, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 12, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 18, 0, 0, 0, -1, 0, 5, 85, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 14, 8, 37 },
+ { 10, 18, 0, 5, -1, 0, 5, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 2 },
+ { 0, 17, 0, 5, -1, 0, 7, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 4, 4, 21, 4, 1 },
+ { 12, 0, 0, 0, -1, 0, 2, 0, { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, 0, 0, 12, 0, 0 }
};
Q_DECL_CONST_FUNCTION static inline const Properties *qGetProp(uint ucs4) noexcept
diff --git a/src/corelib/text/qunicodetables_p.h b/src/corelib/text/qunicodetables_p.h
index cb7a211cb6..c453ef53e7 100644
--- a/src/corelib/text/qunicodetables_p.h
+++ b/src/corelib/text/qunicodetables_p.h
@@ -63,6 +63,15 @@ QT_BEGIN_NAMESPACE
namespace QUnicodeTables {
+enum Case {
+ LowerCase,
+ UpperCase,
+ TitleCase,
+ CaseFold,
+
+ NumCases
+};
+
struct Properties {
ushort category : 8; /* 5 used */
ushort direction : 8; /* 5 used */
@@ -70,63 +79,29 @@ struct Properties {
ushort joining : 3;
signed short digitValue : 5;
signed short mirrorDiff : 16;
- ushort lowerCaseSpecial : 1;
- signed short lowerCaseDiff : 15;
+ ushort unicodeVersion : 8; /* 5 used */
+ ushort nfQuickCheck : 8;
#ifdef Q_OS_WASM
unsigned char : 0; //wasm 64 packing trick
#endif
- ushort upperCaseSpecial : 1;
- signed short upperCaseDiff : 15;
- ushort titleCaseSpecial : 1;
- signed short titleCaseDiff : 15;
- ushort caseFoldSpecial : 1;
- signed short caseFoldDiff : 15;
- ushort unicodeVersion : 8; /* 5 used */
- ushort nfQuickCheck : 8;
+ struct {
+ ushort special : 1;
+ signed short diff : 15;
+ } cases[NumCases];
#ifdef Q_OS_WASM
unsigned char : 0; //wasm 64 packing trick
#endif
ushort graphemeBreakClass : 5; /* 5 used */
ushort wordBreakClass : 5; /* 5 used */
- ushort sentenceBreakClass : 8; /* 4 used */
ushort lineBreakClass : 6; /* 6 used */
+ ushort sentenceBreakClass : 8; /* 4 used */
ushort script : 8;
};
Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4) noexcept;
Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2) noexcept;
-struct LowercaseTraits
-{
- static inline signed short caseDiff(const Properties *prop)
- { return prop->lowerCaseDiff; }
- static inline bool caseSpecial(const Properties *prop)
- { return prop->lowerCaseSpecial; }
-};
-
-struct UppercaseTraits
-{
- static inline signed short caseDiff(const Properties *prop)
- { return prop->upperCaseDiff; }
- static inline bool caseSpecial(const Properties *prop)
- { return prop->upperCaseSpecial; }
-};
-
-struct TitlecaseTraits
-{
- static inline signed short caseDiff(const Properties *prop)
- { return prop->titleCaseDiff; }
- static inline bool caseSpecial(const Properties *prop)
- { return prop->titleCaseSpecial; }
-};
-
-struct CasefoldTraits
-{
- static inline signed short caseDiff(const Properties *prop)
- { return prop->caseFoldDiff; }
- static inline bool caseSpecial(const Properties *prop)
- { return prop->caseFoldSpecial; }
-};
+Q_STATIC_ASSERT(sizeof(Properties) == 20);
enum GraphemeBreakClass {
GraphemeBreak_Any,
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index dc976819ef..9804e60119 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -99,8 +99,10 @@ public:
typename Ops::Type _q_value;
// Everything below is either implemented in ../arch/qatomic_XXX.h or (as fallback) in qgenericatomic.h
- T load() const noexcept { return loadRelaxed(); }
- void store(T newValue) noexcept { storeRelaxed(newValue); }
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") T load() const noexcept { return loadRelaxed(); }
+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(T newValue) noexcept { storeRelaxed(newValue); }
+#endif
T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
@@ -238,8 +240,10 @@ public:
AtomicType _q_value;
- Type load() const noexcept { return loadRelaxed(); }
- void store(Type newValue) noexcept { storeRelaxed(newValue); }
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") Type load() const noexcept { return loadRelaxed(); }
+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(Type newValue) noexcept { storeRelaxed(newValue); }
+#endif
Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index 6430f38a3b..1303be10b1 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -424,12 +424,7 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue,
}
}
-QMutex *QFutureInterfaceBase::mutex() const
-{
- return &d->m_mutex;
-}
-
-QMutex &QFutureInterfaceBase::mutex(int) const
+QMutex &QFutureInterfaceBase::mutex() const
{
return d->m_mutex;
}
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index bcdae24833..43dfd6bac4 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -119,8 +119,7 @@ public:
void waitForResult(int resultIndex);
void waitForResume();
- QMutex *mutex() const;
- QMutex &mutex(int) const;
+ QMutex &mutex() const;
QtPrivate::ExceptionStore &exceptionStore();
QtPrivate::ResultStoreBase &resultStoreBase();
const QtPrivate::ResultStoreBase &resultStoreBase() const;
@@ -191,7 +190,7 @@ public:
template <typename T>
inline void QFutureInterface<T>::reportResult(const T *result, int index)
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
if (this->queryState(Canceled) || this->queryState(Finished)) {
return;
}
@@ -217,7 +216,7 @@ inline void QFutureInterface<T>::reportResult(const T &result, int index)
template <typename T>
inline void QFutureInterface<T>::reportResults(const QVector<T> &_results, int beginIndex, int count)
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
if (this->queryState(Canceled) || this->queryState(Finished)) {
return;
}
@@ -245,14 +244,14 @@ inline void QFutureInterface<T>::reportFinished(const T *result)
template <typename T>
inline const T &QFutureInterface<T>::resultReference(int index) const
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
return resultStoreBase().resultAt(index).template value<T>();
}
template <typename T>
inline const T *QFutureInterface<T>::resultPointer(int index) const
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
return resultStoreBase().resultAt(index).template pointer<T>();
}
@@ -266,7 +265,7 @@ inline QList<T> QFutureInterface<T>::results()
QFutureInterfaceBase::waitForResult(-1);
QList<T> res;
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
QtPrivate::ResultIteratorBase it = resultStoreBase().begin();
while (it != resultStoreBase().end()) {
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 30e9b95a52..14654986a0 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -48,6 +48,7 @@
#include "qreadwritelock_p.h"
#include "qelapsedtimer.h"
#include "private/qfreelist_p.h"
+#include "private/qlocking_p.h"
QT_BEGIN_NAMESPACE
@@ -262,7 +263,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
if (d->recursive)
return d->recursiveLockForRead(timeout);
- QMutexLocker lock(&d->mutex);
+ auto lock = qt_unique_lock(d->mutex);
if (d != d_ptr.loadRelaxed()) {
// d_ptr has changed: this QReadWriteLock was unlocked before we had
// time to lock d->mutex.
@@ -369,7 +370,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
if (d->recursive)
return d->recursiveLockForWrite(timeout);
- QMutexLocker lock(&d->mutex);
+ auto lock = qt_unique_lock(d->mutex);
if (d != d_ptr.loadRelaxed()) {
// The mutex was unlocked before we had time to lock the mutex.
// We are holding to a mutex within a QReadWriteLockPrivate that is already released
@@ -418,7 +419,7 @@ void QReadWriteLock::unlock()
return;
}
- QMutexLocker locker(&d->mutex);
+ const auto lock = qt_scoped_lock(d->mutex);
if (d->writerCount) {
Q_ASSERT(d->writerCount == 1);
Q_ASSERT(d->readerCount == 0);
@@ -536,7 +537,7 @@ void QReadWriteLockPrivate::unlock()
bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
{
Q_ASSERT(recursive);
- QMutexLocker lock(&mutex);
+ auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId();
@@ -556,7 +557,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
{
Q_ASSERT(recursive);
- QMutexLocker lock(&mutex);
+ auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId();
if (currentWriter == self) {
@@ -574,7 +575,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
void QReadWriteLockPrivate::recursiveUnlock()
{
Q_ASSERT(recursive);
- QMutexLocker lock(&mutex);
+ auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId();
if (self == currentWriter) {
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 31da2401c0..a4d002b7f2 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -63,17 +63,16 @@ QT_BEGIN_NAMESPACE
class QReadWriteLockPrivate
{
public:
- QReadWriteLockPrivate(bool isRecursive = false)
- : readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0),
- recursive(isRecursive), id(0), currentWriter(nullptr) {}
+ explicit QReadWriteLockPrivate(bool isRecursive = false)
+ : recursive(isRecursive) {}
QMutex mutex;
QWaitCondition writerCond;
QWaitCondition readerCond;
- int readerCount;
- int writerCount;
- int waitingReaders;
- int waitingWriters;
+ int readerCount = 0;
+ int writerCount = 0;
+ int waitingReaders = 0;
+ int waitingWriters = 0;
const bool recursive;
//Called with the mutex locked
@@ -82,19 +81,18 @@ public:
void unlock();
//memory management
- int id;
+ int id = 0;
void release();
static QReadWriteLockPrivate *allocate();
// Recusive mutex handling
- Qt::HANDLE currentWriter;
+ Qt::HANDLE currentWriter = {};
QHash<Qt::HANDLE, int> currentReaders;
// called with the mutex unlocked
bool recursiveLockForWrite(int timeout);
bool recursiveLockForRead(int timeout);
void recursiveUnlock();
-
};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qsemaphore.h b/src/corelib/thread/qsemaphore.h
index 58c12997ad..b3b9b52052 100644
--- a/src/corelib/thread/qsemaphore.h
+++ b/src/corelib/thread/qsemaphore.h
@@ -80,8 +80,7 @@ public:
explicit QSemaphoreReleaser(QSemaphore *sem, int n = 1) noexcept
: m_sem(sem), m_n(n) {}
QSemaphoreReleaser(QSemaphoreReleaser &&other) noexcept
- : m_sem(other.m_sem), m_n(other.m_n)
- { other.m_sem = nullptr; }
+ : m_sem(other.cancel()), m_n(other.m_n) {}
QSemaphoreReleaser &operator=(QSemaphoreReleaser &&other) noexcept
{ QSemaphoreReleaser moved(std::move(other)); swap(moved); return *this; }
@@ -102,9 +101,7 @@ public:
QSemaphore *cancel() noexcept
{
- QSemaphore *old = m_sem;
- m_sem = nullptr;
- return old;
+ return qExchange(m_sem, nullptr);
}
private:
diff --git a/src/corelib/thread/qwaitcondition_p.h b/src/corelib/thread/qwaitcondition_p.h
new file mode 100644
index 0000000000..5133e52e92
--- /dev/null
+++ b/src/corelib/thread/qwaitcondition_p.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QWAITCONDITION_P_H
+#define QWAITCONDITION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qmutex.cpp, qmutex_unix.cpp, and qmutex_win.cpp. This header
+// file may change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QWaitCondition>
+#include <QtCore/QMutex>
+#include <QtCore/QDeadlineTimer>
+
+#include <condition_variable>
+#include <mutex>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtPrivate
+{
+
+#if defined(Q_OS_INTEGRITY)
+
+class condition_variable;
+
+class mutex : private QMutex
+{
+ friend class QtPrivate::condition_variable;
+public:
+ // all special member functions are ok!
+ // do not expose the (QMutex::Recursive) ctor
+ // don't use 'using QMutex::lock;' etc as those have the wrong noexcept
+
+ void lock() { return QMutex::lock(); }
+ void unlock() { return QMutex::unlock(); }
+ bool try_lock() { return QMutex::tryLock(); }
+};
+
+class condition_variable : private QWaitCondition
+{
+public:
+ // all special member functions are ok!
+
+ void notify_one() { QWaitCondition::wakeOne(); }
+ void notify_all() { QWaitCondition::wakeAll(); }
+
+ void wait(std::unique_lock<QtPrivate::mutex> &lock) { QWaitCondition::wait(lock.mutex()); }
+ template <class Predicate>
+ void wait(std::unique_lock<QtPrivate::mutex> &lock, Predicate p)
+ {
+ while (!p())
+ wait(lock);
+ }
+
+ template <typename Rep, typename Period>
+ std::cv_status wait_for(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::duration<Rep, Period> &d)
+ {
+ return QWaitCondition::wait(lock.mutex(), QDeadlineTimer{d})
+ ? std::cv_status::no_timeout
+ : std::cv_status::timeout;
+ }
+ template <typename Rep, typename Period, typename Predicate>
+ bool wait_for(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::duration<Rep, Period> &d, Predicate p)
+ {
+ const auto timer = QDeadlineTimer{d};
+ while (!p()) {
+ if (!QWaitCondition::wait(lock.mutex(), timer))
+ return p();
+ }
+ return true;
+ }
+
+ template <typename Clock, typename Duration>
+ std::cv_status wait_until(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::time_point<Clock, Duration> &t)
+ {
+ return QWaitCondition::wait(lock.mutex(), QDeadlineTimer{t})
+ ? std::cv_status::no_timeout
+ : std::cv_status::timeout;
+ }
+
+ template <typename Clock, typename Duration, typename Predicate>
+ bool wait_until(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::time_point<Clock, Duration> &t, Predicate p)
+ {
+ const auto timer = QDeadlineTimer{t};
+ while (!p()) {
+ if (!QWaitCondition::wait(lock.mutex(), timer))
+ return p();
+ }
+ return true;
+ }
+
+};
+
+#else // Integrity
+
+using mutex = std::mutex;
+using condition_variable = std::condition_variable;
+
+#endif // Integrity
+
+} // namespace QtPrivate
+
+QT_END_NAMESPACE
+
+#endif /* QWAITCONDITION_P_H */
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index 9fc9af0e65..25cf68a324 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -6,6 +6,7 @@ HEADERS += \
thread/qrunnable.h \
thread/qthread.h \
thread/qthreadstorage.h \
+ thread/qwaitcondition_p.h \
thread/qwaitcondition.h
SOURCES += \
diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp
index b569a6834c..d308aeba2b 100644
--- a/src/corelib/time/qcalendar.cpp
+++ b/src/corelib/time/qcalendar.cpp
@@ -136,6 +136,7 @@ Q_GLOBAL_STATIC(Registry, calendarRegistry);
\class QCalendarBackend
\inmodule QtCore
+ \internal
\reentrant
\brief The QCalendarBackend class provides basic calendaring functions.
@@ -167,7 +168,7 @@ Q_GLOBAL_STATIC(Registry, calendarRegistry);
*/
/*!
- Constructs the calendar and registers it.
+ Constructs the calendar and registers it under \a name using \a id.
*/
QCalendarBackend::QCalendarBackend(const QString &name, QCalendar::System id)
{
@@ -192,7 +193,7 @@ QCalendarBackend::~QCalendarBackend()
return the member of that enum that produces it. Other calendars should
return User.
- \sa QCalendar::fromEnum()
+ \sa QCalendarBackend::fromEnum()
*/
QCalendar::System QCalendarBackend::calendarSystem() const
{
@@ -200,7 +201,7 @@ QCalendar::System QCalendarBackend::calendarSystem() const
}
/*!
- The primary name of this calendar.
+ The primary name of this calendar.
*/
QString QCalendar::name() const
{
@@ -220,10 +221,10 @@ QString QCalendar::name() const
Calendars with intercallary days may represent these as extra days of the
preceding month, or as short months separate from the usual ones. In the
former case, daysInMonth(month, year) should be the number of ordinary days
- in the month, although \c{isDateValid(year, month, day)} might return \c true for
- some larger values of \c day.
+ in the month, although \c{isDateValid(year, month, day)} might return \c true
+ for some larger values of \c day.
- \sa daysInYear(), monthsInYear(), minDaysInMonth(), maxDaysInMonth()
+ \sa daysInYear(), monthsInYear(), minimumDaysInMonth(), maximumDaysInMonth()
*/
// properties of the calendar
@@ -295,7 +296,7 @@ int QCalendarBackend::daysInYear(int year) const
This base implementation returns 12 for any valid year.
- \sa daysInYear(), maxMonthsInYear(), isDateValid()
+ \sa daysInYear(), maximumMonthsInYear(), isDateValid()
*/
int QCalendarBackend::monthsInYear(int year) const
{
@@ -353,13 +354,14 @@ bool QCalendarBackend::hasYearZero() const
This base implementation returns 31, as this is a common case.
For calendars with intercallary days, although daysInMonth() doesn't include
- the intercallary days in its count for an individual month, maxDaysInMonth()
- should include intercallary days, so that it is the maximum value of \c day
- for which \c{isDateValid(year, month, day)} can be true.
+ the intercallary days in its count for an individual month,
+ maximumDaysInMonth() should include intercallary days, so that it is the
+ maximum value of \c day for which \c{isDateValid(year, month, day)} can be
+ true.
- \sa maxMonthsInYear(), daysInMonth()
+ \sa maximumMonthsInYear(), daysInMonth()
*/
-int QCalendarBackend::maxDaysInMonth() const
+int QCalendarBackend::maximumDaysInMonth() const
{
return 31;
}
@@ -369,9 +371,9 @@ int QCalendarBackend::maxDaysInMonth() const
This base implementation returns 29, as this is a common case.
- \sa maxMonthsInYear(), daysInMonth()
+ \sa maximumMonthsInYear(), daysInMonth()
*/
-int QCalendarBackend::minDaysInMonth() const
+int QCalendarBackend::minimumDaysInMonth() const
{
return 29;
}
@@ -381,9 +383,9 @@ int QCalendarBackend::minDaysInMonth() const
This base implementation returns 12, as this is a common case.
- \sa maxDaysInMonth(), monthsInYear()
+ \sa maximumDaysInMonth(), monthsInYear()
*/
-int QCalendarBackend::maxMonthsInYear() const
+int QCalendarBackend::maximumMonthsInYear() const
{
return 12;
}
@@ -391,7 +393,7 @@ int QCalendarBackend::maxMonthsInYear() const
// Julian day number calculations
/*!
- \fn bool dateToJulianDay(int year, int month, int day, qint64 *jd) const
+ \fn bool QCalendarBackend::dateToJulianDay(int year, int month, int day, qint64 *jd) const
Computes the Julian day number corresponding to the specified \a year, \a
month, and \a day. Returns true and sets \a jd if there is such a date in
@@ -401,7 +403,7 @@ int QCalendarBackend::maxMonthsInYear() const
*/
/*!
- \fn QCalendar::YearMonthDay julianDayToDate(qint64 jd) const
+ \fn QCalendar::YearMonthDay QCalendarBackend::julianDayToDate(qint64 jd) const
Computes the year, month, and day in this calendar for the given Julian day
number \a jd. If the given day falls outside this calendar's scope
@@ -413,7 +415,7 @@ int QCalendarBackend::maxMonthsInYear() const
*/
/*!
- Returns the day of the week for a given Julian Day Number.
+ Returns the day of the week for the given Julian Day Number \a jd.
This is 1 for Monday through 7 for Sunday.
@@ -438,101 +440,104 @@ int QCalendarBackend::dayOfWeek(qint64 jd) const
// Month and week-day name look-ups (implemented in qlocale.cpp):
/*!
- \fn QString QCalendarBackend::monthName(const QLocale &locale, int month, int year,
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::monthName(const QLocale &locale, int month, int year,
+ QLocale::FormatType format) const
- Returns the name of the specified \a month in the given \a year for the chosen
- \a locale, using the given \a format to determine how complete the name is.
+ Returns the name of the specified \a month in the given \a year for the
+ chosen \a locale, using the given \a format to determine how complete the
+ name is.
- If \a year is Unspecified, return the name for the month that usually has this
- number within a typical year. Calendars with a leap month that isn't always
- the last may need to take account of the year to map the month number to the
- particular year's month with that number.
+ If \a year is Unspecified, return the name for the month that usually has
+ this number within a typical year. Calendars with a leap month that isn't
+ always the last may need to take account of the year to map the month number
+ to the particular year's month with that number.
- \note Backends for which CLDR provides data can configure the default
- implementation of the two month name look-up methods by arranging for
- localeMonthIndexData() and localeMonthData() to provide access to the CLDR
- data (see cldr2qlocalexml.py, qlocalexml2cpp.py and existing backends).
- Conversely, backends that override both month name look-up methods need not
- return anything meaningful from localeMonthIndexData() or localeMonthData().
+ \note Backends for which CLDR provides data can configure the default
+ implementation of the two month name look-up methods by arranging for
+ localeMonthIndexData() and localeMonthData() to provide access to the CLDR
+ data (see cldr2qlocalexml.py, qlocalexml2cpp.py and existing backends).
+ Conversely, backends that override both month name look-up methods need not
+ return anything meaningful from localeMonthIndexData() or localeMonthData().
- \sa standaloneMonthName(), QLocale::monthName()
+ \sa standaloneMonthName(), QLocale::monthName()
*/
/*!
- \fn QString QCalendarBackend::standaloneMonthName(const QLocale &locale, int month, int year
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::standaloneMonthName(const QLocale &locale, int month, int year
+ QLocale::FormatType format) const
- Returns the standalone name of the specified \a month in the chosen \a locale,
- using the specified \a format to determine how complete the name is.
+ Returns the standalone name of the specified \a month in the chosen \a
+ locale, using the specified \a format to determine how complete the name is.
- If \a year is Unspecified, return the standalone name for the month that
- usually has this number within a typical year. Calendars with a leap month
- that isn't always the last may need to take account of the year to map the
- month number to the particular year's month with that number.
+ If \a year is Unspecified, return the standalone name for the month that
+ usually has this number within a typical year. Calendars with a leap month
+ that isn't always the last may need to take account of the year to map the
+ month number to the particular year's month with that number.
- \sa monthName(), QLocale::standaloneMonthName()
+ \sa monthName(), QLocale::standaloneMonthName()
*/
/*!
- \fn QString QCalendarBackend::weekDayName(const QLocale &locale, int day,
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::weekDayName(const QLocale &locale, int day,
+ QLocale::FormatType format) const
- Returns the name of the specified \a day of the week in the chosen \a locale,
- using the specified \a format to determine how complete the name is.
+ Returns the name of the specified \a day of the week in the chosen \a
+ locale, using the specified \a format to determine how complete the name is.
- The base implementation handles \a day values from 1 to 7 using the day names
- CLDR provides, which are suitable for calendards that use the same
- (Hebrew-derived) week as the Gregorian calendar.
+ The base implementation handles \a day values from 1 to 7 using the day
+ names CLDR provides, which are suitable for calendards that use the same
+ (Hebrew-derived) week as the Gregorian calendar.
- Calendars whose dayOfWeek() returns a value outside the range from 1 to 7 need
- to reimplement this method to handle such extra week-day values. They can
- assume that \a day is a value returned by the same calendar's dayOfWeek().
+ Calendars whose dayOfWeek() returns a value outside the range from 1 to 7
+ need to reimplement this method to handle such extra week-day values. They
+ can assume that \a day is a value returned by the same calendar's
+ dayOfWeek().
- \sa dayOfWeek(), standaloneWeekDayName(), QLocale::dayName()
+ \sa dayOfWeek(), standaloneWeekDayName(), QLocale::dayName()
*/
/*!
- \fn QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
+ QLocale::FormatType format) const
- Returns the standalone name of the specified \a day of the week in the chosen
- \a locale, using the specified \a format to determine how complete the name
- is.
+ Returns the standalone name of the specified \a day of the week in the
+ chosen \a locale, using the specified \a format to determine how complete
+ the name is.
- The base implementation handles \a day values from 1 to 7 using the standalone
- day names CLDR provides, which are suitable for calendards that use the same
- (Hebrew-derived) week as the Gregorian calendar.
+ The base implementation handles \a day values from 1 to 7 using the
+ standalone day names CLDR provides, which are suitable for calendards that
+ use the same (Hebrew-derived) week as the Gregorian calendar.
- Calendars whose dayOfWeek() returns a value outside the range from 1 to 7 need
- to reimplement this method to handle such extra week-day values. They can
- assume that \a day is a value returned by the same calendar's dayOfWeek().
+ Calendars whose dayOfWeek() returns a value outside the range from 1 to 7
+ need to reimplement this method to handle such extra week-day values. They
+ can assume that \a day is a value returned by the same calendar's
+ dayOfWeek().
- \sa dayOfWeek(), weekDayName(), QLocale::standaloneDayName()
+ \sa dayOfWeek(), weekDayName(), QLocale::standaloneDayName()
*/
/*!
- \fn QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &datetime,
- const QDate &dateOnly, const QTime &timeOnly,
- const QLocale &locale) const
-
- Returns a string representing a given date, time or date-time.
-
- If \a datetime is specified and valid, it is used and both date and time
- format tokens are converted to appropriate representations of the parts of the
- datetime. Otherwise, if \a dateOnly is valid, only date format tokens are
- converted; else, if \a timeOnly is valid, only time format tokens are
- converted. If none are valid, an empty string is returned.
-
- The specified \a locale influences how some format tokens are converted; for
- example, when substituting day and month names and their short-forms. For the
- supported formatting tokens, see QDate::toString() and QTime::toString(). As
- described above, the provided date, time and date-time determine which of
- these tokens are recognized: where these appear in \a format they are replaced
- by data. Any text in \a format not recognized as a format token is copied
- verbatim into the result string.
-
- \sa QDate::toString(), QTime::toString(), QDateTime::toString()
+ \fn QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
+ const QLocale &locale) const
+
+ Returns a string representing a given date, time or date-time.
+
+ If \a datetime is specified and valid, it is used and both date and time
+ format tokens are converted to appropriate representations of the parts of
+ the datetime. Otherwise, if \a dateOnly is valid, only date format tokens
+ are converted; else, if \a timeOnly is valid, only time format tokens are
+ converted. If none are valid, an empty string is returned.
+
+ The specified \a locale influences how some format tokens are converted; for
+ example, when substituting day and month names and their short-forms. For
+ the supported formatting tokens, see QDate::toString() and
+ QTime::toString(). As described above, the provided date, time and date-time
+ determine which of these tokens are recognized: where these appear in \a
+ format they are replaced by data. Any text in \a format not recognized as a
+ format token is copied verbatim into the result string.
+
+ \sa QDate::toString(), QTime::toString(), QDateTime::toString()
*/
// End of methods implemented in qlocale.cpp
@@ -541,7 +546,7 @@ int QCalendarBackend::dayOfWeek(qint64 jd) const
QCalendarBackend sub-class must be registered before being exposed to Date
and Time APIs.
- \sa registerCalendar(), fromName()
+ \sa registerAlias(), fromName()
*/
QStringList QCalendarBackend::availableCalendars()
{
@@ -569,16 +574,16 @@ bool QCalendarBackend::registerAlias(const QString &name)
}
/*!
- Returns a pointer to a named calendar backend.
+ Returns a pointer to a named calendar backend.
- If the given \a name is present in availableCalendars(), the backend matching
- it is returned; otherwise, \c nullptr is returned. Matching of names ignores
- case. Note that this won't provoke construction of a calendar backend, it will
- only return ones that have been instantiated (and not yet destroyed) by some
- other means. However, calendars available via the QCalendar::System enum are
- always registered when this is called.
+ If the given \a name is present in availableCalendars(), the backend
+ matching it is returned; otherwise, \c nullptr is returned. Matching of
+ names ignores case. Note that this won't provoke construction of a calendar
+ backend, it will only return ones that have been instantiated (and not yet
+ destroyed) by some other means. However, calendars available via the
+ QCalendar::System enum are always registered when this is called.
- \sa availableCalendars(), registerCalendar(), fromEnum()
+ \sa availableCalendars(), registerAlias(), fromEnum()
*/
const QCalendarBackend *QCalendarBackend::fromName(QStringView name)
{
@@ -590,7 +595,7 @@ const QCalendarBackend *QCalendarBackend::fromName(QStringView name)
}
/*!
- \overload
+ \overload
*/
const QCalendarBackend *QCalendarBackend::fromName(QLatin1String name)
{
@@ -602,11 +607,11 @@ const QCalendarBackend *QCalendarBackend::fromName(QLatin1String name)
}
/*!
- Returns a pointer to a calendar backend, specified by enum.
+ Returns a pointer to a calendar backend, specified by enum.
- This will instantiate the indicated calendar (which will enable fromName() to
- return it subsequently), but only for the Qt-supported calendars for which
- (where relevant) the appropriate feature has been enabled.
+ This will instantiate the indicated calendar (which will enable fromName()
+ to return it subsequently), but only for the Qt-supported calendars for
+ which (where relevant) the appropriate feature has been enabled.
*/
const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
{
@@ -641,28 +646,29 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
}
/*!
- \since 5.14
-
- \class QCalendar
- \inmodule QtCore
- \reentrant
- \brief The QCalendar class describes calendar systems.
-
- A QCalendar object maps a year, month, and day-number to a specific day
- (ultimately identified by its Julian day number), using the rules of a
- particular system.
+ \since 5.14
- The default QCalendar() is a proleptic Gregorian calendar, which has no year
- zero. Other calendars may be supported by enabling suitable features or
- loading plugins. Calendars supported as features can be constructed by passing
- the QCalendar::System enumeration to the constructor. All supported calendars
- may be constructed by name, once they have been constructed. (Thus plugins
- instantiate their calendar backend to register it.) Built-in backends,
- accessible via QCalendar::System, are also always available by name.
+ \class QCalendar
+ \inmodule QtCore
+ \reentrant
+ \brief The QCalendar class describes calendar systems.
+
+ A QCalendar object maps a year, month, and day-number to a specific day
+ (ultimately identified by its Julian day number), using the rules of a
+ particular system.
+
+ The default QCalendar() is a proleptic Gregorian calendar, which has no year
+ zero. Other calendars may be supported by enabling suitable features or
+ loading plugins. Calendars supported as features can be constructed by
+ passing the QCalendar::System enumeration to the constructor. All supported
+ calendars may be constructed by name, once they have been constructed. (Thus
+ plugins instantiate their calendar backend to register it.) Built-in
+ backends, accessible via QCalendar::System, are also always available by
+ name.
- A QCalendar value is immutable.
+ A QCalendar value is immutable.
- \sa QCalendarBackend, QDate, QDateTime
+ \sa QDate, QDateTime
*/
/*!
@@ -675,25 +681,27 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
\value Milankovic A revised Julian calendar used by some Orthodox churches.
\value Jalali The Solar Hijri calendar (also called Persian).
\value IslamicCivil The (tabular) Islamic Civil calendar.
+ \omitvalue Last
+ \omitvalue User
\sa QCalendar
*/
/*!
- \fn QCalendar::QCalendar()
- \fn QCalendar::QCalendar(QCalendar::System system)
- \fn QCalendar::QCalendar(QLatin1String name)
- \fn QCalendar::QCalendar(QStringView name)
+ \fn QCalendar::QCalendar()
+ \fn QCalendar::QCalendar(QCalendar::System system)
+ \fn QCalendar::QCalendar(QLatin1String name)
+ \fn QCalendar::QCalendar(QStringView name)
- Constructs a calendar object.
+ Constructs a calendar object.
- The choice of calendar to use may be indicated as \a system, using the
- enumeration QCalendar::System, or by \a name, using a string (either Unicode
- or Latin 1). Construction by name may depend on an instance of the given
- calendar being constructed by other means first. With no argument, the default
- constructor returns the Gregorian calendar.
+ The choice of calendar to use may be indicated as \a system, using the
+ enumeration QCalendar::System, or by \a name, using a string (either Unicode
+ or Latin 1). Construction by name may depend on an instance of the given
+ calendar being constructed by other means first. With no argument, the
+ default constructor returns the Gregorian calendar.
- \sa QCalendar, System
+ \sa QCalendar, System, isValid()
*/
QCalendar::QCalendar()
@@ -715,15 +723,25 @@ QCalendar::QCalendar(QLatin1String name)
QCalendar::QCalendar(QStringView name)
: d(QCalendarBackend::fromName(name)) {}
+/*
+ \fn bool QCalendar::isValid() const
+
+ Returns true if this is a valid calendar object.
+
+ Constructing a calendar with an unrecognised calendar name may result in an
+ invalid object. Use this method to check after creating a calendar by name.
+*/
+
// Date queries:
/*!
- Returns the number of days in the given \a month of the given \a year.
+ Returns the number of days in the given \a month of the given \a year.
- Months are numbered consecutively, starting with 1 for the first month of each
- year.
+ Months are numbered consecutively, starting with 1 for the first month of
+ each year. If \a year is \c Unspecified (its default, if not passed), the
+ month's length in a normal year is returned.
- \sa maxDaysInMonth(), minDaysInMonth()
+ \sa maximumDaysInMonth(), minimumDaysInMonth()
*/
int QCalendar::daysInMonth(int month, int year) const
{
@@ -731,7 +749,7 @@ int QCalendar::daysInMonth(int month, int year) const
}
/*!
- Returns the number of days in the given \a year.
+ Returns the number of days in the given \a year.
*/
int QCalendar::daysInYear(int year) const
{
@@ -747,12 +765,12 @@ int QCalendar::monthsInYear(int year) const
}
/*!
- Returns \c true precisely if the given \a year, \a month, and \a day specify a
- valid date in this calendar.
+ Returns \c true precisely if the given \a year, \a month, and \a day specify
+ a valid date in this calendar.
- Usually this means 1 <= month <= monthsInYear(year) and 1 <= day <=
- daysInMonth(month, year). However, calendars with intercallary days or months
- may complicate that.
+ Usually this means 1 <= month <= monthsInYear(year) and 1 <= day <=
+ daysInMonth(month, year). However, calendars with intercallary days or
+ months may complicate that.
*/
bool QCalendar::isDateValid(int year, int month, int day) const
{
@@ -772,13 +790,13 @@ bool QCalendar::isGregorian() const
}
/*!
- Returns \c true if the given year is a leap year.
+ Returns \c true if the given \a year is a leap year.
- Since the year is not a whole number of days long, some years are longer than
- others. The difference may be a whole month or just a single day; the details
- vary between calendars.
+ Since the year is not a whole number of days long, some years are longer
+ than others. The difference may be a whole month or just a single day; the
+ details vary between calendars.
- \sa isDateValid()
+ \sa isDateValid()
*/
bool QCalendar::isLeapYear(int year) const
{
@@ -786,9 +804,9 @@ bool QCalendar::isLeapYear(int year) const
}
/*!
- Returns \c true if this calendar is a lunar calendar.
+ Returns \c true if this calendar is a lunar calendar.
- A lunar calendar is one based primarily on the phases of the moon.
+ A lunar calendar is one based primarily on the phases of the moon.
*/
bool QCalendar::isLunar() const
{
@@ -796,11 +814,11 @@ bool QCalendar::isLunar() const
}
/*!
- Returns \c true if this calendar is luni-solar.
+ Returns \c true if this calendar is luni-solar.
- A luni-solar calendar expresses the phases of the moon but adapts itself to
- also keep track of the Sun's varying position in the sky, relative to the
- fixed stars.
+ A luni-solar calendar expresses the phases of the moon but adapts itself to
+ also keep track of the Sun's varying position in the sky, relative to the
+ fixed stars.
*/
bool QCalendar::isLuniSolar() const
{
@@ -808,10 +826,10 @@ bool QCalendar::isLuniSolar() const
}
/*!
- Returns \c true if this calendar is solar.
+ Returns \c true if this calendar is solar.
- A solar calendar is based primarily on the Sun's varying position in the sky,
- relative to the fixed stars.
+ A solar calendar is based primarily on the Sun's varying position in the
+ sky, relative to the fixed stars.
*/
bool QCalendar::isSolar() const
{
@@ -819,13 +837,13 @@ bool QCalendar::isSolar() const
}
/*!
- Returns \c true if this calendar is proleptic.
+ Returns \c true if this calendar is proleptic.
- A proleptic calendar is able to describe years arbitrarily long before its
- first. These are represented by negative year numbers and possibly by a year
- zero.
+ A proleptic calendar is able to describe years arbitrarily long before its
+ first. These are represented by negative year numbers and possibly by a year
+ zero.
- \sa hasYearZero()
+ \sa hasYearZero()
*/
bool QCalendar::isProleptic() const
{
@@ -833,29 +851,29 @@ bool QCalendar::isProleptic() const
}
/*!
- Returns \c true if this calendar has a year zero.
-
- A non-proleptic calendar with no year zero represents years from its first
- year onwards but provides no way to describe years before its first; such a
- calendar has no year zero and is not proleptic.
-
- A calendar which represents years before its first may number these years
- simply by following the usual integer counting, so that the year before the
- first is year zero, with negative-numbered years preceding this; such a
- calendar is proleptic and has a year zero. A calendar might also have a year
- zero (for example, the year of some great event, with subsequent years being
- the first year after that event, the second year after, and so on) without
- describing years before its year zero. Such a calendar would have a year zero
- without being proleptic.
-
- Some calendars, however, represent years before their first by an alternate
- numbering; for example, the proleptic Gregorian calendar's first year is 1 CE
- and the year before it is 1 BCE, preceded by 2 BCE and so on. In this case,
- we use negative year numbers, with year -1 as the year before year 1, year -2
- as the year before year -1 and so on. Such a calendar is proleptic but has no
- year zero.
-
- \sa isProleptic()
+ Returns \c true if this calendar has a year zero.
+
+ A calendar may represent years from its first year onwards but provide no
+ way to describe years before its first; such a calendar has no year zero and
+ is not proleptic.
+
+ A calendar which represents years before its first may number these years
+ simply by following the usual integer counting, so that the year before the
+ first is year zero, with negative-numbered years preceding this; such a
+ calendar is proleptic and has a year zero. A calendar might also have a year
+ zero (for example, the year of some great event, with subsequent years being
+ the first year after that event, the second year after, and so on) without
+ describing years before its year zero. Such a calendar would have a year
+ zero without being proleptic.
+
+ Some calendars, however, represent years before their first by an alternate
+ numbering; for example, the proleptic Gregorian calendar's first year is 1
+ CE and the year before it is 1 BCE, preceded by 2 BCE and so on. In this
+ case, we use negative year numbers for this alternate numbering, with year
+ -1 as the year before year 1, year -2 as the year before year -1 and so
+ on. Such a calendar is proleptic but has no year zero.
+
+ \sa isProleptic()
*/
bool QCalendar::hasYearZero() const
{
@@ -863,40 +881,40 @@ bool QCalendar::hasYearZero() const
}
/*!
- Returns the number of days in the longest month in the calendar, in any year.
+ Returns the number of days in the longest month in the calendar, in any year.
- \sa daysInMonth(), minDaysInMonth()
+ \sa daysInMonth(), minimumDaysInMonth()
*/
-int QCalendar::maxDaysInMonth() const
+int QCalendar::maximumDaysInMonth() const
{
- return d ? d->maxDaysInMonth() : 0;
+ return d ? d->maximumDaysInMonth() : 0;
}
/*!
- Returns the number of days in the shortest month in the calendar, in any year.
+ Returns the number of days in the shortest month in the calendar, in any year.
- \sa daysInMonth(), maxDaysInMonth()
+ \sa daysInMonth(), maximumDaysInMonth()
*/
-int QCalendar::minDaysInMonth() const
+int QCalendar::minimumDaysInMonth() const
{
- return d ? d->minDaysInMonth() : 0;
+ return d ? d->minimumDaysInMonth() : 0;
}
/*!
- Returns the largest number of months that any year may contain.
+ Returns the largest number of months that any year may contain.
- \sa monthName(), standaloneMonthName(), monthsInYear()
+ \sa monthName(), standaloneMonthName(), monthsInYear()
*/
-int QCalendar::maxMonthsInYear() const
+int QCalendar::maximumMonthsInYear() const
{
- return d ? d->maxMonthsInYear() : 0;
+ return d ? d->maximumMonthsInYear() : 0;
}
// Julian Day conversions:
/*!
\fn QDate QCalendar::dateFromParts(int year, int month, int day) const
- \fn QDate QCalendar::dateFromParts(QCalendar::YearMonthDay parts) const
+ \fn QDate QCalendar::dateFromParts(const QCalendar::YearMonthDay &parts) const
Converts a year, month, and day to a QDate.
@@ -924,7 +942,7 @@ QDate QCalendar::dateFromParts(const QCalendar::YearMonthDay &parts) const
Converts a QDate to a year, month, and day of the month.
The returned structure's isValid() shall be false if the calendar is unable
- to represent the given \a date. Otherwise its \a year, \a month, and \a day
+ to represent the given \a date. Otherwise its year, month, and day
members record the so-named parts of its representation.
\sa dateFromParts(), isProleptic(), hasYearZero()
@@ -935,13 +953,13 @@ QCalendar::YearMonthDay QCalendar::partsFromDate(QDate date) const
}
/*!
- Returns the day of the week number for the given \a date.
+ Returns the day of the week number for the given \a date.
- Returns zero if the calendar is unable to represent the indicated date.
- Returns 1 for Monday through 7 for Sunday. Calendars with intercallary days
- may use other numbers to represent these.
+ Returns zero if the calendar is unable to represent the indicated date.
+ Returns 1 for Monday through 7 for Sunday. Calendars with intercallary days
+ may use other numbers to represent these.
- \sa partsFromDate(), Qt::DayOfWeek
+ \sa partsFromDate(), Qt::DayOfWeek
*/
int QCalendar::dayOfWeek(QDate date) const
{
@@ -951,28 +969,28 @@ int QCalendar::dayOfWeek(QDate date) const
// Locale data access
/*!
- Returns a suitably localised name for a month.
+ Returns a suitably localised name for a month.
- The month is indicated by a number, with \a month = 1 meaning the first month
- of the year and subsequent months numbered accordingly. Returns an empty
- string if the \a month number is unrecognized.
+ The month is indicated by a number, with \a month = 1 meaning the first
+ month of the year and subsequent months numbered accordingly. Returns an
+ empty string if the \a month number is unrecognized.
- The \a year may be Unspecified, in which case the mapping from numbers to
- names for a typical year's months should be used. Some calendars have leap
- months that aren't always at the end of the year; their mapping of month
- numbers to names may then depend on the placement of a leap month. Thus the
- year should normally be specified, if known.
+ The \a year may be Unspecified, in which case the mapping from numbers to
+ names for a typical year's months should be used. Some calendars have leap
+ months that aren't always at the end of the year; their mapping of month
+ numbers to names may then depend on the placement of a leap month. Thus the
+ year should normally be specified, if known.
- The name is returned in the form that would normally be used in a full date,
- in the specified \a locale; the \a format determines how fully it shall be
- expressed (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would normally be used in a full date,
+ in the specified \a locale; the \a format determines how fully it shall be
+ expressed (i.e. to what extent it is abbreviated).
- \sa standaloneMonthName(), maxMonthsInYear(), dateTimeString()
+ \sa standaloneMonthName(), maximumMonthsInYear(), dateTimeToString()
*/
QString QCalendar::monthName(const QLocale &locale, int month, int year,
QLocale::FormatType format) const
{
- const int maxMonth = year == Unspecified ? maxMonthsInYear() : monthsInYear(year);
+ const int maxMonth = year == Unspecified ? maximumMonthsInYear() : monthsInYear(year);
if (!d || month < 1 || month > maxMonth)
return QString();
@@ -980,28 +998,28 @@ QString QCalendar::monthName(const QLocale &locale, int month, int year,
}
/*!
- Returns a suitably localised standalone name for a month.
+ Returns a suitably localised standalone name for a month.
- The month is indicated by a number, with \a month = 1 meaning the first month
- of the year and subsequent months numbered accordingly. Returns an empty
- string if the \a month number is unrecognized.
+ The month is indicated by a number, with \a month = 1 meaning the first
+ month of the year and subsequent months numbered accordingly. Returns an
+ empty string if the \a month number is unrecognized.
- The \a year may be Unspecified, in which case the mapping from numbers to
- names for a typical year's months should be used. Some calendars have leap
- months that aren't always at the end of the year; their mapping of month
- numbers to names may then depend on the placement of a leap month. Thus the
- year should normally be specified, if known.
+ The \a year may be Unspecified, in which case the mapping from numbers to
+ names for a typical year's months should be used. Some calendars have leap
+ months that aren't always at the end of the year; their mapping of month
+ numbers to names may then depend on the placement of a leap month. Thus the
+ year should normally be specified, if known.
- The name is returned in the form that would be used in isolation in the
- specified \a locale; the \a format determines how fully it shall be expressed
- (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would be used in isolation in the
+ specified \a locale; the \a format determines how fully it shall be
+ expressed (i.e. to what extent it is abbreviated).
- \sa monthName(), maxMonthsInYear(), dateTimeString()
+ \sa monthName(), maximumMonthsInYear(), dateTimeToString()
*/
QString QCalendar::standaloneMonthName(const QLocale &locale, int month, int year,
QLocale::FormatType format) const
{
- const int maxMonth = year == Unspecified ? maxMonthsInYear() : monthsInYear(year);
+ const int maxMonth = year == Unspecified ? maximumMonthsInYear() : monthsInYear(year);
if (!d || month < 1 || month > maxMonth)
return QString();
@@ -1009,18 +1027,18 @@ QString QCalendar::standaloneMonthName(const QLocale &locale, int month, int yea
}
/*!
- Returns a suitably localised name for a day of the week.
+ Returns a suitably localised name for a day of the week.
- The days of the week are numbered from 1 for Monday through 7 for Sunday. Some
- calendars may support higher numbers for other days (e.g. intercallary days,
- that are not part of any week). Returns an empty string if the \a day number
- is unrecognized.
+ The days of the week are numbered from 1 for Monday through 7 for
+ Sunday. Some calendars may support higher numbers for other days
+ (e.g. intercallary days, that are not part of any week). Returns an empty
+ string if the \a day number is unrecognized.
- The name is returned in the form that would normally be used in a full date,
- in the specified \a locale; the \a format determines how fully it shall be
- expressed (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would normally be used in a full date,
+ in the specified \a locale; the \a format determines how fully it shall be
+ expressed (i.e. to what extent it is abbreviated).
- \sa standaloneWeekDayName(), dayOfWeek()
+ \sa standaloneWeekDayName(), dayOfWeek()
*/
QString QCalendar::weekDayName(const QLocale &locale, int day,
QLocale::FormatType format) const
@@ -1029,19 +1047,20 @@ QString QCalendar::weekDayName(const QLocale &locale, int day,
}
/*!
- Returns a suitably localised standalone name for a day of the week.
+ Returns a suitably localised standalone name for a day of the week.
- The days of the week are numbered from 1 for Monday through 7 for Sunday. Some
- calendars may support higher numbers for other days (e.g. intercallary days,
- that are not part of any week). Returns an empty string if the \a day number
- is unrecognized.
+ The days of the week are numbered from 1 for Monday through 7 for
+ Sunday. Some calendars may support higher numbers for other days
+ (e.g. intercallary days, that are not part of any week). Returns an empty
+ string if the \a day number is unrecognized.
- The name is returned in the form that would be used in isolation (for example
- as a column heading in a calendar's tabular display of a month with successive
- weeks as rows) in the specified \a locale; the \a format determines how fully
- it shall be expressed (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would be used in isolation (for
+ example as a column heading in a calendar's tabular display of a month with
+ successive weeks as rows) in the specified \a locale; the \a format
+ determines how fully it shall be expressed (i.e. to what extent it is
+ abbreviated).
- \sa weekDayName(), dayOfWeek()
+ \sa weekDayName(), dayOfWeek()
*/
QString QCalendar::standaloneWeekDayName(const QLocale &locale, int day,
QLocale::FormatType format) const
@@ -1050,23 +1069,23 @@ QString QCalendar::standaloneWeekDayName(const QLocale &locale, int day,
}
/*!
- Returns a string representing a given date, time or date-time.
-
- If \a datetime is valid, it is represented and format specifiers for both date
- and time fields are recognized; otherwise, if \a dateOnly is valid, it is
- represented and only format specifiers for date fields are recognized;
- finally, if \a timeOnly is valid, it is represented and only format specifiers
- for time fields are recognized. If none of these is valid, an empty string is
- returned.
-
- See QDate::toString and QTime::toString() for the supported field specifiers.
- Characters in \a format that are recognized as field specifiers are replaced
- by text representing appropriate data from the date and/or time being
- represented. The texts to represent them may depend on the \a locale
- specified. Other charagers in \a format are copied verbatim into the returned
- string.
-
- \sa monthName(), weekDayName(), QDate::toString(), QTime::toString()
+ Returns a string representing a given date, time or date-time.
+
+ If \a datetime is valid, it is represented and format specifiers for both
+ date and time fields are recognized; otherwise, if \a dateOnly is valid, it
+ is represented and only format specifiers for date fields are recognized;
+ finally, if \a timeOnly is valid, it is represented and only format
+ specifiers for time fields are recognized. If none of these is valid, an
+ empty string is returned.
+
+ See QDate::toString and QTime::toString() for the supported field
+ specifiers. Characters in \a format that are recognized as field specifiers
+ are replaced by text representing appropriate data from the date and/or time
+ being represented. The texts to represent them may depend on the \a locale
+ specified. Other charagers in \a format are copied verbatim into the
+ returned string.
+
+ \sa monthName(), weekDayName(), QDate::toString(), QTime::toString()
*/
QString QCalendar::dateTimeToString(QStringView format, const QDateTime &datetime,
const QDate &dateOnly, const QTime &timeOnly,
diff --git a/src/corelib/time/qcalendar.h b/src/corelib/time/qcalendar.h
index b117f4d6a9..42c8e150c5 100644
--- a/src/corelib/time/qcalendar.h
+++ b/src/corelib/time/qcalendar.h
@@ -128,7 +128,7 @@ public:
User = -1
};
// New entries must be added to the \enum doc in qcalendar.cpp and
- // handled in QCalendar::fromEnum()
+ // handled in QCalendarBackend::fromEnum()
Q_ENUM(System)
explicit QCalendar(); // Gregorian, optimised
@@ -137,7 +137,7 @@ public:
explicit QCalendar(QStringView name);
// QCalendar is a trivially copyable value type.
- bool isValid() { return d != nullptr; }
+ bool isValid() const { return d != nullptr; }
// Date queries:
int daysInMonth(int month, int year = Unspecified) const;
@@ -155,9 +155,9 @@ public:
bool isSolar() const;
bool isProleptic() const;
bool hasYearZero() const;
- int maxDaysInMonth() const;
- int minDaysInMonth() const;
- int maxMonthsInYear() const;
+ int maximumDaysInMonth() const;
+ int minimumDaysInMonth() const;
+ int maximumMonthsInYear() const;
QString name() const;
// QDate conversions:
diff --git a/src/corelib/time/qcalendarbackend_p.h b/src/corelib/time/qcalendarbackend_p.h
index 12db8928ca..21506e9e2c 100644
--- a/src/corelib/time/qcalendarbackend_p.h
+++ b/src/corelib/time/qcalendarbackend_p.h
@@ -95,9 +95,9 @@ public:
virtual bool isSolar() const = 0;
virtual bool isProleptic() const;
virtual bool hasYearZero() const;
- virtual int maxDaysInMonth() const;
- virtual int minDaysInMonth() const;
- virtual int maxMonthsInYear() const;
+ virtual int maximumDaysInMonth() const;
+ virtual int minimumDaysInMonth() const;
+ virtual int maximumMonthsInYear() const;
// Julian Day conversions:
virtual bool dateToJulianDay(int year, int month, int day, qint64 *jd) const = 0;
virtual QCalendar::YearMonthDay julianDayToDate(qint64 jd) const = 0;
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index a9fc47e053..95a7255a04 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -1465,7 +1465,7 @@ QDate QDate::addMonths(int nmonths, QCalendar cal) const
}
/*!
- \override
+ \overload
*/
QDate QDate::addMonths(int nmonths) const
@@ -1530,7 +1530,7 @@ QDate QDate::addYears(int nyears, QCalendar cal) const
}
/*!
- \override
+ \overload
*/
QDate QDate::addYears(int nyears) const
@@ -3432,15 +3432,15 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
datetime by adding a number of seconds, days, months, or years.
QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local
- time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset
- from UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction
- with the QTimeZone class. For example, a time zone of "Europe/Berlin" will
- apply the daylight-saving rules as used in Germany since 1970. In contrast,
- an offset from UTC of +3600 seconds is one hour ahead of UTC (usually
- written in ISO standard notation as "UTC+01:00"), with no daylight-saving
- offset or changes. When using either local time or a specified time zone,
- time-zone transitions such as the starts and ends of daylight-saving time
- (DST) are taken into account. The choice of system used to represent a
+ time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset from
+ UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction with the
+ QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the
+ daylight-saving rules as used in Germany since 1970. In contrast, an offset
+ from UTC of +3600 seconds is one hour ahead of UTC (usually written in ISO
+ standard notation as "UTC+01:00"), with no daylight-saving offset or
+ changes. When using either local time or a specified time zone, time-zone
+ transitions such as the starts and ends of daylight-saving time (DST; but
+ see below) are taken into account. The choice of system used to represent a
datetime is described as its "timespec".
A QDateTime object is typically created either by giving a date and time
@@ -3528,11 +3528,13 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
The range of valid dates taking DST into account is 1970-01-01 to the
present, and rules are in place for handling DST correctly until 2037-12-31,
- but these could change. For dates falling outside that range, QDateTime
- makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
- guarantee accuracy. This means QDateTime doesn't take into account changes
- in a time zone before 1970, even if the system's time zone database provides
- that information.
+ but these could change. For dates after 2037, QDateTime makes a \e{best
+ guess} using the rules for year 2037, but we can't guarantee accuracy;
+ indeed, for \e{any} future date, the time-zone may change its rules before
+ that date comes around. For dates before 1970, QDateTime doesn't take DST
+ changes into account, even if the system's time zone database provides that
+ information, although it does take into account changes to the time-zone's
+ standard offset, where this information is available.
\section2 Offsets From UTC
@@ -3546,6 +3548,7 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
*/
/*!
+ \since 5.14
\enum QDateTime::YearRange
This enumerated type describes the range of years (in the Gregorian
@@ -3797,17 +3800,22 @@ QTimeZone QDateTime::timeZone() const
/*!
\since 5.2
- Returns the current Offset From UTC in seconds.
+ Returns this date-time's Offset From UTC in seconds.
- If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set.
-
- If the timeSpec() is Qt::TimeZone this will be the offset effective in the
- Time Zone including any Daylight-Saving Offset.
-
- If the timeSpec() is Qt::LocalTime this will be the difference between the
- Local Time and UTC including any Daylight-Saving Offset.
+ The result depends on timeSpec():
+ \list
+ \li \c Qt::UTC The offset is 0.
+ \li \c Qt::OffsetFromUTC The offset is the value originally set.
+ \li \c Qt::LocalTime The local time's offset from UTC is returned.
+ \li \c Qt::TimeZone The offset used by the time-zone is returned.
+ \endlist
- If the timeSpec() is Qt::UTC this will be 0.
+ For the last two, the offset at this date and time will be returned, taking
+ account of Daylight-Saving Offset unless the date precedes the start of
+ 1970. The offset is the difference between the local time or time in the
+ given time-zone and UTC time; it is positive in time-zones ahead of UTC
+ (East of The Prime Meridian), negative for those behind UTC (West of The
+ Prime Meridian).
\sa setOffsetFromUtc()
*/
@@ -3853,6 +3861,9 @@ int QDateTime::offsetFromUtc() const
QString QDateTime::timeZoneAbbreviation() const
{
+ if (!isValid())
+ return QString();
+
switch (getSpec(d)) {
case Qt::UTC:
return QLatin1String("UTC");
@@ -3887,6 +3898,9 @@ QString QDateTime::timeZoneAbbreviation() const
bool QDateTime::isDaylightTime() const
{
+ if (!isValid())
+ return false;
+
switch (getSpec(d)) {
case Qt::UTC:
case Qt::OffsetFromUTC:
@@ -4753,17 +4767,24 @@ QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const
Returns \c true if this datetime is equal to the \a other datetime;
otherwise returns \c false.
+ Since 5.14, all invalid datetimes are equal to one another and differ from
+ all other datetimes.
+
\sa operator!=()
*/
bool QDateTime::operator==(const QDateTime &other) const
{
- if (getSpec(d) == Qt::LocalTime
- && getStatus(d) == getStatus(other.d)) {
+ if (!isValid())
+ return !other.isValid();
+ if (!other.isValid())
+ return false;
+
+ if (getSpec(d) == Qt::LocalTime && getStatus(d) == getStatus(other.d))
return getMSecs(d) == getMSecs(other.d);
- }
+
// Convert to UTC and compare
- return (toMSecsSinceEpoch() == other.toMSecsSinceEpoch());
+ return toMSecsSinceEpoch() == other.toMSecsSinceEpoch();
}
/*!
@@ -4772,8 +4793,9 @@ bool QDateTime::operator==(const QDateTime &other) const
Returns \c true if this datetime is different from the \a other
datetime; otherwise returns \c false.
- Two datetimes are different if either the date, the time, or the
- time zone components are different.
+ Two datetimes are different if either the date, the time, or the time zone
+ components are different. Since 5.14, any invalid datetime is less than all
+ valid datetimes.
\sa operator==()
*/
@@ -4785,12 +4807,16 @@ bool QDateTime::operator==(const QDateTime &other) const
bool QDateTime::operator<(const QDateTime &other) const
{
- if (getSpec(d) == Qt::LocalTime
- && getStatus(d) == getStatus(other.d)) {
+ if (!isValid())
+ return other.isValid();
+ if (!other.isValid())
+ return false;
+
+ if (getSpec(d) == Qt::LocalTime && getStatus(d) == getStatus(other.d))
return getMSecs(d) < getMSecs(other.d);
- }
+
// Convert to UTC and compare
- return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch());
+ return toMSecsSinceEpoch() < other.toMSecsSinceEpoch();
}
/*!
@@ -5841,7 +5867,7 @@ uint qHash(const QDateTime &key, uint seed)
// QDate/QTime/spec/offset because QDateTime::operator== converts both arguments
// to the same timezone. If we don't, qHash would return different hashes for
// two QDateTimes that are equivalent once converted to the same timezone.
- return qHash(key.toMSecsSinceEpoch(), seed);
+ return key.isValid() ? qHash(key.toMSecsSinceEpoch(), seed) : seed;
}
/*! \fn uint qHash(const QDate &key, uint seed = 0)
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index d0f34358b9..2c566e3584 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -223,21 +223,23 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
case TimeZoneSection: return QTimeZone::MaxUtcOffsetSecs;
#endif
case Hour24Section:
- case Hour12Section: return 23; // this is special-cased in
- // parseSection. We want it to be
- // 23 for the stepBy case.
+ case Hour12Section:
+ // This is special-cased in parseSection.
+ // We want it to be 23 for the stepBy case.
+ return 23;
case MinuteSection:
case SecondSection: return 59;
case MSecSection: return 999;
case YearSection2Digits:
- case YearSection: return 9999; // sectionMaxSize will prevent
- // people from typing in a larger
- // number in count == 2 sections.
- // stepBy() will work on real years anyway
- case MonthSection: return calendar.maxMonthsInYear();
+ case YearSection:
+ // sectionMaxSize will prevent people from typing in a larger number in
+ // count == 2 sections; stepBy() will work on real years anyway.
+ return 9999;
+ case MonthSection: return calendar.maximumMonthsInYear();
case DaySection:
case DayOfWeekSectionShort:
- case DayOfWeekSectionLong: return cur.isValid() ? cur.date().daysInMonth(calendar) : calendar.maxDaysInMonth() ;
+ case DayOfWeekSectionLong:
+ return cur.isValid() ? cur.date().daysInMonth(calendar) : calendar.maximumDaysInMonth();
case AmPmSection: return 1;
default: break;
}
@@ -615,7 +617,7 @@ int QDateTimeParser::sectionSize(int sectionIndex) const
int QDateTimeParser::sectionMaxSize(Section s, int count) const
{
#if QT_CONFIG(textdate)
- int mcount = calendar.maxMonthsInYear();
+ int mcount = calendar.maximumMonthsInYear();
#endif
switch (s) {
@@ -1291,9 +1293,9 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
}
if (!calendar.isDateValid(year, month, day)) {
- if (day <= calendar.maxDaysInMonth())
+ if (day <= calendar.maximumDaysInMonth())
cachedDay = day;
- if (day > calendar.minDaysInMonth() && calendar.isDateValid(year, month, 1))
+ if (day > calendar.minimumDaysInMonth() && calendar.isDateValid(year, month, 1))
needfixday = true;
}
if (needfixday) {
diff --git a/src/corelib/time/qgregoriancalendar.cpp b/src/corelib/time/qgregoriancalendar.cpp
index 447185d124..633b1ea94e 100644
--- a/src/corelib/time/qgregoriancalendar.cpp
+++ b/src/corelib/time/qgregoriancalendar.cpp
@@ -57,7 +57,7 @@ using namespace QRoundingDown;
The Gregorian calendar is a refinement of the earlier Julian calendar,
itself a late form of the Roman calendar. It is widely used.
- \sa QRomanCalendar, QJulianCalendar, QCalendarBackend, QCalendar
+ \sa QRomanCalendar, QJulianCalendar, QCalendar
*/
QGregorianCalendar::QGregorianCalendar()
diff --git a/src/corelib/time/qhijricalendar.cpp b/src/corelib/time/qhijricalendar.cpp
index 1a1155be6d..b5d89fbc5c 100644
--- a/src/corelib/time/qhijricalendar.cpp
+++ b/src/corelib/time/qhijricalendar.cpp
@@ -44,36 +44,37 @@
QT_BEGIN_NAMESPACE
/*!
- \since 5.14
+ \since 5.14
+ \internal
- \class QHijriCalendar
- \inmodule QtCore
- \brief The QHijriCalendar class supports Islamic (Hijri) calendar implementations.
+ \class QHijriCalendar
+ \inmodule QtCore
+ \brief The QHijriCalendar class supports Islamic (Hijri) calendar implementations.
- \section1 Islamic Calendar System
+ \section1 Islamic Calendar System
- The Islamic, Muslim, or Hijri calendar is a lunar calendar consisting of 12
- months in a year of 354 or 355 days. It is used (often alongside the
- Gregorian calendar) to date events in many Muslim countries. It is also used
- by Muslims to determine the proper days of Islamic holidays and rituals,
- such as the annual period of fasting and the proper time for the pilgrimage
- to Mecca.
+ The Islamic, Muslim, or Hijri calendar is a lunar calendar consisting of 12
+ months in a year of 354 or 355 days. It is used (often alongside the
+ Gregorian calendar) to date events in many Muslim countries. It is also used
+ by Muslims to determine the proper days of Islamic holidays and rituals,
+ such as the annual period of fasting and the proper time for the pilgrimage
+ to Mecca.
- Source: \l {https://en.wikipedia.org/wiki/Islamic_calendar}{Wikipedia page on
- Hijri Calendar}
+ Source: \l {https://en.wikipedia.org/wiki/Islamic_calendar}{Wikipedia page
+ on Hijri Calendar}
- \section1 Support for variants
+ \section1 Support for variants
- This base class provides the common details shared by all variants on the
- Islamic calendar. Each year comprises 12 months of 29 or 30 days each; most
- years have as many of 29 as of 30, but leap years extend one 29-day month to
- 30 days. In tabular versions of the calendar (where mathematical rules are
- used to determine the details), odd-numbered months have 30 days, as does the
- last (twelfth) month of a leap year; all other months have 29 days. Other
- versions are based on actual astronomical observations of the moon's phase at
- sunset, which vary from place to place.
+ This base class provides the common details shared by all variants on the
+ Islamic calendar. Each year comprises 12 months of 29 or 30 days each; most
+ years have as many of 29 as of 30, but leap years extend one 29-day month to
+ 30 days. In tabular versions of the calendar (where mathematical rules are
+ used to determine the details), odd-numbered months have 30 days, as does
+ the last (twelfth) month of a leap year; all other months have 29
+ days. Other versions are based on actual astronomical observations of the
+ moon's phase at sunset, which vary from place to place.
- \sa QIslamicCivilCalendar, QCalendar
+ \sa QIslamicCivilCalendar, QCalendar
*/
bool QHijriCalendar::isLunar() const
@@ -102,7 +103,7 @@ int QHijriCalendar::daysInMonth(int month, int year) const
return month % 2 == 0 ? 29 : 30;
}
-int QHijriCalendar::maxDaysInMonth() const
+int QHijriCalendar::maximumDaysInMonth() const
{
return 30;
}
diff --git a/src/corelib/time/qhijricalendar_p.h b/src/corelib/time/qhijricalendar_p.h
index 8f15495d11..60820488b4 100644
--- a/src/corelib/time/qhijricalendar_p.h
+++ b/src/corelib/time/qhijricalendar_p.h
@@ -63,7 +63,7 @@ class Q_CORE_EXPORT QHijriCalendar : public QCalendarBackend
{
public:
int daysInMonth(int month, int year = QCalendar::Unspecified) const override;
- int maxDaysInMonth() const override;
+ int maximumDaysInMonth() const override;
int daysInYear(int year) const override;
bool isLunar() const override;
diff --git a/src/corelib/time/qislamiccivilcalendar.cpp b/src/corelib/time/qislamiccivilcalendar.cpp
index 27c93f5c00..a6a2afd207 100644
--- a/src/corelib/time/qislamiccivilcalendar.cpp
+++ b/src/corelib/time/qislamiccivilcalendar.cpp
@@ -47,27 +47,29 @@ QT_BEGIN_NAMESPACE
using namespace QRoundingDown;
/*!
- \since 5.14
+ \since 5.14
+ \internal
- \class QIslamicCivilCalendar
- \inmodule QtCore
- \brief Implements a commonly-used computed version of the Islamic calendar.
+ \class QIslamicCivilCalendar
+ \inmodule QtCore
+ \brief Implements a commonly-used computed version of the Islamic calendar.
- \section1 Civil Islamic Calendar
+ \section1 Civil Islamic Calendar
- QIslamicCivilCalendar implements a tabular version of the Hijri calendar which
- is known as the Islamic Civil Calendar. It has the same numbering of years and
- months, but the months are determined by arithmetical rules rather than by
- observation or astronomical calculations.
+ QIslamicCivilCalendar implements a tabular version of the Hijri calendar
+ which is known as the Islamic Civil Calendar. It has the same numbering of
+ years and months, but the months are determined by arithmetical rules rather
+ than by observation or astronomical calculations.
- \section2 Calendar Organization
+ \section2 Calendar Organization
- The civil calendar follows the usual tabular scheme of odd-numbered months and
- the last month of each leap year being 30 days long, the rest being 29 days
- long. Its determination of leap years follows a 30-year cycle, in each of
- which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap years.
+ The civil calendar follows the usual tabular scheme of odd-numbered months
+ and the last month of each leap year being 30 days long, the rest being 29
+ days long. Its determination of leap years follows a 30-year cycle, in each
+ of which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap
+ years.
- \sa QJijriCalendar, QCalendar
+ \sa QHijriCalendar, QCalendar
*/
QIslamicCivilCalendar::QIslamicCivilCalendar()
diff --git a/src/corelib/time/qromancalendar.cpp b/src/corelib/time/qromancalendar.cpp
index 81b8d93d43..c3cd134490 100644
--- a/src/corelib/time/qromancalendar.cpp
+++ b/src/corelib/time/qromancalendar.cpp
@@ -44,20 +44,20 @@
QT_BEGIN_NAMESPACE
/*!
- \since 5.14
+ \since 5.14
- \class QRomanCalendar
- \inmodule QtCore
- \brief The QRomanCalendar class is a shared base for calendars based on the
- ancient Roman calendar.
+ \class QRomanCalendar
+ \inmodule QtCore
+ \brief The QRomanCalendar class is a shared base for calendars based on the
+ ancient Roman calendar.
- \section1
+ \section1
- Calendars based on the ancient Roman calendar share the names of months, whose
- lengths depend in a common way on whether the year is a leap year. They differ
- in how they determine which years are leap years.
+ Calendars based on the ancient Roman calendar share the names of months,
+ whose lengths depend in a common way on whether the year is a leap
+ year. They differ in how they determine which years are leap years.
- \sa QGregorianCalendar, QJulianCalendar, QMilankovicCalendar
+ \sa QGregorianCalendar, QJulianCalendar, QMilankovicCalendar
*/
int QRomanCalendar::daysInMonth(int month, int year) const
@@ -72,7 +72,7 @@ int QRomanCalendar::daysInMonth(int month, int year) const
return 30 | ((month & 1) ^ (month >> 3));
}
-int QRomanCalendar::minDaysInMonth() const
+int QRomanCalendar::minimumDaysInMonth() const
{
return 28;
}
diff --git a/src/corelib/time/qromancalendar_p.h b/src/corelib/time/qromancalendar_p.h
index ea2f9d01f0..49efb3df89 100644
--- a/src/corelib/time/qromancalendar_p.h
+++ b/src/corelib/time/qromancalendar_p.h
@@ -60,7 +60,7 @@ class Q_CORE_EXPORT QRomanCalendar : public QCalendarBackend
public:
// date queries:
int daysInMonth(int month, int year = QCalendar::Unspecified) const override;
- int minDaysInMonth() const override;
+ int minimumDaysInMonth() const override;
// properties of the calendar
bool isLunar() const override;
bool isLuniSolar() const override;
diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp
index ef323de14a..410a16e3c5 100644
--- a/src/corelib/time/qtimezone.cpp
+++ b/src/corelib/time/qtimezone.cpp
@@ -325,20 +325,33 @@ QTimeZone::QTimeZone() noexcept
/*!
Creates an instance of the requested time zone \a ianaId.
- The ID must be one of the available system IDs otherwise an invalid
- time zone will be returned.
+ The ID must be one of the available system IDs or a valid UTC-with-offset
+ ID, otherwise an invalid time zone will be returned.
\sa availableTimeZoneIds()
*/
QTimeZone::QTimeZone(const QByteArray &ianaId)
{
- // Try and see if it's a valid UTC offset ID, just as quick to try create as look-up
+ // Try and see if it's a CLDR UTC offset ID - just as quick by creating as
+ // by looking up.
d = new QUtcTimeZonePrivate(ianaId);
- // If not a valid UTC offset ID then try create it with the system backend
- // Relies on backend not creating valid tz with invalid name
+ // If not a CLDR UTC offset ID then try creating it with the system backend.
+ // Relies on backend not creating valid TZ with invalid name.
if (!d->isValid())
d = newBackendTimeZone(ianaId);
+ // Can also handle UTC with arbitrary (valid) offset, but only do so as
+ // fall-back, since either of the above may handle it more informatively.
+ if (!d->isValid()) {
+ qint64 offset = QUtcTimeZonePrivate::offsetFromUtcString(ianaId);
+ if (offset != QTimeZonePrivate::invalidSeconds()) {
+ // Should have abs(offset) < 24 * 60 * 60 = 86400.
+ qint32 seconds = qint32(offset);
+ Q_ASSERT(qint64(seconds) == offset);
+ // NB: this canonicalises the name, so it might not match ianaId
+ d = new QUtcTimeZonePrivate(seconds);
+ }
+ }
}
/*!
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp
index 569b343187..72a0e3c24e 100644
--- a/src/corelib/time/qtimezoneprivate.cpp
+++ b/src/corelib/time/qtimezoneprivate.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2013 John Layt <jlayt@kde.org>
** Contact: https://www.qt.io/licensing/
**
@@ -761,6 +762,39 @@ QUtcTimeZonePrivate::QUtcTimeZonePrivate(const QByteArray &id)
}
}
+qint64 QUtcTimeZonePrivate::offsetFromUtcString(const QByteArray &id)
+{
+ // Convert reasonable UTC[+-]\d+(:\d+){,2} to offset in seconds.
+ // Assumption: id has already been tried as a CLDR UTC offset ID (notably
+ // including plain "UTC" itself) and a system offset ID; it's neither.
+ if (!id.startsWith("UTC") || id.size() < 5)
+ return invalidSeconds(); // Doesn't match
+ const char signChar = id.at(3);
+ if (signChar != '-' && signChar != '+')
+ return invalidSeconds(); // No sign
+ const int sign = signChar == '-' ? -1 : 1;
+
+ const auto offsets = id.mid(4).split(':');
+ if (offsets.isEmpty() || offsets.size() > 3)
+ return invalidSeconds(); // No numbers, or too many.
+
+ qint32 seconds = 0;
+ int prior = 0; // Number of fields parsed thus far
+ for (const auto &offset : offsets) {
+ bool ok = false;
+ unsigned short field = offset.toUShort(&ok);
+ // Bound hour above at 24, minutes and seconds at 60:
+ if (!ok || field >= (prior ? 60 : 24))
+ return invalidSeconds();
+ seconds = seconds * 60 + field;
+ ++prior;
+ }
+ while (prior++ < 3)
+ seconds *= 60;
+
+ return seconds * sign;
+}
+
// Create offset from UTC
QUtcTimeZonePrivate::QUtcTimeZonePrivate(qint32 offsetSeconds)
{
@@ -874,22 +908,25 @@ QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
bool QUtcTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
{
+ // Only the zone IDs supplied by CLDR and recognized by constructor.
for (int i = 0; i < utcDataTableSize; ++i) {
const QUtcData *data = utcData(i);
- if (utcId(data) == ianaId) {
+ if (utcId(data) == ianaId)
return true;
- }
}
+ // But see offsetFromUtcString(), which lets us accept some "unavailable" IDs.
return false;
}
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
{
+ // Only the zone IDs supplied by CLDR and recognized by constructor.
QList<QByteArray> result;
result.reserve(utcDataTableSize);
for (int i = 0; i < utcDataTableSize; ++i)
result << utcId(utcData(i));
- std::sort(result.begin(), result.end()); // ### or already sorted??
+ // Not guaranteed to be sorted, so sort:
+ std::sort(result.begin(), result.end());
// ### assuming no duplicates
return result;
}
@@ -904,13 +941,16 @@ QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(QLocale::Country cou
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(qint32 offsetSeconds) const
{
+ // Only if it's present in CLDR. (May get more than one ID: UTC, UTC+00:00
+ // and UTC-00:00 all have the same offset.)
QList<QByteArray> result;
for (int i = 0; i < utcDataTableSize; ++i) {
const QUtcData *data = utcData(i);
if (data->offsetFromUtc == offsetSeconds)
result << utcId(data);
}
- std::sort(result.begin(), result.end()); // ### or already sorted??
+ // Not guaranteed to be sorted, so sort:
+ std::sort(result.begin(), result.end());
// ### assuming no duplicates
return result;
}
diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h
index 5f6491ef81..a57f61f381 100644
--- a/src/corelib/time/qtimezoneprivate_p.h
+++ b/src/corelib/time/qtimezoneprivate_p.h
@@ -188,6 +188,9 @@ public:
QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other);
virtual ~QUtcTimeZonePrivate();
+ // Fall-back for UTC[+-]\d+(:\d+){,2} IDs.
+ static qint64 offsetFromUtcString(const QByteArray &id);
+
QUtcTimeZonePrivate *clone() const override;
Data data(qint64 forMSecsSinceEpoch) const override;
diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp
index 1bf2366748..5a480222e0 100644
--- a/src/corelib/time/qtimezoneprivate_win.cpp
+++ b/src/corelib/time/qtimezoneprivate_win.cpp
@@ -371,6 +371,7 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
// Otherwise, the rule date is annual and relative:
const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
QDate date(year, rule.wMonth, 1);
+ Q_ASSERT(date.isValid());
// How many days before was last dayOfWeek before target month ?
int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
if (adjust >= 0) // Ensure -7 <= adjust < 0:
@@ -401,6 +402,7 @@ qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)
{
// TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in
// WinTransitionRule; do this in init() once and store the results.
+ Q_ASSERT(year);
const QDate date = calculateTransitionLocalDate(rule, year);
const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
if (date.isValid() && time.isValid())
@@ -479,6 +481,7 @@ struct TransitionTimePair
int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
{
+ Q_ASSERT(year);
int offset = rule.standardTimeBias;
// Only needed to help another TransitionTimePair work out year + 1's start
// offset; and the oldYearOffset we use only affects an alleged transition
@@ -743,11 +746,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
// Does this rule's period include any transition at all ?
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- const int endYear = qMax(rule.startYear, year - 1);
+ int prior = year == 1 ? -1 : year - 1; // No year 0.
+ const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) {
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false;
if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
@@ -755,7 +759,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
} else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
isDst = true;
} else {
- --year; // Try an earlier year for this rule (once).
+ year = prior; // Try an earlier year for this rule (once).
+ prior = year == 1 ? -1 : year - 1; // No year 0.
continue;
}
return ruleToData(rule, forMSecsSinceEpoch,
@@ -767,8 +772,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
// No transition, no DST, use the year's standard time.
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
}
- if (year >= rule.startYear)
+ if (year >= rule.startYear) {
year = rule.startYear - 1; // Seek last transition in new rule.
+ if (!year)
+ --year;
+ }
}
// We don't have relevant data :-(
return invalidData();
@@ -795,9 +803,10 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
year = rule.startYear; // Seek first transition in this rule.
const int endYear = ruleIndex + 1 < m_tranRules.count()
? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2);
+ int prior = year == 1 ? -1 : year - 1; // No year 0.
int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
while (year < endYear) {
const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false;
@@ -810,7 +819,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
newYearOffset = rule.standardTimeBias;
if (pair.dst > pair.std)
newYearOffset += rule.daylightTimeBias;
- ++year; // Try a later year for this rule (once).
+ // Try a later year for this rule (once).
+ prior = year;
+ year = year == -1 ? 1 : year + 1; // No year 0
continue;
}
@@ -837,11 +848,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
// Does this rule's period include any transition at all ?
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- const int endYear = qMax(rule.startYear, year - 1);
+ int prior = year == 1 ? -1 : year - 1; // No year 0.
+ const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) {
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false;
if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) {
@@ -849,7 +861,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
} else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) {
isDst = true;
} else {
- --year; // Try an earlier year for this rule (once).
+ year = prior; // Try an earlier year for this rule (once).
+ prior = year == 1 ? -1 : year - 1; // No year 0.
continue;
}
if (isDst)
@@ -863,8 +876,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
// rule:
return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
} // else: no transition during rule's period
- if (year >= rule.startYear)
+ if (year >= rule.startYear) {
year = rule.startYear - 1; // Seek last transition in new rule
+ if (!year)
+ --year;
+ }
}
// Apparently no transition before the given time:
return invalidData();
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 234a44f6b6..36a221f728 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -143,7 +143,7 @@ qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t heade
}
result.elementCount = (bytes - unsigned(headerSize)) / unsigned(elementSize);
- result.size = bytes;
+ result.size = result.elementCount * elementSize + headerSize;
return result;
}
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index 86a16eb32b..3a0c4381f1 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -49,8 +49,6 @@
#include <QtCore/qglobal.h>
#include <iterator>
-#ifndef Q_QDOC
-
QT_BEGIN_NAMESPACE
namespace QtPrivate
@@ -131,6 +129,4 @@ using IfAssociativeIteratorHasFirstAndSecond =
QT_END_NAMESPACE
-#endif // Q_QDOC
-
#endif // QCONTAINERTOOLS_IMPL_H
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 8e00c46b41..d7f69d3e0a 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -583,6 +583,13 @@ struct BezierEase : public QEasingCurveFunction
qWarning("QEasingCurve: Invalid bezier curve");
return x;
}
+
+ // The bezier computation is not always precise on the endpoints, so handle explicitly
+ if (!(x > 0))
+ return 0;
+ if (!(x < 1))
+ return 1;
+
SingleCubicBezier *singleCubicBezier = 0;
getBezierSegment(singleCubicBezier, x);
@@ -998,6 +1005,11 @@ struct BackEase : public QEasingCurveFunction
qreal value(qreal t) override
{
+ // The *Back() functions are not always precise on the endpoints, so handle explicitly
+ if (!(t > 0))
+ return 0;
+ if (!(t < 1))
+ return 1;
qreal o = (_o < 0) ? qreal(1.70158) : _o;
switch(_t) {
case QEasingCurve::InBack:
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index dfebd57e34..3dc962236c 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -847,9 +847,10 @@ void **QListData::erase(void **xi)
/*! \fn template <class T> void QList<T>::insert(int i, const T &value)
- Inserts \a value at index position \a i in the list. If \a i <= 0,
- the value is prepended to the list. If \a i >= size(), the
- value is appended to the list.
+ Inserts \a value at index position \a i in the list.
+
+ If \a i == 0, the value is prepended to the list. If \a i == size(),
+ the value is appended to the list.
Example:
\snippet code/src_corelib_tools_qlistdata.cpp 8
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index be987c359b..ffd470efcd 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -580,8 +580,16 @@ inline T &QList<T>::operator[](int i)
detach(); return reinterpret_cast<Node *>(p.at(i))->t(); }
template <typename T>
inline void QList<T>::removeAt(int i)
-{ if(i >= 0 && i < p.size()) { detach();
- node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i); } }
+{
+#if !QT_DEPRECATED_SINCE(5, 15)
+ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::removeAt", "index out of range");
+#elif !defined(QT_NO_DEBUG)
+ if (i < 0 || i >= p.size())
+ qWarning("QList::removeAt(): Index out of range.");
+#endif
+ detach();
+ node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i);
+}
template <typename T>
inline T QList<T>::takeAt(int i)
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::take", "index out of range");
@@ -676,6 +684,12 @@ inline void QList<T>::prepend(const T &t)
template <typename T>
inline void QList<T>::insert(int i, const T &t)
{
+#if !QT_DEPRECATED_SINCE(5, 15)
+ Q_ASSERT_X(i >= 0 && i <= p.size(), "QList<T>::insert", "index out of range");
+#elif !defined(QT_NO_DEBUG)
+ if (i < 0 || i > p.size())
+ qWarning("QList::insert(): Index out of range.");
+#endif
if (d->ref.isShared()) {
Node *n = detach_helper_grow(i, 1);
QT_TRY {
@@ -1051,7 +1065,7 @@ int lastIndexOf(const QList<T> &list, const U &u, int from)
Node *n = reinterpret_cast<Node *>(list.p.at(from + 1));
while (n-- != b) {
if (n->t() == u)
- return typename QList<T>::difference_type(n - b);
+ return int(n - b);
}
}
return -1;
diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc
index 59e6931995..65576ef2e6 100644
--- a/src/corelib/tools/qpair.qdoc
+++ b/src/corelib/tools/qpair.qdoc
@@ -28,6 +28,7 @@
/*!
\class QPair
\inmodule QtCore
+ \reentrant
\brief The QPair class is a template class that stores a pair of items.
\ingroup tools
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 6683188ad4..923411c34c 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -108,7 +108,11 @@ public:
friend class QSet<T>;
public:
+#if QT_DEPRECATED_SINCE(5, 15)
typedef std::bidirectional_iterator_tag iterator_category;
+#else
+ typedef std::forward_iterator_tag iterator_category;
+#endif
typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
@@ -128,13 +132,15 @@ public:
{ return i != o.i; }
inline iterator &operator++() { ++i; return *this; }
inline iterator operator++(int) { iterator r = *this; ++i; return r; }
- inline iterator &operator--() { --i; return *this; }
- inline iterator operator--(int) { iterator r = *this; --i; return r; }
- inline iterator operator+(int j) const { return i + j; }
- inline iterator operator-(int j) const { return i - j; }
- friend inline iterator operator+(int j, iterator k) { return k + j; }
- inline iterator &operator+=(int j) { i += j; return *this; }
- inline iterator &operator-=(int j) { i -= j; return *this; }
+#if QT_DEPRECATED_SINCE(5, 15)
+ inline QT_DEPRECATED iterator &operator--() { --i; return *this; }
+ inline QT_DEPRECATED iterator operator--(int) { iterator r = *this; --i; return r; }
+ inline QT_DEPRECATED iterator operator+(int j) const { return i + j; }
+ inline QT_DEPRECATED iterator operator-(int j) const { return i - j; }
+ friend inline QT_DEPRECATED iterator operator+(int j, iterator k) { return k + j; }
+ inline QT_DEPRECATED iterator &operator+=(int j) { i += j; return *this; }
+ inline QT_DEPRECATED iterator &operator-=(int j) { i -= j; return *this; }
+#endif
};
class const_iterator
@@ -145,7 +151,11 @@ public:
friend class QSet<T>;
public:
+#if QT_DEPRECATED_SINCE(5, 15)
typedef std::bidirectional_iterator_tag iterator_category;
+#else
+ typedef std::forward_iterator_tag iterator_category;
+#endif
typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
@@ -163,19 +173,18 @@ public:
inline bool operator!=(const const_iterator &o) const { return i != o.i; }
inline const_iterator &operator++() { ++i; return *this; }
inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
- inline const_iterator &operator--() { --i; return *this; }
- inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
- inline const_iterator operator+(int j) const { return i + j; }
- inline const_iterator operator-(int j) const { return i - j; }
- friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
- inline const_iterator &operator+=(int j) { i += j; return *this; }
- inline const_iterator &operator-=(int j) { i -= j; return *this; }
+#if QT_DEPRECATED_SINCE(5, 15)
+ inline QT_DEPRECATED const_iterator &operator--() { --i; return *this; }
+ inline QT_DEPRECATED const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
+ inline QT_DEPRECATED const_iterator operator+(int j) const { return i + j; }
+ inline QT_DEPRECATED const_iterator operator-(int j) const { return i - j; }
+ friend inline QT_DEPRECATED const_iterator operator+(int j, const_iterator k) { return k + j; }
+ inline QT_DEPRECATED const_iterator &operator+=(int j) { i += j; return *this; }
+ inline QT_DEPRECATED const_iterator &operator-=(int j) { i -= j; return *this; }
+#endif
};
// STL style
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
inline iterator begin() { return q_hash.begin(); }
inline const_iterator begin() const noexcept { return q_hash.begin(); }
inline const_iterator cbegin() const noexcept { return q_hash.begin(); }
@@ -185,12 +194,17 @@ public:
inline const_iterator cend() const noexcept { return q_hash.end(); }
inline const_iterator constEnd() const noexcept { return q_hash.constEnd(); }
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
- const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
- const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
- const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
+#if QT_DEPRECATED_SINCE(5, 15)
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ reverse_iterator QT_DEPRECATED rbegin() { return reverse_iterator(end()); }
+ reverse_iterator QT_DEPRECATED rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator QT_DEPRECATED rbegin() const noexcept { return const_reverse_iterator(end()); }
+ const_reverse_iterator QT_DEPRECATED rend() const noexcept { return const_reverse_iterator(begin()); }
+ const_reverse_iterator QT_DEPRECATED crbegin() const noexcept { return const_reverse_iterator(end()); }
+ const_reverse_iterator QT_DEPRECATED crend() const noexcept { return const_reverse_iterator(begin()); }
+#endif
iterator erase(iterator i)
{ return erase(m2c(i)); }
@@ -399,17 +413,19 @@ public:
inline bool hasNext() const { return c->constEnd() != i; }
inline const T &next() { n = i++; return *n; }
inline const T &peekNext() const { return *i; }
- inline bool hasPrevious() const { return c->constBegin() != i; }
- inline const T &previous() { n = --i; return *n; }
- inline const T &peekPrevious() const { iterator p = i; return *--p; }
inline void remove()
{ if (c->constEnd() != n) { i = c->erase(n); n = c->end(); } }
inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
inline bool findNext(const T &t)
{ while (c->constEnd() != (n = i)) if (*i++ == t) return true; return false; }
- inline bool findPrevious(const T &t)
+#if QT_DEPRECATED_SINCE(5, 15)
+ inline QT_DEPRECATED bool hasPrevious() const { return c->constBegin() != i; }
+ inline QT_DEPRECATED const T &previous() { n = --i; return *n; }
+ inline QT_DEPRECATED const T &peekPrevious() const { iterator p = i; return *--p; }
+ inline QT_DEPRECATED bool findPrevious(const T &t)
{ while (c->constBegin() != i) if (*(n = --i) == t) return true;
n = c->end(); return false; }
+#endif
};
#endif // QT_NO_JAVA_STYLE_ITERATORS
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index 084523ed4b..7c752d0318 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -906,8 +906,6 @@
Calling this function on QSet<T>::constEnd() leads to
undefined results.
-
- \sa operator--()
*/
/*!
@@ -924,6 +922,7 @@
/*!
\fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator--()
\fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator--()
+ \obsolete
The prefix -- operator (\c{--it}) makes the preceding item
current and returns an iterator to the new current item.
@@ -937,6 +936,7 @@
/*!
\fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator--(int)
\fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator--(int)
+ \obsolete
\overload
@@ -947,6 +947,7 @@
/*!
\fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator+(int j) const
\fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator+(int j) const
+ \obsolete
Returns an iterator to the item at \a j positions forward from
this iterator. (If \a j is negative, the iterator goes backward.)
@@ -959,6 +960,7 @@
/*!
\fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator-(int j) const
\fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator-(int j) const
+ \obsolete
Returns an iterator to the item at \a j positions backward from
this iterator. (If \a j is negative, the iterator goes forward.)
@@ -971,6 +973,7 @@
/*!
\fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator+=(int j)
\fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator+=(int j)
+ \obsolete
Advances the iterator by \a j items. (If \a j is negative, the
iterator goes backward.)
@@ -983,6 +986,7 @@
/*!
\fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator-=(int j)
\fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator-=(int j)
+ \obsolete
Makes the iterator go back by \a j items. (If \a j is negative,
the iterator goes forward.)
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index ecf1822e42..d7c1d8c4a9 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -188,6 +188,8 @@ static inline quint64 detectProcessorFeatures()
# define PICreg "%%rbx"
#endif
+static bool checkRdrndWorks() noexcept;
+
static int maxBasicCpuidSupported()
{
#if defined(Q_CC_EMSCRIPTEN)
@@ -376,6 +378,9 @@ static quint64 detectProcessorFeatures()
features &= ~AllAVX512;
}
+ if (features & CpuFeatureRDRND && !checkRdrndWorks())
+ features &= ~(CpuFeatureRDRND | CpuFeatureRDSEED);
+
return features;
}
@@ -590,4 +595,124 @@ void qDumpCPUFeatures()
puts("");
}
+#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
+
+# ifdef Q_PROCESSOR_X86_64
+# define _rdrandXX_step _rdrand64_step
+# define _rdseedXX_step _rdseed64_step
+# else
+# define _rdrandXX_step _rdrand32_step
+# define _rdseedXX_step _rdseed32_step
+# endif
+
+# if QT_COMPILER_SUPPORTS_HERE(RDSEED)
+static QT_FUNCTION_TARGET(RDSEED) unsigned *qt_random_rdseed(unsigned *ptr, unsigned *end) noexcept
+{
+ // Unlike for the RDRAND code below, the Intel whitepaper describing the
+ // use of the RDSEED instruction indicates we should not retry in a loop.
+ // If the independent bit generator used by RDSEED is out of entropy, it
+ // may take time to replenish.
+ // https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
+ while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
+ if (_rdseedXX_step(reinterpret_cast<qregisteruint *>(ptr)) == 0)
+ goto out;
+ ptr += sizeof(qregisteruint)/sizeof(*ptr);
+ }
+
+ if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
+ if (_rdseed32_step(ptr) == 0)
+ goto out;
+ ++ptr;
+ }
+
+out:
+ return ptr;
+}
+# else
+static unsigned *qt_random_rdseed(unsigned *ptr, unsigned *)
+{
+ return ptr;
+}
+# endif
+
+static QT_FUNCTION_TARGET(RDRND) unsigned *qt_random_rdrnd(unsigned *ptr, unsigned *end) noexcept
+{
+ int retries = 10;
+ while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
+ if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)))
+ ptr += sizeof(qregisteruint)/sizeof(*ptr);
+ else if (--retries == 0)
+ goto out;
+ }
+
+ while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
+ bool ok = _rdrand32_step(ptr);
+ if (!ok && --retries)
+ continue;
+ if (ok)
+ ++ptr;
+ break;
+ }
+
+out:
+ return ptr;
+}
+
+static QT_FUNCTION_TARGET(RDRND) Q_DECL_COLD_FUNCTION bool checkRdrndWorks() noexcept
+{
+ /*
+ * Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a
+ * failing random generation instruction, which always returns
+ * 0xffffffff, even when generation was "successful".
+ *
+ * This code checks if hardware random generator generates four consecutive
+ * equal numbers. If it does, then we probably have a failing one and
+ * should disable it completely.
+ *
+ * https://bugreports.qt.io/browse/QTBUG-69423
+ */
+ constexpr qsizetype TestBufferSize = 4;
+ unsigned testBuffer[TestBufferSize] = {};
+
+ unsigned *end = qt_random_rdrnd(testBuffer, testBuffer + TestBufferSize);
+ if (end < testBuffer + 3) {
+ // Random generation didn't produce enough data for us to make a
+ // determination whether it's working or not. Assume it isn't, but
+ // don't print a warning.
+ return false;
+ }
+
+ // Check the results for equality
+ if (testBuffer[0] == testBuffer[1]
+ && testBuffer[0] == testBuffer[2]
+ && end == testBuffer + TestBufferSize && testBuffer[0] == testBuffer[3]) {
+ fprintf(stderr, "WARNING: CPU random generator seem to be failing, "
+ "disabling hardware random number generation\n"
+ "WARNING: RDRND generated:");
+ for (unsigned *ptr = testBuffer; ptr < end; ++ptr)
+ fprintf(stderr, " 0x%x", *ptr);
+ fprintf(stderr, "\n");
+ return false;
+ }
+
+ // We're good
+ return true;
+}
+
+QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) noexcept
+{
+ unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
+ unsigned *end = ptr + count;
+
+ if (qCpuHasFeature(RDSEED))
+ ptr = qt_random_rdseed(ptr, end);
+
+ // fill the buffer with RDRND if RDSEED didn't
+ ptr = qt_random_rdrnd(ptr, end);
+ return ptr - reinterpret_cast<unsigned *>(buffer);
+}
+#elif defined(Q_PROCESSOR_X86) && !defined(Q_OS_NACL) && !defined(Q_PROCESSOR_ARM)
+static bool checkRdrndWorks() noexcept { return false; }
+#endif // Q_PROCESSOR_X86 && RDRND
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index db2f546651..c28624a25e 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -346,6 +346,15 @@ extern Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2];
#endif
Q_CORE_EXPORT quint64 qDetectCpuFeatures();
+#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
+Q_CORE_EXPORT qsizetype qRandomCpu(void *, qsizetype) noexcept;
+#else
+static inline qsizetype qRandomCpu(void *, qsizetype) noexcept
+{
+ return 0;
+}
+#endif
+
static inline quint64 qCpuFeatures()
{
quint64 features = qt_cpu_features[0].loadRelaxed();
@@ -362,6 +371,15 @@ static inline quint64 qCpuFeatures()
#define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature) \
|| ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature))
+inline bool qHasHwrng()
+{
+#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
+ return qCpuHasFeature(RDRND);
+#else
+ return false;
+#endif
+}
+
#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 253d05ba2b..6be695e317 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -104,7 +104,7 @@ public:
QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list)
{
- resize(list.size());
+ resize(int(list.size())); // ### q6sizetype
std::copy(list.begin(), list.end(),
QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size()));
return *this;
diff --git a/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp b/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp
index 0fc7a2b26c..f5d9fe7889 100644
--- a/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp
+++ b/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp
@@ -62,7 +62,6 @@ QString processRequest(const QString &request, const QDBusMessage &message)
data->request = request;
message.setDelayedReply(true);
data->reply = message.createReply();
- QDBusConnection::sessionBus().send(data->reply);
appendRequest(data);
return QString();
diff --git a/src/dbus/doc/snippets/code/src_qdbus_qdbusargument.cpp b/src/dbus/doc/snippets/code/src_qdbus_qdbusargument.cpp
index be72220153..b64ea5cf21 100644
--- a/src/dbus/doc/snippets/code/src_qdbus_qdbusargument.cpp
+++ b/src/dbus/doc/snippets/code/src_qdbus_qdbusargument.cpp
@@ -186,7 +186,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, MyDictionary &myd
argument.beginMap();
mydict.clear();
- while ( !argMap.atEnd() ) {
+ while ( !argument.atEnd() ) {
int key;
MyValue value;
argument.beginMapEntry();
diff --git a/src/dbus/doc/src/dbus-adaptors.qdoc b/src/dbus/doc/src/dbus-adaptors.qdoc
index 9ebf0cedf2..3398a45af7 100644
--- a/src/dbus/doc/src/dbus-adaptors.qdoc
+++ b/src/dbus/doc/src/dbus-adaptors.qdoc
@@ -174,9 +174,6 @@
\snippet code/doc_src_qdbusadaptors.cpp 10
- The use of
- \l{QDBusConnection::send()}{QDBusConnection::sessionBus().send(data->reply)}
- is needed to explicitly inform the caller that the response will be delayed.
In this case, the return value is unimportant; we return an arbitrary value
to satisfy the compiler.
diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp
index 284ba999c2..1e2cbf6da6 100644
--- a/src/dbus/qdbus_symbols.cpp
+++ b/src/dbus/qdbus_symbols.cpp
@@ -100,15 +100,15 @@ bool qdbus_loadLibDBus()
};
lib->unload();
- for (uint i = 0; i < sizeof(majorversions) / sizeof(majorversions[0]); ++i) {
- for (uint j = 0; j < sizeof(baseNames) / sizeof(baseNames[0]); ++j) {
+ for (const int majorversion : majorversions) {
+ for (const QString &baseName : baseNames) {
#ifdef Q_OS_WIN
QString suffix;
- if (majorversions[i] != -1)
- suffix = QString::number(- majorversions[i]); // negative so it prepends the dash
- lib->setFileName(baseNames[j] + suffix);
+ if (majorversion != -1)
+ suffix = QString::number(- majorversion); // negative so it prepends the dash
+ lib->setFileName(baseName + suffix);
#else
- lib->setFileNameAndVersion(baseNames[j], majorversions[i]);
+ lib->setFileNameAndVersion(baseName, majorversion);
#endif
if (lib->load() && lib->resolve("dbus_connection_open_private"))
return true;
diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp
index 993607a643..b7b291551d 100644
--- a/src/dbus/qdbusabstractadaptor.cpp
+++ b/src/dbus/qdbusabstractadaptor.cpp
@@ -276,11 +276,11 @@ void QDBusAdaptorConnector::polish()
std::sort(adaptors.begin(), adaptors.end());
}
-void QDBusAdaptorConnector::relaySlot(void **argv)
+void QDBusAdaptorConnector::relaySlot(QMethodRawArguments argv)
{
QObject *sndr = sender();
if (Q_LIKELY(sndr)) {
- relay(sndr, senderSignalIndex(), argv);
+ relay(sndr, senderSignalIndex(), argv.arguments);
} else {
qWarning("QtDBus: cannot relay signals from parent %s(%p \"%s\") unless they are emitted in the object's thread %s(%p \"%s\"). "
"Current thread is %s(%p \"%s\").",
@@ -333,120 +333,6 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
emit relaySignal(realObject, senderMetaObject, lastSignalIdx, args);
}
-// our Meta Object
-// modify carefully: this has been hand-edited!
-// the relaySlot slot gets called with the void** array
-
-struct qt_meta_stringdata_QDBusAdaptorConnector_t {
- QByteArrayData data[10];
- char stringdata[96];
-};
-#define QT_MOC_LITERAL(idx, ofs, len) \
- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
- offsetof(qt_meta_stringdata_QDBusAdaptorConnector_t, stringdata) + ofs \
- - idx * sizeof(QByteArrayData) \
- )
-static const qt_meta_stringdata_QDBusAdaptorConnector_t qt_meta_stringdata_QDBusAdaptorConnector = {
- {
-QT_MOC_LITERAL(0, 0, 21),
-QT_MOC_LITERAL(1, 22, 11),
-QT_MOC_LITERAL(2, 34, 0),
-QT_MOC_LITERAL(3, 35, 3),
-QT_MOC_LITERAL(4, 39, 18),
-QT_MOC_LITERAL(5, 58, 10),
-QT_MOC_LITERAL(6, 69, 3),
-QT_MOC_LITERAL(7, 73, 4),
-QT_MOC_LITERAL(8, 78, 9),
-QT_MOC_LITERAL(9, 88, 6)
- },
- "QDBusAdaptorConnector\0relaySignal\0\0"
- "obj\0const QMetaObject*\0metaObject\0sid\0"
- "args\0relaySlot\0polish\0"
-};
-#undef QT_MOC_LITERAL
-
-static const uint qt_meta_data_QDBusAdaptorConnector[] = {
-
- // content:
- 7, // revision
- 0, // classname
- 0, 0, // classinfo
- 3, 14, // methods
- 0, 0, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 1, // signalCount
-
- // signals: name, argc, parameters, tag, flags
- 1, 4, 29, 2, 0x05,
-
- // slots: name, argc, parameters, tag, flags
- 8, 0, 38, 2, 0x0a,
- 9, 0, 39, 2, 0x0a,
-
- // signals: parameters
- QMetaType::Void, QMetaType::QObjectStar, 0x80000000 | 4, QMetaType::Int, QMetaType::QVariantList, 3, 5, 6, 7,
-
- // slots: parameters
- QMetaType::Void,
- QMetaType::Void,
-
- 0 // eod
-};
-
-void QDBusAdaptorConnector::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
-{
- if (_c == QMetaObject::InvokeMetaMethod) {
- Q_ASSERT(staticMetaObject.cast(_o));
- QDBusAdaptorConnector *_t = static_cast<QDBusAdaptorConnector *>(_o);
- switch (_id) {
- case 0: _t->relaySignal((*reinterpret_cast< QObject*(*)>(_a[1])),(*reinterpret_cast< const QMetaObject*(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3])),(*reinterpret_cast< const QVariantList(*)>(_a[4]))); break;
- case 1: _t->relaySlot(_a); break; // HAND EDIT: add the _a parameter
- case 2: _t->polish(); break;
- default: ;
- }
- }
-}
-
-const QMetaObject QDBusAdaptorConnector::staticMetaObject = {
- { &QObject::staticMetaObject, qt_meta_stringdata_QDBusAdaptorConnector.data,
- qt_meta_data_QDBusAdaptorConnector, qt_static_metacall, 0, 0 }
-};
-
-const QMetaObject *QDBusAdaptorConnector::metaObject() const
-{
- return &staticMetaObject;
-}
-
-void *QDBusAdaptorConnector::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_QDBusAdaptorConnector.stringdata))
- return static_cast<void*>(const_cast< QDBusAdaptorConnector*>(this));
- return QObject::qt_metacast(_clname);
-}
-
-int QDBusAdaptorConnector::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
- _id = QObject::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- if (_c == QMetaObject::InvokeMetaMethod) {
- if (_id < 3)
- qt_static_metacall(this, _c, _id, _a);
- _id -= 3;
- }
- return _id;
-}
-
-// SIGNAL 0
-void QDBusAdaptorConnector::relaySignal(QObject * _t1, const QMetaObject * _t2, int _t3, const QVariantList & _t4)
-{
- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)), const_cast<void*>(reinterpret_cast<const void*>(&_t3)), const_cast<void*>(reinterpret_cast<const void*>(&_t4)) };
- QMetaObject::activate(this, &staticMetaObject, 0, _a);
-}
-
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/dbus/qdbusabstractadaptor_p.h b/src/dbus/qdbusabstractadaptor_p.h
index 023b3b1be2..404901381b 100644
--- a/src/dbus/qdbusabstractadaptor_p.h
+++ b/src/dbus/qdbusabstractadaptor_p.h
@@ -92,7 +92,7 @@ public:
class QDBusAdaptorConnector: public QObject
{
- Q_OBJECT_FAKE
+ Q_OBJECT
public: // typedefs
struct AdaptorData
@@ -118,12 +118,11 @@ public: // methods
void disconnectAllSignals(QObject *object);
void relay(QObject *sender, int id, void **);
-//public slots:
- void relaySlot(void **);
+public Q_SLOTS:
+ void relaySlot(QMethodRawArguments a);
void polish();
-protected:
-//signals:
+Q_SIGNALS:
void relaySignal(QObject *obj, const QMetaObject *metaObject, int sid, const QVariantList &args);
public: // member variables
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 58b5af3615..d6f3230fd2 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -871,8 +871,12 @@ bool QDBusConnection::disconnect(const QString &service, const QString &path, co
This function does not replace existing objects: if there is already an object registered at
path \a path, this function will return false. Use unregisterObject() to unregister it first.
+ The ExportChildObjects flag exports child objects on D-Bus based on the
+ path of the registered objects and the QObject::objectName of the child.
+ Therefore, it is important for the child object to have an object name.
+
You cannot register an object as a child object of an object that
- was registered with QDBusConnection::ExportChildObjects.
+ was registered with ExportChildObjects.
*/
bool QDBusConnection::registerObject(const QString &path, QObject *object, RegisterOptions options)
{
@@ -891,8 +895,12 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis
This function does not replace existing objects: if there is already an object registered at
path \a path, this function will return false. Use unregisterObject() to unregister it first.
+ The ExportChildObjects flag exports child objects on D-Bus based on the
+ path of the registered objects and the QObject::objectName of the child.
+ Therefore, it is important for the child object to have an object name.
+
You cannot register an object as a child object of an object that
- was registered with QDBusConnection::ExportChildObjects.
+ was registered with ExportChildObjects.
*/
bool QDBusConnection::registerObject(const QString &path, const QString &interface, QObject *object, RegisterOptions options)
{
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index f2607e3e8d..eccffc3d3e 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -111,12 +111,16 @@ QDBusServer::QDBusServer(QObject *parent)
*/
QDBusServer::~QDBusServer()
{
- QWriteLocker locker(&d->lock);
+ QMutex *managerMutex = nullptr;
+ if (QDBusConnectionManager::instance())
+ managerMutex = &QDBusConnectionManager::instance()->mutex;
+ QMutexLocker locker(managerMutex);
+ QWriteLocker writeLocker(&d->lock);
if (QDBusConnectionManager::instance()) {
- const auto locker = qt_scoped_lock(QDBusConnectionManager::instance()->mutex);
for (const QString &name : qAsConst(d->serverConnectionNames))
QDBusConnectionManager::instance()->removeConnection(name);
d->serverConnectionNames.clear();
+ locker.unlock();
}
d->serverObject = nullptr;
d->ref.storeRelaxed(0);
diff --git a/src/gui/configure.pri b/src/gui/configure.pri
index 1b95449a10..490ef0df28 100644
--- a/src/gui/configure.pri
+++ b/src/gui/configure.pri
@@ -1,18 +1,22 @@
# custom tests
defineTest(qtConfLibrary_freetype) {
- TRY_INCLUDEPATHS = $$EXTRA_INCLUDEPATH $$QMAKE_INCDIR_X11
- haiku: TRY_INCLUDEPATHS += /system/develop/headers
- TRY_INCLUDEPATHS += $$QMAKE_DEFAULT_INCDIR
- for (p, TRY_INCLUDEPATHS) {
- includedir = $$p/freetype2
- exists($$includedir) {
- $${1}.includedir = $$includedir
- export($${1}.includedir)
- return(true)
+ input = $$eval($${2}.alias)
+ isEmpty(config.input.$${input}.incdir) {
+ TRY_INCLUDEPATHS = $$EXTRA_INCLUDEPATH $$QMAKE_INCDIR_X11
+ haiku: TRY_INCLUDEPATHS += /system/develop/headers
+ TRY_INCLUDEPATHS += $$QMAKE_DEFAULT_INCDIRS
+ for (p, TRY_INCLUDEPATHS) {
+ includedir = $$p/freetype2
+ exists($$includedir) {
+ config.input.$${input}.incdir = $$includedir
+ export(config.input.$${input}.incdir)
+ break()
+ }
}
}
- return(true)
+ qtConfLibrary_inline($$1, $$2): return(true)
+ return(false)
}
# Check for Direct X shader compiler 'fxc'.
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 1d0c93f26f..27c82bc09f 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -281,7 +281,7 @@ static quint32 icon_name_hash(const char *p)
QVector<const char *> QIconCacheGtkReader::lookup(const QStringRef &name)
{
QVector<const char *> ret;
- if (!isValid())
+ if (!isValid() || name.isEmpty())
return ret;
QByteArray nameUtf8 = name.toUtf8();
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index b7f67cd7ef..dda407181a 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3370,7 +3370,7 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical)
\sa {QImage#Image Transformations}{Image Transformations}
*/
-inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
+static inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
{
const RbSwapFunc func = layout->rbSwap;
if (!func) {
@@ -5025,7 +5025,7 @@ QImage QImage::convertedToColorSpace(const QColorSpace &colorSpace) const
QColorSpace QImage::colorSpace() const
{
if (!d)
- return QColorSpace::Undefined;
+ return QColorSpace();
return d->colorSpace;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index c657d6067f..73c960f13f 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -68,7 +68,6 @@ class QMatrix;
class QStringList;
class QTransform;
class QVariant;
-template <class T> class QList;
template <class T> class QVector;
struct QImageData;
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 539bac222a..9e1df7058c 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -564,6 +564,67 @@ static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFl
return true;
}
+static void convert_rgbswap_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const RbSwapFunc func = qPixelLayouts[src->format].rbSwap;
+ Q_ASSERT(func);
+
+ const qsizetype sbpl = src->bytes_per_line;
+ const qsizetype dbpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ func(dest_data, src_data, src->width);
+
+ src_data += sbpl;
+ dest_data += dbpl;
+ }
+}
+
+static bool convert_rgbswap_generic_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ const RbSwapFunc func = qPixelLayouts[data->format].rbSwap;
+ Q_ASSERT(func);
+
+ const qsizetype bpl = data->bytes_per_line;
+ uchar *line_data = data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ func(line_data, line_data, data->width);
+ line_data += bpl;
+ }
+
+ switch (data->format) {
+ case QImage::Format_RGB888:
+ data->format = QImage::Format_BGR888;
+ break;
+ case QImage::Format_BGR888:
+ data->format = QImage::Format_RGB888;
+ break;
+ case QImage::Format_BGR30:
+ data->format = QImage::Format_RGB30;
+ break;
+ case QImage::Format_A2BGR30_Premultiplied:
+ data->format = QImage::Format_A2RGB30_Premultiplied;
+ break;
+ case QImage::Format_RGB30:
+ data->format = QImage::Format_BGR30;
+ break;
+ case QImage::Format_A2RGB30_Premultiplied:
+ data->format = QImage::Format_A2BGR30_Premultiplied;
+ break;
+ default:
+ Q_UNREACHABLE();
+ data->format = QImage::Format_Invalid;
+ return false;
+ }
+ return true;
+}
+
template<QtPixelOrder PixelOrder, bool RGBA>
static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
@@ -693,74 +754,10 @@ static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConve
return true;
}
-static void convert_BGR30_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB30 || src->format == QImage::Format_BGR30 ||
- src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30 ||
- dest->format == QImage::Format_A2RGB30_Premultiplied || dest->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = qRgbSwapRgb30(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30 ||
- data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- uint *rgb_data = (uint *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const uint *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = qRgbSwapRgb30(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
-
- switch (data->format) {
- case QImage::Format_BGR30:
- data->format = QImage::Format_RGB30;
- break;
- case QImage::Format_A2BGR30_Premultiplied:
- data->format = QImage::Format_A2RGB30_Premultiplied;
- break;
- case QImage::Format_RGB30:
- data->format = QImage::Format_BGR30;
- break;
- case QImage::Format_A2RGB30_Premultiplied:
- data->format = QImage::Format_A2BGR30_Premultiplied;
- break;
- default:
- Q_UNREACHABLE();
- data->format = QImage::Format_Invalid;
- return false;
- }
- return true;
-}
-
static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversionFlags flags)
{
Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30);
- if (!convert_BGR30_to_RGB30_inplace(data, flags))
+ if (!convert_rgbswap_generic_inplace(data, flags))
return false;
if (data->format == QImage::Format_RGB30)
@@ -1421,69 +1418,6 @@ static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt
}
}
-static void convert_RGB888_to_BGR888(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
- Q_ASSERT(dest->format == QImage::Format_RGB888 || dest->format == QImage::Format_BGR888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const qsizetype sbpl = src->bytes_per_line;
- const qsizetype dbpl = dest->bytes_per_line;
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- int pixel = 0;
- // Handle 4 pixels (12 bytes) at a time
- for (; pixel + 3 < src->width; pixel += 4) {
- const uchar *src = src_data + pixel * 3;
- quint32 *dest_packed = (quint32 *) (dest_data + pixel * 3);
- dest_packed[0] = (src[5] << 24) | (src[0] << 16) | (src[1] << 8) | (src[2] << 0);
- dest_packed[1] = (src[7] << 24) | (src[8] << 16) | (src[3] << 8) | (src[4] << 0);
- dest_packed[2] = (src[9] << 24) | (src[10] << 16) | (src[11] << 8) | (src[6] << 0);
- }
-
- // epilog: handle left over pixels
- for (; pixel < src->width; ++pixel) {
- dest_data[pixel * 3 + 0] = src_data[pixel * 3 + 2];
- dest_data[pixel * 3 + 1] = src_data[pixel * 3 + 1];
- dest_data[pixel * 3 + 2] = src_data[pixel * 3 + 0];
- }
-
- src_data += sbpl;
- dest_data += dbpl;
- }
-}
-
-static bool convert_RGB888_to_BGR888_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB888 || data->format == QImage::Format_BGR888);
-
- const qsizetype bpl = data->bytes_per_line;
- uchar *line_data = data->data;
-
- for (int i = 0; i < data->height; ++i) {
- for (int j = 0; j < data->width; ++j)
- qSwap(line_data[j * 3 + 0], line_data[j * 3 + 2]);
- line_data += bpl;
- }
-
- switch (data->format) {
- case QImage::Format_RGB888:
- data->format = QImage::Format_BGR888;
- break;
- case QImage::Format_BGR888:
- data->format = QImage::Format_RGB888;
- break;
- default:
- Q_UNREACHABLE();
- data->format = QImage::Format_Invalid;
- return false;
- }
- return true;
-}
-
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2635,7 +2569,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888,
+ convert_rgbswap_generic,
}, // Format_RGB888
{
@@ -2781,8 +2715,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
convert_passthrough,
- convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
+ convert_rgbswap_generic,
0, 0,
0, 0, 0, 0, 0
}, // Format_BGR30
@@ -2809,7 +2743,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<false>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
0, 0,
0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
@@ -2833,8 +2767,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
+ convert_rgbswap_generic,
0,
convert_passthrough,
0, 0, 0, 0, 0, 0, 0
@@ -2860,7 +2794,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
convert_A2RGB30_PM_to_RGB30<false>,
0,
0, 0,
@@ -3013,7 +2947,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_RGB888_to_BGR888,
+ convert_rgbswap_generic,
0,
0,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
@@ -3161,7 +3095,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
}, // Format_ARGB8555_Premultiplied
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888_inplace
+ convert_rgbswap_generic_inplace
}, // Format_RGB888
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -3267,7 +3201,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0, // self
convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, 0,
0, 0, 0, 0, 0
@@ -3295,7 +3229,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
convert_A2RGB30_PM_to_RGB30_inplace<true>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
0, 0, 0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
{
@@ -3318,7 +3252,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
@@ -3345,7 +3279,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30_inplace<true>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
0, 0,
@@ -3427,7 +3361,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
}, // Format_Grayscale16
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888_inplace,
+ convert_rgbswap_generic_inplace,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_BGR888
};
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 6a0763e696..dff24b449a 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -150,7 +150,7 @@
// factory loader
#include <qcoreapplication.h>
#include <private/qfactoryloader_p.h>
-#include <QMutexLocker>
+#include <QtCore/private/qlocking_p.h>
// for qt_getImageText
#include <private/qimage_p.h>
@@ -186,8 +186,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray suffix;
#ifndef QT_NO_IMAGEFORMATPLUGIN
- static QMutex mutex;
- QMutexLocker locker(&mutex);
+ static QBasicMutex mutex;
+ const auto locker = qt_scoped_lock(mutex);
typedef QMultiMap<int, QString> PluginKeyMap;
diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp
index 3e975115ab..25fce050a1 100644
--- a/src/gui/image/qmovie.cpp
+++ b/src/gui/image/qmovie.cpp
@@ -414,7 +414,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
} else {
// We've read all frames now. Return an end marker
haveReadAll = true;
- return QFrameInfo::endMarker();
+ return frameNumber == greatestFrameNumber + 1 ? QFrameInfo::endMarker() : QFrameInfo();
}
}
}
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 84de91353a..e119103462 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -57,6 +57,7 @@
#include "qregexp.h"
#include "qregion.h"
#include "qdebug.h"
+#include <QtCore/private/qlocking_p.h>
#include <algorithm>
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 4ab45337b0..d6caf6773a 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -174,7 +174,7 @@ public:
void setGamma(float);
bool writeImage(const QImage& img, int x, int y);
- bool writeImage(const QImage& img, volatile int compression_in, const QString &description, int x, int y);
+ bool writeImage(const QImage& img, int compression_in, const QString &description, int x, int y);
bool writeImage(const QImage& img)
{ return writeImage(img, 0, 0); }
bool writeImage(const QImage& img, int compression, const QString &description)
@@ -900,7 +900,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y)
return writeImage(image, -1, QString(), off_x, off_y);
}
-bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_in, const QString &description,
+bool QPNGImageWriter::writeImage(const QImage& image, int compression_in, const QString &description,
int off_x_in, int off_y_in)
{
QPoint offset = image.offset();
diff --git a/src/gui/itemmodels/qstandarditemmodel.h b/src/gui/itemmodels/qstandarditemmodel.h
index 435b66591c..f1c6e6df5c 100644
--- a/src/gui/itemmodels/qstandarditemmodel.h
+++ b/src/gui/itemmodels/qstandarditemmodel.h
@@ -53,8 +53,6 @@ QT_REQUIRE_CONFIG(standarditemmodel);
QT_BEGIN_NAMESPACE
-template <class T> class QList;
-
class QStandardItemModel;
class QStandardItemPrivate;
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 8e5945be41..f2f083c277 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -791,37 +791,44 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
\obsolete
This constructor has been deprecated.
*/
-
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
: QWheelEvent(pos, globalPos, pixelDelta, angleDelta, qt4Delta, qt4Orientation,
buttons, modifiers, Qt::NoScrollPhase)
{}
+QT_WARNING_POP
/*!
\obsolete
This constructor has been deprecated.
*/
-
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase)
: QWheelEvent(pos, globalPos, pixelDelta, angleDelta, qt4Delta, qt4Orientation,
buttons, modifiers, phase, Qt::MouseEventNotSynthesized)
{}
+QT_WARNING_POP
/*!
\obsolete
This constructor has been deprecated.
*/
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source)
: QWheelEvent(pos, globalPos, pixelDelta, angleDelta, qt4Delta, qt4Orientation,
buttons, modifiers, phase, source, false)
{}
+QT_WARNING_POP
/*!
\obsolete
@@ -931,6 +938,30 @@ QWheelEvent::~QWheelEvent()
\endlist
*/
+/*!
+ \fn QPoint QWheelEvent::position() const
+
+ Returns the position of the mouse cursor relative to the widget
+ that received the event.
+
+ If you move your widgets around in response to mouse events,
+ use globalPosition() instead of this function.
+
+ \sa globalPosition()
+*/
+
+/*!
+ \fn QPoint QWheelEvent::globalPosition() const
+
+ Returns the global position of the mouse pointer \e{at the time
+ of the event}. This is important on asynchronous window systems
+ such as X11; whenever you move your widgets around in response to
+ mouse events, globalPosition() can differ a lot from the current
+ cursor position returned by QCursor::pos().
+
+ \sa position()
+*/
+
#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn int QWheelEvent::delta() const
@@ -3895,12 +3926,15 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
case QEvent::Wheel: {
const QWheelEvent *we = static_cast<const QWheelEvent *>(e);
dbg << "QWheelEvent(" << we->phase();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED // delta() and orientation()
if (!we->pixelDelta().isNull() || !we->angleDelta().isNull())
dbg << ", pixelDelta=" << we->pixelDelta() << ", angleDelta=" << we->angleDelta();
#if QT_DEPRECATED_SINCE(5, 14)
else if (int qt4Delta = we->delta())
dbg << ", delta=" << qt4Delta << ", orientation=" << we->orientation();
#endif
+QT_WARNING_POP
dbg << ')';
}
break;
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 10ef01fa1d..8a0e42f592 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -854,7 +854,6 @@ private:
qint64 m_numericId;
};
Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE);
-template <> class QList<QPointingDeviceUniqueId> {}; // to prevent instantiation: use QVector instead
Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept;
inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept
@@ -960,6 +959,8 @@ public:
friend class QGuiApplicationPrivate;
friend class QApplication;
friend class QApplicationPrivate;
+ friend class QQuickPointerTouchEvent;
+ friend class QQuickMultiPointTouchArea;
};
#if QT_DEPRECATED_SINCE(5, 0)
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index c2d8bd72b9..b7645496f8 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -67,7 +67,8 @@ public:
state(Qt::TouchPointReleased),
pressure(-1),
rotation(0),
- ellipseDiameters(0, 0)
+ ellipseDiameters(0, 0),
+ stationaryWithModifiedProperty(false)
{ }
inline QTouchEventTouchPointPrivate *detach()
@@ -91,6 +92,7 @@ public:
QSizeF ellipseDiameters;
QVector2D velocity;
QTouchEvent::TouchPoint::InfoFlags flags;
+ bool stationaryWithModifiedProperty : 1;
QVector<QPointF> rawScreenPositions;
};
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 432618968f..fa4c419ef0 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -58,6 +58,7 @@
#include <QtCore/private/qabstracteventdispatcher_p.h>
#include <QtCore/qmutex.h>
#include <QtCore/private/qthread_p.h>
+#include <QtCore/private/qlocking_p.h>
#include <QtCore/qdir.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qnumeric.h>
@@ -1039,7 +1040,9 @@ QList<QScreen *> QGuiApplication::screens()
The \a point is in relation to the virtualGeometry() of each set of virtual
siblings. If the point maps to more than one set of virtual siblings the first
- match is returned.
+ match is returned. If you wish to search only the virtual desktop siblings
+ of a known screen (for example siblings of the screen of your application
+ window \c QWidget::windowHandle()->screen()), use QScreen::virtualSiblingAt().
\since 5.10
*/
@@ -2248,8 +2251,11 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
}
#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation,
mouse_buttons, e->modifiers, e->phase, e->source, e->inverted);
+QT_WARNING_POP
#else
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta,
mouse_buttons, e->modifiers, e->phase, e->inverted, e->source);
@@ -2527,9 +2533,8 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl
QCloseEvent event;
QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
- if (e->accepted) {
- *(e->accepted) = event.isAccepted();
- }
+
+ e->eventAccepted = event.isAccepted();
}
void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e)
@@ -2766,7 +2771,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QWindow *window = e->window.data();
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
- bool stationaryTouchPointChangedVelocity = false;
+ bool stationaryTouchPointChangedProperty = false;
for (int i = 0; i < e->points.count(); ++i) {
QTouchEvent::TouchPoint touchPoint = e->points.at(i);
@@ -2846,7 +2851,13 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
if (touchPoint.state() == Qt::TouchPointStationary) {
if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) {
touchInfo.touchPoint.setVelocity(touchPoint.velocity());
- stationaryTouchPointChangedVelocity = true;
+ touchPoint.d->stationaryWithModifiedProperty = true;
+ stationaryTouchPointChangedProperty = true;
+ }
+ if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) {
+ touchInfo.touchPoint.setPressure(touchPoint.pressure());
+ touchPoint.d->stationaryWithModifiedProperty = true;
+ stationaryTouchPointChangedProperty = true;
}
} else {
touchInfo.touchPoint = touchPoint;
@@ -2887,7 +2898,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
break;
case Qt::TouchPointStationary:
// don't send the event if nothing changed
- if (!stationaryTouchPointChangedVelocity)
+ if (!stationaryTouchPointChangedProperty)
continue;
Q_FALLTHROUGH();
default:
@@ -3305,7 +3316,7 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
QFont QGuiApplication::font()
{
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
- QMutexLocker locker(&applicationFontMutex);
+ const auto locker = qt_scoped_lock(applicationFontMutex);
initFontUnlocked();
return *QGuiApplicationPrivate::app_font;
}
@@ -3317,7 +3328,7 @@ QFont QGuiApplication::font()
*/
void QGuiApplication::setFont(const QFont &font)
{
- QMutexLocker locker(&applicationFontMutex);
+ auto locker = qt_unique_lock(applicationFontMutex);
const bool emitChange = !QGuiApplicationPrivate::app_font
|| (*QGuiApplicationPrivate::app_font != font);
if (!QGuiApplicationPrivate::app_font)
@@ -3326,8 +3337,11 @@ void QGuiApplication::setFont(const QFont &font)
*QGuiApplicationPrivate::app_font = font;
applicationResourceFlags |= ApplicationFontExplicitlySet;
- if (emitChange && qGuiApp)
- emit qGuiApp->fontChanged(*QGuiApplicationPrivate::app_font);
+ if (emitChange && qGuiApp) {
+ auto font = *QGuiApplicationPrivate::app_font;
+ locker.unlock();
+ emit qGuiApp->fontChanged(font);
+ }
}
/*!
@@ -3502,7 +3516,7 @@ Qt::ApplicationState QGuiApplication::applicationState()
\since 5.14
Sets the high-DPI scale factor rounding policy for the application. The
- policy decides how non-integer scale factors (such as Windows 150%) are
+ \a policy decides how non-integer scale factors (such as Windows 150%) are
handled, for applications that have AA_EnableHighDpiScaling enabled.
The two principal options are whether fractional scale factors should
@@ -4078,7 +4092,7 @@ void QGuiApplicationPrivate::notifyThemeChanged()
sendApplicationPaletteChange();
}
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
- QMutexLocker locker(&applicationFontMutex);
+ const auto locker = qt_scoped_lock(applicationFontMutex);
clearFontUnlocked();
initFontUnlocked();
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index c031885d5d..76548d5d86 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -86,7 +86,7 @@ static inline qreal initialGlobalScaleFactor()
qreal result = 1;
if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) {
bool ok;
- const qreal f = qgetenv(scaleFactorEnvVar).toDouble(&ok);
+ const qreal f = qEnvironmentVariable(scaleFactorEnvVar).toDouble(&ok);
if (ok && f > 0) {
qCDebug(lcScaling) << "Apply " << scaleFactorEnvVar << f;
result = f;
@@ -284,7 +284,8 @@ static inline bool usePixelDensity()
return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling)
|| (screenEnvValueOk && screenEnvValue > 0)
|| (enableEnvValueOk && enableEnvValue > 0)
- || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto");
+ || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar)
+ && qEnvironmentVariable(legacyDevicePixelEnvVar).compare(QLatin1String("auto"), Qt::CaseInsensitive) == 0);
}
qreal QHighDpiScaling::rawScaleFactor(const QPlatformScreen *screen)
@@ -506,20 +507,20 @@ void QHighDpiScaling::updateHighDpiScaling()
}
if (qEnvironmentVariableIsSet(screenFactorsEnvVar)) {
int i = 0;
- const auto specs = qgetenv(screenFactorsEnvVar).split(';');
- for (const QByteArray &spec : specs) {
- int equalsPos = spec.lastIndexOf('=');
+ const QString spec = qEnvironmentVariable(screenFactorsEnvVar);
+ const auto specs = spec.splitRef(QLatin1Char(';'));
+ for (const QStringRef &spec : specs) {
+ int equalsPos = spec.lastIndexOf(QLatin1Char('='));
qreal factor = 0;
if (equalsPos > 0) {
// support "name=factor"
- QByteArray name = spec.mid(0, equalsPos);
- QByteArray f = spec.mid(equalsPos + 1);
bool ok;
- factor = f.toDouble(&ok);
+ const auto name = spec.left(equalsPos);
+ factor = spec.mid(equalsPos + 1).toDouble(&ok);
if (ok && factor > 0 ) {
const auto screens = QGuiApplication::screens();
for (QScreen *s : screens) {
- if (s->name() == QString::fromLocal8Bit(name)) {
+ if (s->name() == name) {
setScreenFactor(s, factor);
break;
}
@@ -537,7 +538,7 @@ void QHighDpiScaling::updateHighDpiScaling()
++i;
}
}
- m_active = m_globalScalingActive || m_usePixelDensity;
+ m_active = m_globalScalingActive || m_screenFactorSet || m_usePixelDensity;
}
/*
@@ -679,8 +680,11 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
if (!screen || !screen->handle())
return QDpi(96, 96);
- if (!m_usePixelDensity)
- return QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
+ if (!m_usePixelDensity) {
+ const qreal screenScaleFactor = screenSubfactor(screen->handle());
+ const QDpi dpi = QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
+ return QDpi{ dpi.first / screenScaleFactor, dpi.second / screenScaleFactor };
+ }
const qreal scaleFactor = rawScaleFactor(screen->handle());
const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);
@@ -711,8 +715,10 @@ QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *w
{
if (!m_active)
return { qreal(1), QPoint() };
+
QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
- return scaleAndOrigin(screen, nativePosition);
+ const bool searchScreen = !window || window->isTopLevel();
+ return scaleAndOrigin(screen, searchScreen ? nativePosition : nullptr);
}
#endif //QT_NO_HIGHDPISCALING
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index f58944a7d2..3c85481495 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -313,7 +313,7 @@ public:
static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
static inline QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window) { return pos; }
static inline QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window) { return pos; }
- static inline QDpi logicalDpi() { return QDpi(-1,-1); }
+ static inline QDpi logicalDpi(const QScreen *screen) { return QDpi(-1,-1); }
};
namespace QHighDpi {
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 6f51fe3095..638eb1d12f 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QThreadStorage>
#include <QtCore/QThread>
+#include <QtCore/private/qlocking_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qopengl_p.h>
@@ -1442,7 +1443,7 @@ QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
{
- QMutexLocker locker(&m_mutex);
+ const auto locker = qt_scoped_lock(m_mutex);
m_refs.ref();
m_shares << ctx;
}
@@ -1454,7 +1455,7 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
bool deleteObject = false;
{
- QMutexLocker locker(&m_mutex);
+ const auto locker = qt_scoped_lock(m_mutex);
m_shares.removeOne(ctx);
if (ctx == m_context && !m_shares.isEmpty())
@@ -1502,7 +1503,7 @@ void QOpenGLContextGroupPrivate::cleanup()
void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
{
- QMutexLocker locker(&m_mutex);
+ const auto locker = qt_scoped_lock(m_mutex);
const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
m_pendingDeletion.clear();
@@ -1543,7 +1544,7 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group)
: m_group(group)
{
- QMutexLocker locker(&m_group->d_func()->m_mutex);
+ const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
m_group->d_func()->m_sharedResources << this;
}
@@ -1559,7 +1560,7 @@ void QOpenGLSharedResource::free()
return;
}
- QMutexLocker locker(&m_group->d_func()->m_mutex);
+ const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
m_group->d_func()->m_sharedResources.removeOne(this);
m_group->d_func()->m_pendingDeletion << this;
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 4e95751397..2a0cb1094c 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -348,9 +348,7 @@ void QPlatformWindow::setWindowIcon(const QIcon &icon) { Q_UNUSED(icon); }
*/
bool QPlatformWindow::close()
{
- bool accepted = false;
- QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window(), &accepted);
- return accepted;
+ return QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window());
}
/*!
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 7adf3db1b8..80de561297 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -700,6 +700,25 @@ void QScreenPrivate::updatePrimaryOrientation()
}
/*!
+ Returns the screen at \a point within the set of \l QScreen::virtualSiblings(),
+ or \c nullptr if outside of any screen.
+
+ The \a point is in relation to the virtualGeometry() of each set of virtual
+ siblings.
+
+ \since 5.15
+*/
+QScreen *QScreen::virtualSiblingAt(const QPoint &point)
+{
+ const auto &siblings = virtualSiblings();
+ for (QScreen *sibling : siblings) {
+ if (sibling->geometry().contains(point))
+ return sibling;
+ }
+ return nullptr;
+}
+
+/*!
Creates and returns a pixmap constructed by grabbing the contents
of the given \a window restricted by QRect(\a x, \a y, \a width,
\a height).
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index 14392d3036..88925ab731 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -125,6 +125,7 @@ public:
QRect availableGeometry() const;
QList<QScreen *> virtualSiblings() const;
+ QScreen *virtualSiblingAt(const QPoint &point);
QSize virtualSize() const;
QRect virtualGeometry() const;
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index ea187f54aa..8293fddc59 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -228,7 +228,7 @@ TouchDevices::TouchDevices()
*/
QList<const QTouchDevice *> QTouchDevice::devices()
{
- QMutexLocker lock(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list;
}
@@ -237,13 +237,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
*/
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{
- QMutexLocker locker(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list.contains(dev);
}
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{
- QMutexLocker locker(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
for (const QTouchDevice *dev : qAsConst(deviceList->list))
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev;
@@ -255,7 +255,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
*/
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{
- QMutexLocker lock(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.append(dev);
}
@@ -264,7 +264,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
*/
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
{
- QMutexLocker lock(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.removeOne(dev);
}
diff --git a/src/gui/kernel/qwindowdefs.h b/src/gui/kernel/qwindowdefs.h
index b4f3ed4712..cb0842da8c 100644
--- a/src/gui/kernel/qwindowdefs.h
+++ b/src/gui/kernel/qwindowdefs.h
@@ -43,6 +43,7 @@
#include <QtGui/qtguiglobal.h>
#include <QtCore/qobjectdefs.h>
#include <QtCore/qnamespace.h>
+#include <QtCore/qcontainerfwd.h>
QT_BEGIN_NAMESPACE
@@ -80,7 +81,6 @@ class QString;
class QByteArray;
class QApplication;
-template<typename T> class QList;
typedef QList<QWidget *> QWidgetList;
typedef QList<QWindow *> QWindowList;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 40a298226a..5f61853a6d 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -340,13 +340,11 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleExposeEvent, QWindow *window, const QReg
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
-QT_DEFINE_QPA_EVENT_HANDLER(void, handleCloseEvent, QWindow *window, bool *accepted)
+QT_DEFINE_QPA_EVENT_HANDLER(bool, handleCloseEvent, QWindow *window)
{
- if (window) {
- QWindowSystemInterfacePrivate::CloseEvent *e =
- new QWindowSystemInterfacePrivate::CloseEvent(window, accepted);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
- }
+ Q_ASSERT(window);
+ auto *event = new QWindowSystemInterfacePrivate::CloseEvent(window);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(event);
}
/*!
@@ -619,6 +617,7 @@ bool QWindowSystemInterface::isTouchDeviceRegistered(const QTouchDevice *device)
static int g_nextPointId = 1;
// map from device-independent point id (arbitrary) to "Qt point" ids
+QMutex QWindowSystemInterfacePrivate::pointIdMapMutex;
typedef QMap<quint64, int> PointIdMap;
Q_GLOBAL_STATIC(PointIdMap, g_pointIdMap)
@@ -636,6 +635,8 @@ Q_GLOBAL_STATIC(PointIdMap, g_pointIdMap)
*/
static int acquireCombinedPointId(quint8 deviceId, int pointId)
{
+ QMutexLocker locker(&QWindowSystemInterfacePrivate::pointIdMapMutex);
+
quint64 combinedId64 = (quint64(deviceId) << 32) + pointId;
auto it = g_pointIdMap->constFind(combinedId64);
int uid;
@@ -695,6 +696,8 @@ QList<QTouchEvent::TouchPoint>
}
if (states == Qt::TouchPointReleased) {
+ QMutexLocker locker(&QWindowSystemInterfacePrivate::pointIdMapMutex);
+
// All points on deviceId have been released.
// Remove all points associated with that device from g_pointIdMap.
// (On other devices, some touchpoints might still be pressed.
@@ -714,6 +717,7 @@ QList<QTouchEvent::TouchPoint>
void QWindowSystemInterfacePrivate::clearPointIdMap()
{
+ QMutexLocker locker(&QWindowSystemInterfacePrivate::pointIdMapMutex);
g_pointIdMap->clear();
g_nextPointId = 1;
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index fd70eda9ff..4a0bc858a9 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -194,7 +194,7 @@ public:
static void handleExposeEvent(QWindow *window, const QRegion &region);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
- static void handleCloseEvent(QWindow *window, bool *accepted = nullptr);
+ static bool handleCloseEvent(QWindow *window);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleEnterEvent(QWindow *window, const QPointF &local = QPointF(), const QPointF& global = QPointF());
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index d6513f1836..55fd181ef0 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -123,11 +123,10 @@ public:
class CloseEvent : public WindowSystemEvent {
public:
- explicit CloseEvent(QWindow *w, bool *a = nullptr)
- : WindowSystemEvent(Close), window(w), accepted(a)
+ explicit CloseEvent(QWindow *w)
+ : WindowSystemEvent(Close), window(w)
{ }
QPointer<QWindow> window;
- bool *accepted;
};
class GeometryChangeEvent : public WindowSystemEvent {
@@ -529,6 +528,7 @@ public:
static QWaitCondition eventsFlushed;
static QMutex flushEventMutex;
+ static QMutex pointIdMapMutex;
static QAtomicInt eventAccepted;
static QList<QTouchEvent::TouchPoint>
diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp
index 9f1bb76869..462a4fdb3b 100644
--- a/src/gui/opengl/qopengldebug.cpp
+++ b/src/gui/opengl/qopengldebug.cpp
@@ -1807,7 +1807,7 @@ QList<QOpenGLDebugMessage> QOpenGLDebugLogger::loggedMessages() const
\note Message texts are encoded in UTF-8 when they get passed to OpenGL, so
their size in bytes does not usually match the amount of UTF-16 code units,
- as returned f.i. by QString::length(). (It does if the message contains
+ as returned, for instance, by QString::length(). (It does if the message contains
7-bit ASCII only data, which is typical for debug messages.)
*/
qint64 QOpenGLDebugLogger::maximumMessageLength() const
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index c087326068..47394999c6 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -1474,6 +1474,8 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
#ifndef QT_OPENGL_ES_2
if (!QOpenGLContext::currentContext()->isOpenGLES()) {
Q_D(QOpenGL2PaintEngineEx);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if ((state()->renderHints & QPainter::Antialiasing)
#if QT_DEPRECATED_SINCE(5, 14)
|| (state()->renderHints & QPainter::HighQualityAntialiasing)
@@ -1482,6 +1484,7 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
d->funcs.glEnable(GL_MULTISAMPLE);
else
d->funcs.glDisable(GL_MULTISAMPLE);
+QT_WARNING_POP
}
#endif // QT_OPENGL_ES_2
diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp
index 8d4d8ed183..72bdacf43f 100644
--- a/src/gui/opengl/qopenglprogrambinarycache.cpp
+++ b/src/gui/opengl/qopenglprogrambinarycache.cpp
@@ -44,7 +44,9 @@
#include <QStandardPaths>
#include <QDir>
#include <QSaveFile>
+#include <QCoreApplication>
#include <QLoggingCategory>
+#include <QCryptographicHash>
#ifdef Q_OS_UNIX
#include <sys/mman.h>
@@ -53,7 +55,7 @@
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(DBG_SHADER_CACHE)
+Q_LOGGING_CATEGORY(lcOpenGLProgramDiskCache, "qt.opengl.diskcache")
#ifndef GL_CONTEXT_LOST
#define GL_CONTEXT_LOST 0x0507
@@ -63,6 +65,10 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_SHADER_CACHE)
#define GL_PROGRAM_BINARY_LENGTH 0x8741
#endif
+#ifndef GL_NUM_PROGRAM_BINARY_FORMATS
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#endif
+
const quint32 BINSHADER_MAGIC = 0x5174;
const quint32 BINSHADER_VERSION = 0x3;
const quint32 BINSHADER_QTVERSION = QT_VERSION;
@@ -94,6 +100,15 @@ GLEnvInfo::GLEnvInfo()
glversion = QByteArray(version);
}
+QByteArray QOpenGLProgramBinaryCache::ProgramDesc::cacheKey() const
+{
+ QCryptographicHash keyBuilder(QCryptographicHash::Sha1);
+ for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : shaders)
+ keyBuilder.addData(shader.source);
+
+ return keyBuilder.result().toHex();
+}
+
static inline bool qt_ensureWritableDir(const QString &name)
{
QDir::root().mkpath(name);
@@ -113,7 +128,7 @@ QOpenGLProgramBinaryCache::QOpenGLProgramBinaryCache()
m_cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + subPath;
m_cacheWritable = qt_ensureWritableDir(m_cacheDir);
}
- qCDebug(DBG_SHADER_CACHE, "Cache location '%s' writable = %d", qPrintable(m_cacheDir), m_cacheWritable);
+ qCDebug(lcOpenGLProgramDiskCache, "Cache location '%s' writable = %d", qPrintable(m_cacheDir), m_cacheWritable);
}
QString QOpenGLProgramBinaryCache::cacheFileName(const QByteArray &cacheKey) const
@@ -144,24 +159,24 @@ static inline QByteArray readStr(const uchar **p)
bool QOpenGLProgramBinaryCache::verifyHeader(const QByteArray &buf) const
{
if (buf.size() < BASE_HEADER_SIZE) {
- qCDebug(DBG_SHADER_CACHE, "Cached size too small");
+ qCDebug(lcOpenGLProgramDiskCache, "Cached size too small");
return false;
}
const uchar *p = reinterpret_cast<const uchar *>(buf.constData());
if (readUInt(&p) != BINSHADER_MAGIC) {
- qCDebug(DBG_SHADER_CACHE, "Magic does not match");
+ qCDebug(lcOpenGLProgramDiskCache, "Magic does not match");
return false;
}
if (readUInt(&p) != BINSHADER_VERSION) {
- qCDebug(DBG_SHADER_CACHE, "Version does not match");
+ qCDebug(lcOpenGLProgramDiskCache, "Version does not match");
return false;
}
if (readUInt(&p) != BINSHADER_QTVERSION) {
- qCDebug(DBG_SHADER_CACHE, "Qt version does not match");
+ qCDebug(lcOpenGLProgramDiskCache, "Qt version does not match");
return false;
}
if (readUInt(&p) != sizeof(quintptr)) {
- qCDebug(DBG_SHADER_CACHE, "Architecture does not match");
+ qCDebug(lcOpenGLProgramDiskCache, "Architecture does not match");
return false;
}
return true;
@@ -186,7 +201,7 @@ bool QOpenGLProgramBinaryCache::setProgramBinary(uint programId, uint blobFormat
GLenum err = funcs->glGetError();
if (err != GL_NO_ERROR) {
- qCDebug(DBG_SHADER_CACHE, "Program binary failed to load for program %u, size %d, "
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary failed to load for program %u, size %d, "
"format 0x%x, err = 0x%x",
programId, blobSize, blobFormat, err);
return false;
@@ -194,13 +209,13 @@ bool QOpenGLProgramBinaryCache::setProgramBinary(uint programId, uint blobFormat
GLint linkStatus = 0;
funcs->glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
- qCDebug(DBG_SHADER_CACHE, "Program binary failed to load for program %u, size %d, "
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary failed to load for program %u, size %d, "
"format 0x%x, linkStatus = 0x%x, err = 0x%x",
programId, blobSize, blobFormat, linkStatus, err);
return false;
}
- qCDebug(DBG_SHADER_CACHE, "Program binary set for program %u, size %d, format 0x%x, err = 0x%x",
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary set for program %u, size %d, format 0x%x, err = 0x%x",
programId, blobSize, blobFormat, err);
return true;
}
@@ -263,10 +278,9 @@ public:
bool QOpenGLProgramBinaryCache::load(const QByteArray &cacheKey, uint programId)
{
- if (m_memCache.contains(cacheKey)) {
- const MemCacheEntry *e = m_memCache[cacheKey];
+ QMutexLocker lock(&m_mutex);
+ if (const MemCacheEntry *e = m_memCache.object(cacheKey))
return setProgramBinary(programId, e->format, e->blob.constData(), e->blob.size());
- }
QByteArray buf;
const QString fn = cacheFileName(cacheKey);
@@ -309,19 +323,19 @@ bool QOpenGLProgramBinaryCache::load(const QByteArray &cacheKey, uint programId)
if (vendor != info.glvendor) {
// readStr returns non-null terminated strings just pointing to inside
// 'p' so must print these via the stream qCDebug and not constData().
- qCDebug(DBG_SHADER_CACHE) << "GL_VENDOR does not match" << vendor << info.glvendor;
+ qCDebug(lcOpenGLProgramDiskCache) << "GL_VENDOR does not match" << vendor << info.glvendor;
undertaker.setActive();
return false;
}
QByteArray renderer = readStr(&p);
if (renderer != info.glrenderer) {
- qCDebug(DBG_SHADER_CACHE) << "GL_RENDERER does not match" << renderer << info.glrenderer;
+ qCDebug(lcOpenGLProgramDiskCache) << "GL_RENDERER does not match" << renderer << info.glrenderer;
undertaker.setActive();
return false;
}
QByteArray version = readStr(&p);
if (version != info.glversion) {
- qCDebug(DBG_SHADER_CACHE) << "GL_VERSION does not match" << version << info.glversion;
+ qCDebug(lcOpenGLProgramDiskCache) << "GL_VERSION does not match" << version << info.glversion;
undertaker.setActive();
return false;
}
@@ -374,7 +388,7 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId)
const int totalSize = headerSize + paddingSize + blobSize;
- qCDebug(DBG_SHADER_CACHE, "Program binary is %d bytes, err = 0x%x, total %d", blobSize, funcs->glGetError(), totalSize);
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary is %d bytes, err = 0x%x, total %d", blobSize, funcs->glGetError(), totalSize);
if (!blobSize)
return;
@@ -401,13 +415,14 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId)
GLint outSize = 0;
#if defined(QT_OPENGL_ES_2)
if (context->isOpenGLES() && context->format().majorVersion() < 3) {
+ QMutexLocker lock(&m_mutex);
initializeProgramBinaryOES(context);
getProgramBinaryOES(programId, blobSize, &outSize, &blobFormat, p);
} else
#endif
funcs->glGetProgramBinary(programId, blobSize, &outSize, &blobFormat, p);
if (blobSize != outSize) {
- qCDebug(DBG_SHADER_CACHE, "glGetProgramBinary returned size %d instead of %d", outSize, blobSize);
+ qCDebug(lcOpenGLProgramDiskCache, "glGetProgramBinary returned size %d instead of %d", outSize, blobSize);
return;
}
@@ -423,9 +438,9 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId)
if (f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
if (f.write(blob) < blob.length())
#endif
- qCDebug(DBG_SHADER_CACHE, "Failed to write %s to shader cache", qPrintable(f.fileName()));
+ qCDebug(lcOpenGLProgramDiskCache, "Failed to write %s to shader cache", qPrintable(f.fileName()));
} else {
- qCDebug(DBG_SHADER_CACHE, "Failed to create %s in shader cache", qPrintable(f.fileName()));
+ qCDebug(lcOpenGLProgramDiskCache, "Failed to create %s in shader cache", qPrintable(f.fileName()));
}
}
@@ -442,4 +457,45 @@ void QOpenGLProgramBinaryCache::initializeProgramBinaryOES(QOpenGLContext *conte
}
#endif
+QOpenGLProgramBinarySupportCheck::QOpenGLProgramBinarySupportCheck(QOpenGLContext *context)
+ : QOpenGLSharedResource(context->shareGroup()),
+ m_supported(false)
+{
+ if (QCoreApplication::testAttribute(Qt::AA_DisableShaderDiskCache)) {
+ qCDebug(lcOpenGLProgramDiskCache, "Shader cache disabled via app attribute");
+ return;
+ }
+ if (qEnvironmentVariableIntValue("QT_DISABLE_SHADER_DISK_CACHE")) {
+ qCDebug(lcOpenGLProgramDiskCache, "Shader cache disabled via env var");
+ return;
+ }
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx) {
+ if (ctx->isOpenGLES()) {
+ qCDebug(lcOpenGLProgramDiskCache, "OpenGL ES v%d context", ctx->format().majorVersion());
+ if (ctx->format().majorVersion() >= 3) {
+ m_supported = true;
+ } else {
+ const bool hasExt = ctx->hasExtension("GL_OES_get_program_binary");
+ qCDebug(lcOpenGLProgramDiskCache, "GL_OES_get_program_binary support = %d", hasExt);
+ if (hasExt)
+ m_supported = true;
+ }
+ } else {
+ const bool hasExt = ctx->hasExtension("GL_ARB_get_program_binary");
+ qCDebug(lcOpenGLProgramDiskCache, "GL_ARB_get_program_binary support = %d", hasExt);
+ if (hasExt)
+ m_supported = true;
+ }
+ if (m_supported) {
+ GLint fmtCount = 0;
+ ctx->functions()->glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &fmtCount);
+ qCDebug(lcOpenGLProgramDiskCache, "Supported binary format count = %d", fmtCount);
+ m_supported = fmtCount > 0;
+ }
+ }
+ qCDebug(lcOpenGLProgramDiskCache, "Shader cache supported = %d", m_supported);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglprogrambinarycache_p.h b/src/gui/opengl/qopenglprogrambinarycache_p.h
index 9fade08e66..f1cf24cd87 100644
--- a/src/gui/opengl/qopenglprogrambinarycache_p.h
+++ b/src/gui/opengl/qopenglprogrambinarycache_p.h
@@ -52,24 +52,31 @@
//
#include <QtGui/qtguiglobal.h>
-#include <QtGui/qopenglshaderprogram.h>
#include <QtCore/qcache.h>
+#include <QtCore/qmutex.h>
+#include <QtGui/private/qopenglcontext_p.h>
+#include <QtGui/private/qshader_p.h>
QT_BEGIN_NAMESPACE
+// These classes are also used by the OpenGL backend of QRhi. They must
+// therefore stay independent from QOpenGLShader(Program). Must rely only on
+// QOpenGLContext/Functions.
+
class QOpenGLProgramBinaryCache
{
public:
struct ShaderDesc {
ShaderDesc() { }
- ShaderDesc(QOpenGLShader::ShaderType type, const QByteArray &source = QByteArray())
- : type(type), source(source)
+ ShaderDesc(QShader::Stage stage, const QByteArray &source = QByteArray())
+ : stage(stage), source(source)
{ }
- QOpenGLShader::ShaderType type;
+ QShader::Stage stage;
QByteArray source;
};
struct ProgramDesc {
QVector<ShaderDesc> shaders;
+ QByteArray cacheKey() const;
};
QOpenGLProgramBinaryCache();
@@ -99,6 +106,37 @@ private:
void initializeProgramBinaryOES(QOpenGLContext *context);
bool m_programBinaryOESInitialized = false;
#endif
+ QMutex m_mutex;
+};
+
+// While unlikely, one application can in theory use contexts with different versions
+// or profiles. Therefore any version- or extension-specific checks must be done on a
+// per-context basis, not just once per process. QOpenGLSharedResource enables this,
+// although it's once-per-sharing-context-group, not per-context. Still, this should
+// be good enough in practice.
+class QOpenGLProgramBinarySupportCheck : public QOpenGLSharedResource
+{
+public:
+ QOpenGLProgramBinarySupportCheck(QOpenGLContext *context);
+ void invalidateResource() override { }
+ void freeResource(QOpenGLContext *) override { }
+
+ bool isSupported() const { return m_supported; }
+
+private:
+ bool m_supported;
+};
+
+class QOpenGLProgramBinarySupportCheckWrapper
+{
+public:
+ QOpenGLProgramBinarySupportCheck *get(QOpenGLContext *context)
+ {
+ return m_resource.value<QOpenGLProgramBinarySupportCheck>(context);
+ }
+
+private:
+ QOpenGLMultiGroupSharedResource m_resource;
};
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index 3c7bd4f90d..4986ca573d 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -47,8 +47,6 @@
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
#include <QtCore/qloggingcategory.h>
-#include <QtCore/qcryptographichash.h>
-#include <QtCore/qcoreapplication.h>
#include <QtGui/qtransform.h>
#include <QtGui/QColor>
#include <QtGui/QSurfaceFormat>
@@ -179,7 +177,7 @@ QT_BEGIN_NAMESPACE
(requires OpenGL >= 4.3 or OpenGL ES >= 3.1).
*/
-Q_LOGGING_CATEGORY(DBG_SHADER_CACHE, "qt.opengl.diskcache")
+Q_DECLARE_LOGGING_CATEGORY(lcOpenGLProgramDiskCache)
// For GLES 3.1/3.2
#ifndef GL_GEOMETRY_SHADER
@@ -210,10 +208,6 @@ Q_LOGGING_CATEGORY(DBG_SHADER_CACHE, "qt.opengl.diskcache")
#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
#endif
-#ifndef GL_NUM_PROGRAM_BINARY_FORMATS
-#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
-#endif
-
#ifndef QT_OPENGL_ES_2
static inline bool isFormatGLES(const QSurfaceFormat &f)
{
@@ -1081,6 +1075,44 @@ bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::Shade
return addCacheableShaderFromSourceCode(type, QByteArray(source));
}
+static inline QShader::Stage qt_shaderTypeToStage(QOpenGLShader::ShaderType type)
+{
+ switch (type) {
+ case QOpenGLShader::Vertex:
+ return QShader::VertexStage;
+ case QOpenGLShader::Fragment:
+ return QShader::FragmentStage;
+ case QOpenGLShader::Geometry:
+ return QShader::GeometryStage;
+ case QOpenGLShader::TessellationControl:
+ return QShader::TessellationControlStage;
+ case QOpenGLShader::TessellationEvaluation:
+ return QShader::TessellationEvaluationStage;
+ case QOpenGLShader::Compute:
+ return QShader::ComputeStage;
+ }
+ return QShader::VertexStage;
+}
+
+static inline QOpenGLShader::ShaderType qt_shaderStageToType(QShader::Stage stage)
+{
+ switch (stage) {
+ case QShader::VertexStage:
+ return QOpenGLShader::Vertex;
+ case QShader::TessellationControlStage:
+ return QOpenGLShader::TessellationControl;
+ case QShader::TessellationEvaluationStage:
+ return QOpenGLShader::TessellationEvaluation;
+ case QShader::GeometryStage:
+ return QOpenGLShader::Geometry;
+ case QShader::FragmentStage:
+ return QOpenGLShader::Fragment;
+ case QShader::ComputeStage:
+ return QOpenGLShader::Compute;
+ }
+ return QOpenGLShader::Vertex;
+}
+
/*!
\overload
@@ -1109,7 +1141,7 @@ bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::Shade
if (d->isCacheDisabled())
return addShaderFromSourceCode(type, source);
- d->binaryProgram.shaders.append(QOpenGLProgramBinaryCache::ShaderDesc(type, source));
+ d->binaryProgram.shaders.append(QOpenGLProgramBinaryCache::ShaderDesc(qt_shaderTypeToStage(type), source));
return true;
}
@@ -1166,7 +1198,7 @@ bool QOpenGLShaderProgram::addCacheableShaderFromSourceFile(QOpenGLShader::Shade
if (d->isCacheDisabled())
return addShaderFromSourceFile(type, fileName);
- QOpenGLProgramBinaryCache::ShaderDesc shader(type);
+ QOpenGLProgramBinaryCache::ShaderDesc shader(qt_shaderTypeToStage(type));
// NB! It could be tempting to defer reading the file contents and just
// hash the filename as the cache key, perhaps combined with last-modified
// timestamp checks. However, this would raise a number of issues (no
@@ -3720,77 +3752,6 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
return true;
}
-// While unlikely, one application can in theory use contexts with different versions
-// or profiles. Therefore any version- or extension-specific checks must be done on a
-// per-context basis, not just once per process. QOpenGLSharedResource enables this,
-// although it's once-per-sharing-context-group, not per-context. Still, this should
-// be good enough in practice.
-class QOpenGLProgramBinarySupportCheck : public QOpenGLSharedResource
-{
-public:
- QOpenGLProgramBinarySupportCheck(QOpenGLContext *context);
- void invalidateResource() override { }
- void freeResource(QOpenGLContext *) override { }
-
- bool isSupported() const { return m_supported; }
-
-private:
- bool m_supported;
-};
-
-QOpenGLProgramBinarySupportCheck::QOpenGLProgramBinarySupportCheck(QOpenGLContext *context)
- : QOpenGLSharedResource(context->shareGroup()),
- m_supported(false)
-{
- if (QCoreApplication::testAttribute(Qt::AA_DisableShaderDiskCache)) {
- qCDebug(DBG_SHADER_CACHE, "Shader cache disabled via app attribute");
- return;
- }
- if (qEnvironmentVariableIntValue("QT_DISABLE_SHADER_DISK_CACHE")) {
- qCDebug(DBG_SHADER_CACHE, "Shader cache disabled via env var");
- return;
- }
-
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- if (ctx) {
- if (ctx->isOpenGLES()) {
- qCDebug(DBG_SHADER_CACHE, "OpenGL ES v%d context", ctx->format().majorVersion());
- if (ctx->format().majorVersion() >= 3) {
- m_supported = true;
- } else {
- const bool hasExt = ctx->hasExtension("GL_OES_get_program_binary");
- qCDebug(DBG_SHADER_CACHE, "GL_OES_get_program_binary support = %d", hasExt);
- if (hasExt)
- m_supported = true;
- }
- } else {
- const bool hasExt = ctx->hasExtension("GL_ARB_get_program_binary");
- qCDebug(DBG_SHADER_CACHE, "GL_ARB_get_program_binary support = %d", hasExt);
- if (hasExt)
- m_supported = true;
- }
- if (m_supported) {
- GLint fmtCount = 0;
- ctx->functions()->glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &fmtCount);
- qCDebug(DBG_SHADER_CACHE, "Supported binary format count = %d", fmtCount);
- m_supported = fmtCount > 0;
- }
- }
- qCDebug(DBG_SHADER_CACHE, "Shader cache supported = %d", m_supported);
-}
-
-class QOpenGLProgramBinarySupportCheckWrapper
-{
-public:
- QOpenGLProgramBinarySupportCheck *get(QOpenGLContext *context)
- {
- return m_resource.value<QOpenGLProgramBinarySupportCheck>(context);
- }
-
-private:
- QOpenGLMultiGroupSharedResource m_resource;
-};
-
bool QOpenGLShaderProgramPrivate::isCacheDisabled() const
{
static QOpenGLProgramBinarySupportCheckWrapper binSupportCheck;
@@ -3801,7 +3762,7 @@ bool QOpenGLShaderProgramPrivate::compileCacheable()
{
Q_Q(QOpenGLShaderProgram);
for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders)) {
- QScopedPointer<QOpenGLShader> s(new QOpenGLShader(shader.type, q));
+ QScopedPointer<QOpenGLShader> s(new QOpenGLShader(qt_shaderStageToType(shader.stage), q));
if (!s->compileSourceCode(shader.source)) {
log = s->log();
return false;
@@ -3819,24 +3780,20 @@ bool QOpenGLShaderProgramPrivate::linkBinary()
Q_Q(QOpenGLShaderProgram);
- QCryptographicHash keyBuilder(QCryptographicHash::Sha1);
- for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders))
- keyBuilder.addData(shader.source);
-
- const QByteArray cacheKey = keyBuilder.result().toHex();
- if (DBG_SHADER_CACHE().isEnabled(QtDebugMsg))
- qCDebug(DBG_SHADER_CACHE, "program with %d shaders, cache key %s",
+ const QByteArray cacheKey = binaryProgram.cacheKey();
+ if (lcOpenGLProgramDiskCache().isEnabled(QtDebugMsg))
+ qCDebug(lcOpenGLProgramDiskCache, "program with %d shaders, cache key %s",
binaryProgram.shaders.count(), cacheKey.constData());
bool needsCompile = true;
if (binCache.load(cacheKey, q->programId())) {
- qCDebug(DBG_SHADER_CACHE, "Program binary received from cache");
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary received from cache");
needsCompile = false;
}
bool needsSave = false;
if (needsCompile) {
- qCDebug(DBG_SHADER_CACHE, "Program binary not in cache, compiling");
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary not in cache, compiling");
if (compileCacheable())
needsSave = true;
else
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 61a6202017..ed58766dde 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -4612,7 +4612,7 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire
\note This function has no effect on Mac and Qt built for OpenGL ES 2.
\sa borderColor()
*/
-void QOpenGLTexture::setBorderColor(QColor color)
+void QOpenGLTexture::setBorderColor(const QColor &color)
{
setBorderColor(static_cast<float>(color.redF()), static_cast<float>(color.greenF()),
static_cast<float>(color.blueF()), static_cast<float>(color.alphaF()));
diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h
index 7d984babc8..539b6aa7b2 100644
--- a/src/gui/opengl/qopengltexture.h
+++ b/src/gui/opengl/qopengltexture.h
@@ -621,7 +621,7 @@ public:
void setWrapMode(CoordinateDirection direction, WrapMode mode);
WrapMode wrapMode(CoordinateDirection direction) const;
- void setBorderColor(QColor color);
+ void setBorderColor(const QColor &color);
void setBorderColor(float r, float g, float b, float a);
void setBorderColor(int r, int g, int b, int a);
void setBorderColor(uint r, uint g, uint b, uint a);
diff --git a/src/gui/painting/XCONSORTIUM_LICENSE.txt b/src/gui/painting/XCONSORTIUM_LICENSE.txt
new file mode 100644
index 0000000000..5d98625787
--- /dev/null
+++ b/src/gui/painting/XCONSORTIUM_LICENSE.txt
@@ -0,0 +1,43 @@
+Copyright (c) 1987, 1988 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 3240b83451..b0393aff95 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -95,6 +95,11 @@ public:
QBackingStore::QBackingStore(QWindow *window)
: d_ptr(new QBackingStorePrivate(window))
{
+ if (window->handle()) {
+ // Create platform backingstore up front if we have a platform window,
+ // otherwise delay the creation until absolutely necessary.
+ handle();
+ }
}
/*!
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index 9861fffff3..7622262da9 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -106,10 +106,10 @@ void QBezier::addToPolygon(QPolygonF *polygon, qreal bezier_flattening_threshold
int levels[10];
beziers[0] = *this;
levels[0] = 9;
- QBezier *b = beziers;
- int *lvl = levels;
+ int top = 0;
- while (b >= beziers) {
+ while (top >= 0) {
+ QBezier *b = &beziers[top];
// check if we can pop the top bezier curve from the stack
qreal y4y1 = b->y4 - b->y1;
qreal x4x1 = b->x4 - b->x1;
@@ -123,17 +123,15 @@ void QBezier::addToPolygon(QPolygonF *polygon, qreal bezier_flattening_threshold
qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
l = 1.;
}
- if (d < bezier_flattening_threshold*l || *lvl == 0) {
+ if (d < bezier_flattening_threshold * l || levels[top] == 0) {
// good enough, we pop it off and add the endpoint
polygon->append(QPointF(b->x4, b->y4));
- --b;
- --lvl;
+ --top;
} else {
// split, second half of the polygon goes lower into the stack
std::tie(b[1], b[0]) = b->split();
- lvl[1] = --lvl[0];
- ++b;
- ++lvl;
+ levels[top + 1] = --levels[top];
+ ++top;
}
}
}
@@ -144,10 +142,10 @@ void QBezier::addToPolygon(QDataBuffer<QPointF> &polygon, qreal bezier_flattenin
int levels[10];
beziers[0] = *this;
levels[0] = 9;
- QBezier *b = beziers;
- int *lvl = levels;
+ int top = 0;
- while (b >= beziers) {
+ while (top >= 0) {
+ QBezier *b = &beziers[top];
// check if we can pop the top bezier curve from the stack
qreal y4y1 = b->y4 - b->y1;
qreal x4x1 = b->x4 - b->x1;
@@ -161,17 +159,15 @@ void QBezier::addToPolygon(QDataBuffer<QPointF> &polygon, qreal bezier_flattenin
qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
l = 1.;
}
- if (d < bezier_flattening_threshold*l || *lvl == 0) {
+ if (d < bezier_flattening_threshold * l || levels[top] == 0) {
// good enough, we pop it off and add the endpoint
polygon.add(QPointF(b->x4, b->y4));
- --b;
- --lvl;
+ --top;
} else {
// split, second half of the polygon goes lower into the stack
std::tie(b[1], b[0]) = b->split();
- lvl[1] = --lvl[0];
- ++b;
- ++lvl;
+ levels[top + 1] = --levels[top];
+ ++top;
}
}
}
diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h
index 66db95df7e..edb2d32258 100644
--- a/src/gui/painting/qcolormatrix_p.h
+++ b/src/gui/painting/qcolormatrix_p.h
@@ -62,17 +62,16 @@ class QColorVector
{
public:
QColorVector() = default;
- Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z), _unused(0.0f) { }
+ Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z) { }
explicit Q_DECL_CONSTEXPR QColorVector(const QPointF &chr) // from XY chromaticity
: x(chr.x() / chr.y())
, y(1.0f)
, z((1.0 - chr.x() - chr.y()) / chr.y())
- , _unused(0.0f)
{ }
- float x; // X, x or red
- float y; // Y, y or green
- float z; // Z, Y or blue
- float _unused;
+ float x = 0.0f; // X, x or red
+ float y = 0.0f; // Y, y or green
+ float z = 0.0f; // Z, Y or blue
+ float _unused = 0.0f;
friend inline bool operator==(const QColorVector &v1, const QColorVector &v2);
friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2);
@@ -81,7 +80,6 @@ public:
return !x && !y && !z;
}
- static Q_DECL_CONSTEXPR QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); }
static bool isValidChromaticity(const QPointF &chr)
{
if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0))
@@ -187,10 +185,6 @@ public:
{ r.z, g.z, b.z } };
}
- static QColorMatrix null()
- {
- return { QColorVector::null(), QColorVector::null(), QColorVector::null() };
- }
static QColorMatrix identity()
{
return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
@@ -226,12 +220,6 @@ public:
{ 0.1351922452f, 0.7118769884f, 0.0000000000f },
{ 0.0313525312f, 0.0000856627f, 0.8251883388f } };
}
- static QColorMatrix toXyzFromBt2020()
- {
- return QColorMatrix { { 0.6506130099f, 0.2695676684f, -0.0018652577f },
- { 0.1865101457f, 0.6840794086f, 0.0172256753f },
- { 0.1270887405f, 0.0463530831f, 0.8098278046f } };
- }
};
inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2)
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index 86d0c57cfe..937bb505c9 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -70,12 +70,6 @@ QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Primaries primaries)
bluePoint = QPointF(0.150, 0.060);
whitePoint = QColorVector::D65Chromaticity();
break;
- case QColorSpace::Primaries::Bt2020:
- redPoint = QPointF(0.708, 0.292);
- greenPoint = QPointF(0.190, 0.797);
- bluePoint = QPointF(0.131, 0.046);
- whitePoint = QColorVector::D65Chromaticity();
- break;
case QColorSpace::Primaries::AdobeRgb:
redPoint = QPointF(0.640, 0.330);
greenPoint = QPointF(0.210, 0.710);
@@ -152,25 +146,13 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const
}
QColorSpacePrivate::QColorSpacePrivate()
- : id(QColorSpace::Unknown)
- , primaries(QColorSpace::Primaries::Custom)
- , transferFunction(QColorSpace::TransferFunction::Custom)
- , gamma(0.0f)
- , whitePoint(QColorVector::null())
- , toXyz(QColorMatrix::null())
{
}
-QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId)
- : id(colorSpaceId)
- , gamma(0.0f)
+QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace)
+ : namedColorSpace(namedColorSpace)
{
- switch (colorSpaceId) {
- case QColorSpace::Undefined:
- primaries = QColorSpace::Primaries::Custom;
- transferFunction = QColorSpace::TransferFunction::Custom;
- description = QStringLiteral("Undefined");
- break;
+ switch (namedColorSpace) {
case QColorSpace::SRgb:
primaries = QColorSpace::Primaries::SRgb;
transferFunction = QColorSpace::TransferFunction::SRgb;
@@ -197,14 +179,6 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId)
transferFunction = QColorSpace::TransferFunction::ProPhotoRgb;
description = QStringLiteral("ProPhoto RGB");
break;
- case QColorSpace::Bt2020:
- primaries = QColorSpace::Primaries::Bt2020;
- transferFunction = QColorSpace::TransferFunction::Bt2020;
- description = QStringLiteral("BT.2020");
- break;
- case QColorSpace::Unknown:
- qWarning("Can not create an unknown color space");
- Q_FALLTHROUGH();
default:
Q_UNREACHABLE();
}
@@ -216,8 +190,7 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, QColorS
, transferFunction(fun)
, gamma(gamma)
{
- if (!identifyColorSpace())
- id = QColorSpace::Unknown;
+ identifyColorSpace();
initialize();
}
@@ -235,71 +208,63 @@ QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries,
setTransferFunction();
}
-bool QColorSpacePrivate::identifyColorSpace()
+void QColorSpacePrivate::identifyColorSpace()
{
switch (primaries) {
case QColorSpace::Primaries::SRgb:
if (transferFunction == QColorSpace::TransferFunction::SRgb) {
- id = QColorSpace::SRgb;
+ namedColorSpace = QColorSpace::SRgb;
if (description.isEmpty())
description = QStringLiteral("sRGB");
- return true;
+ return;
}
if (transferFunction == QColorSpace::TransferFunction::Linear) {
- id = QColorSpace::SRgbLinear;
+ namedColorSpace = QColorSpace::SRgbLinear;
if (description.isEmpty())
description = QStringLiteral("Linear sRGB");
- return true;
+ return;
}
break;
case QColorSpace::Primaries::AdobeRgb:
if (transferFunction == QColorSpace::TransferFunction::Gamma) {
if (qAbs(gamma - 2.19921875f) < (1/1024.0f)) {
- id = QColorSpace::AdobeRgb;
+ namedColorSpace = QColorSpace::AdobeRgb;
if (description.isEmpty())
description = QStringLiteral("Adobe RGB");
- return true;
+ return;
}
}
break;
case QColorSpace::Primaries::DciP3D65:
if (transferFunction == QColorSpace::TransferFunction::SRgb) {
- id = QColorSpace::DisplayP3;
+ namedColorSpace = QColorSpace::DisplayP3;
if (description.isEmpty())
description = QStringLiteral("Display P3");
- return true;
+ return;
}
break;
case QColorSpace::Primaries::ProPhotoRgb:
if (transferFunction == QColorSpace::TransferFunction::ProPhotoRgb) {
- id = QColorSpace::ProPhotoRgb;
+ namedColorSpace = QColorSpace::ProPhotoRgb;
if (description.isEmpty())
description = QStringLiteral("ProPhoto RGB");
- return true;
+ return;
}
if (transferFunction == QColorSpace::TransferFunction::Gamma) {
// ProPhoto RGB's curve is effectively gamma 1.8 for 8bit precision.
if (qAbs(gamma - 1.8f) < (1/1024.0f)) {
- id = QColorSpace::ProPhotoRgb;
+ namedColorSpace = QColorSpace::ProPhotoRgb;
if (description.isEmpty())
description = QStringLiteral("ProPhoto RGB");
- return true;
+ return;
}
}
break;
- case QColorSpace::Primaries::Bt2020:
- if (transferFunction == QColorSpace::TransferFunction::Bt2020) {
- id = QColorSpace::Bt2020;
- if (description.isEmpty())
- description = QStringLiteral("BT.2020");
- return true;
- }
- break;
default:
break;
}
- id = QColorSpace::Unknown;
- return false;
+
+ namedColorSpace = Unknown;
}
void QColorSpacePrivate::initialize()
@@ -311,7 +276,7 @@ void QColorSpacePrivate::initialize()
void QColorSpacePrivate::setToXyzMatrix()
{
if (primaries == QColorSpace::Primaries::Custom) {
- toXyz = QColorMatrix::null();
+ toXyz = QColorMatrix();
whitePoint = QColorVector::D50();
return;
}
@@ -345,12 +310,6 @@ void QColorSpacePrivate::setTransferFunction()
if (qFuzzyIsNull(gamma))
gamma = 1.8f;
break;
- case QColorSpace::TransferFunction::Bt2020:
- trc[0].m_type = QColorTrc::Type::Function;
- trc[0].m_fun = QColorTransferFunction::fromBt2020();
- if (qFuzzyIsNull(gamma))
- gamma = 1.961f;
- break;
case QColorSpace::TransferFunction::Custom:
break;
default:
@@ -410,12 +369,10 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
/*!
- \enum QColorSpace::ColorSpaceId
+ \enum QColorSpace::NamedColorSpace
Predefined color spaces.
- \value Undefined An empty, invalid or unsupported color space.
- \value Unknown A valid color space that doesn't match any of the predefined color spaces.
\value SRgb The sRGB color space, which Qt operates in by default. It is a close approximation
of how most classic monitors operate, and a mode most software and hardware support.
\l{http://www.color.org/chardata/rgb/srgb.xalter}{ICC registration of sRGB}.
@@ -427,8 +384,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\l{http://www.color.org/chardata/rgb/DCIP3.xalter}{ICC registration of DCI-P3}
\value ProPhotoRgb The Pro Photo RGB color space, also known as ROMM RGB is a very wide gamut color space.
\l{http://www.color.org/chardata/rgb/rommrgb.xalter}{ICC registration of ROMM RGB}
- \value Bt2020 BT.2020 also known as Rec.2020 is the color space of HDR TVs.
- \l{http://www.color.org/chardata/rgb/BT2020.xalter}{ICC registration of BT.2020}
*/
/*!
@@ -441,7 +396,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\value AdobeRgb The Adobe RGB primaries
\value DciP3D65 The DCI-P3 primaries with the D65 whitepoint
\value ProPhotoRgb The ProPhoto RGB primaries with the D50 whitepoint
- \value Bt2020 The BT.2020 primaries
*/
/*!
@@ -454,26 +408,28 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\value Gamma A transfer function that is a real gamma curve based on the value of gamma()
\value SRgb The sRGB transfer function, composed of linear and gamma parts
\value ProPhotoRgb The ProPhoto RGB transfer function, composed of linear and gamma parts
- \value Bt2020 The BT.2020 transfer function, composed of linear and gamma parts
*/
/*!
- Creates a new colorspace object that represents \a colorSpaceId.
+ Creates a new colorspace object that represents an undefined and invalid colorspace.
*/
-QColorSpace::QColorSpace(QColorSpace::ColorSpaceId colorSpaceId)
- : d_ptr(nullptr)
-{
- static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::Bt2020];
- // Unknown and undefined both returns the static undefined colorspace
- if (colorSpaceId > QColorSpace::Unknown) {
- if (!predefinedColorspacePrivates[colorSpaceId - 2]) {
- predefinedColorspacePrivates[colorSpaceId - 2] = new QColorSpacePrivate(colorSpaceId);
- predefinedColorspacePrivates[colorSpaceId - 2]->ref.ref();
- }
- d_ptr = predefinedColorspacePrivates[colorSpaceId - 2];
- d_ptr->ref.ref();
- Q_ASSERT(isValid());
+QColorSpace::QColorSpace()
+{
+}
+
+/*!
+ Creates a new colorspace object that represents a \a namedColorSpace.
+ */
+QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
+{
+ static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::ProPhotoRgb + 1];
+ if (!predefinedColorspacePrivates[namedColorSpace]) {
+ predefinedColorspacePrivates[namedColorSpace] = new QColorSpacePrivate(namedColorSpace);
+ predefinedColorspacePrivates[namedColorSpace]->ref.ref();
}
+ d_ptr = predefinedColorspacePrivates[namedColorSpace];
+ d_ptr->ref.ref();
+ Q_ASSERT(isValid());
}
/*!
@@ -545,17 +501,6 @@ QColorSpace &QColorSpace::operator=(const QColorSpace &colorSpace)
*/
/*!
- Returns the id of the predefined color space this object
- represents or \c Unknown if it doesn't match any of them.
-*/
-QColorSpace::ColorSpaceId QColorSpace::colorSpaceId() const noexcept
-{
- if (Q_UNLIKELY(!d_ptr))
- return QColorSpace::Undefined;
- return d_ptr->id;
-}
-
-/*!
Returns the predefined primaries of the color space
or \c primaries::Custom if it doesn't match any of them.
*/
@@ -596,8 +541,6 @@ float QColorSpace::gamma() const noexcept
/*!
Sets the transfer function to \a transferFunction and \a gamma.
- \note This also changes colorSpaceId().
-
\sa transferFunction(), gamma(), withTransferFunction()
*/
void QColorSpace::setTransferFunction(QColorSpace::TransferFunction transferFunction, float gamma)
@@ -634,8 +577,6 @@ QColorSpace QColorSpace::withTransferFunction(QColorSpace::TransferFunction tran
/*!
Sets the primaries to those of the \a primariesId set.
- \note This also changes colorSpaceId().
-
\sa primaries()
*/
void QColorSpace::setPrimaries(QColorSpace::Primaries primariesId)
@@ -655,8 +596,6 @@ void QColorSpace::setPrimaries(QColorSpace::Primaries primariesId)
Set primaries to the chromaticities of \a whitePoint, \a redPoint, \a greenPoint
and \a bluePoint.
- \note This also changes colorSpaceId().
-
\sa primaries()
*/
void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoint,
@@ -718,7 +657,6 @@ QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
if (QIcc::fromIccProfile(iccProfile, &colorSpace))
return colorSpace;
QColorSpacePrivate *d = QColorSpacePrivate::getWritable(colorSpace);
- d->id = QColorSpace::Undefined;
d->iccProfile = iccProfile;
return colorSpace;
}
@@ -728,7 +666,8 @@ QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
*/
bool QColorSpace::isValid() const noexcept
{
- return d_ptr && d_ptr->id != QColorSpace::Undefined && d_ptr->toXyz.isValid()
+ return d_ptr
+ && d_ptr->toXyz.isValid()
&& d_ptr->trc[0].isValid() && d_ptr->trc[1].isValid() && d_ptr->trc[2].isValid();
}
@@ -744,11 +683,17 @@ bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2)
if (!colorSpace1.d_ptr || !colorSpace2.d_ptr)
return false;
- if (colorSpace1.colorSpaceId() == QColorSpace::Undefined && colorSpace2.colorSpaceId() == QColorSpace::Undefined)
+ if (colorSpace1.d_ptr->namedColorSpace && colorSpace2.d_ptr->namedColorSpace)
+ return colorSpace1.d_ptr->namedColorSpace == colorSpace2.d_ptr->namedColorSpace;
+
+ const bool valid1 = colorSpace1.isValid();
+ const bool valid2 = colorSpace2.isValid();
+ if (!valid1 && !valid2)
return colorSpace1.d_ptr->iccProfile == colorSpace2.d_ptr->iccProfile;
+ else if (!valid1 || !valid2)
+ return false;
- if (colorSpace1.colorSpaceId() != QColorSpace::Unknown && colorSpace2.colorSpaceId() != QColorSpace::Unknown)
- return colorSpace1.colorSpaceId() == colorSpace2.colorSpaceId();
+ // At this point one or both color spaces are unknown but valid, and must be compared in detail instead
if (colorSpace1.primaries() != QColorSpace::Primaries::Custom && colorSpace2.primaries() != QColorSpace::Primaries::Custom) {
if (colorSpace1.primaries() != colorSpace2.primaries())
@@ -839,7 +784,9 @@ QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace)
QDebugStateSaver saver(dbg);
dbg.nospace();
dbg << "QColorSpace(";
- dbg << colorSpace.colorSpaceId() << ", " << colorSpace.primaries() << ", " << colorSpace.transferFunction();
+ if (colorSpace.d_ptr->namedColorSpace)
+ dbg << colorSpace.d_ptr->namedColorSpace << ", ";
+ dbg << colorSpace.primaries() << ", " << colorSpace.transferFunction();
dbg << ", gamma=" << colorSpace.gamma();
dbg << ')';
return dbg;
diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h
index 880f0ad4cf..e6bc62d58a 100644
--- a/src/gui/painting/qcolorspace.h
+++ b/src/gui/painting/qcolorspace.h
@@ -54,24 +54,20 @@ class Q_GUI_EXPORT QColorSpace
{
Q_GADGET
public:
- enum ColorSpaceId {
- Undefined = 0,
- Unknown = 1,
- SRgb,
+ enum NamedColorSpace {
+ SRgb = 1,
SRgbLinear,
AdobeRgb,
DisplayP3,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
- Q_ENUM(ColorSpaceId)
+ Q_ENUM(NamedColorSpace)
enum class Primaries {
Custom = 0,
SRgb,
AdobeRgb,
DciP3D65,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(Primaries)
enum class TransferFunction {
@@ -79,12 +75,12 @@ public:
Linear,
Gamma,
SRgb,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(TransferFunction)
- QColorSpace(ColorSpaceId colorSpaceId = Undefined);
+ QColorSpace();
+ QColorSpace(NamedColorSpace namedColorSpace);
QColorSpace(Primaries primaries, TransferFunction fun, float gamma = 0.0f);
QColorSpace(Primaries primaries, float gamma);
QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
@@ -108,7 +104,6 @@ public:
void swap(QColorSpace &colorSpace) noexcept
{ qSwap(d_ptr, colorSpace.d_ptr); }
- ColorSpaceId colorSpaceId() const noexcept;
Primaries primaries() const noexcept;
TransferFunction transferFunction() const noexcept;
float gamma() const noexcept;
@@ -133,7 +128,11 @@ public:
private:
Q_DECLARE_PRIVATE(QColorSpace)
- QColorSpacePrivate *d_ptr;
+ QColorSpacePrivate *d_ptr = nullptr;
+
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace);
+#endif
};
bool Q_GUI_EXPORT operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2);
diff --git a/src/gui/painting/qcolorspace_p.h b/src/gui/painting/qcolorspace_p.h
index 037111a0ae..e7add19ed3 100644
--- a/src/gui/painting/qcolorspace_p.h
+++ b/src/gui/painting/qcolorspace_p.h
@@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QColorSpacePrimaries
+class Q_AUTOTEST_EXPORT QColorSpacePrimaries
{
public:
QColorSpacePrimaries() = default;
@@ -90,7 +90,7 @@ class QColorSpacePrivate : public QSharedData
{
public:
QColorSpacePrivate();
- QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId);
+ QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace);
QColorSpacePrivate(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma);
QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction fun, float gamma);
QColorSpacePrivate(const QColorSpacePrivate &other) = default;
@@ -118,13 +118,15 @@ public:
void initialize();
void setToXyzMatrix();
void setTransferFunction();
- bool identifyColorSpace();
+ void identifyColorSpace();
QColorTransform transformationToColorSpace(const QColorSpacePrivate *out) const;
- QColorSpace::ColorSpaceId id;
- QColorSpace::Primaries primaries;
- QColorSpace::TransferFunction transferFunction;
- float gamma;
+ static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);
+ QColorSpace::NamedColorSpace namedColorSpace = Unknown;
+
+ QColorSpace::Primaries primaries = QColorSpace::Primaries::Custom;
+ QColorSpace::TransferFunction transferFunction = QColorSpace::TransferFunction::Custom;
+ float gamma = 0.0f;
QColorVector whitePoint;
QColorTrc trc[3];
diff --git a/src/gui/painting/qcolortransferfunction_p.h b/src/gui/painting/qcolortransferfunction_p.h
index fd7cfa2b2b..0575dbd888 100644
--- a/src/gui/painting/qcolortransferfunction_p.h
+++ b/src/gui/painting/qcolortransferfunction_p.h
@@ -130,10 +130,6 @@ public:
{
return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f);
}
- static QColorTransferFunction fromBt2020()
- {
- return QColorTransferFunction(1.0f / 1.0993f, 0.0993f / 1.0993f, 1.0f / 4.5f, 0.08145f, 0.0f, 0.0f, 2.2f);
- }
static QColorTransferFunction fromProPhotoRgb()
{
return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f);
diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp
index 53fd1dfbaa..10ccefed74 100644
--- a/src/gui/painting/qcolortransform.cpp
+++ b/src/gui/painting/qcolortransform.cpp
@@ -612,6 +612,15 @@ static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *bu
static constexpr qsizetype WorkBlockSize = 256;
+template <typename T, int Count = 1>
+class QUninitialized
+{
+public:
+ operator T*() { return reinterpret_cast<T *>(this); }
+private:
+ alignas(T) char data[sizeof(T) * Count];
+};
+
template<typename T>
void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const
{
@@ -623,7 +632,8 @@ void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, Transf
bool doApplyMatrix = (colorMatrix != QColorMatrix::identity());
- QColorVector buffer[WorkBlockSize];
+ QUninitialized<QColorVector, WorkBlockSize> buffer;
+
qsizetype i = 0;
while (i < count) {
const qsizetype len = qMin(count - i, WorkBlockSize);
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c17bf2ddfd..e5f752b94e 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -669,8 +669,7 @@ static void QT_FASTCALL rbSwap_rgb30(uchar *d, const uchar *s, int count)
{
const uint *src = reinterpret_cast<const uint *>(s);
uint *dest = reinterpret_cast<uint *>(d);
- for (int i = 0; i < count; ++i)
- dest[i] = qRgbSwapRgb30(src[i]);
+ UNALIASED_CONVERSION_LOOP(dest, src, count, qRgbSwapRgb30);
}
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
@@ -5659,44 +5658,63 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL
{
if (coverage == 0) {
// nothing
- } else if (coverage == 255) {
- *dst = src;
- } else if (!colorProfile) {
- *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
+ } else if (coverage == 255 || !colorProfile) {
+ blend_pixel(*dst, src, coverage);
+ } else if (*dst < 0xff000000) {
+ // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
+ blend_pixel(*dst, src, coverage);
+ } else if (src >= 0xff000000) {
+ grayBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
- if (*dst >= 0xff000000) {
- grayBlendPixel(dst, coverage, srcLinear, colorProfile);
- } else {
- // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
- *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
- }
+ // First do naive blend with text-color
+ QRgb s = *dst;
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
+ grayBlendPixel(dst, coverage, s64, colorProfile);
}
}
#if QT_CONFIG(raster_64bit)
+
+static inline void grayBlendPixel(QRgba64 &dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
+{
+ // Do a gammacorrected gray alphablend...
+ QRgba64 dstColor = dst;
+ if (colorProfile) {
+ if (dstColor.isOpaque())
+ dstColor = colorProfile->toLinear(dstColor);
+ else if (!dstColor.isTransparent())
+ dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
+ }
+
+ blend_pixel(dstColor, srcLinear, coverage);
+
+ if (colorProfile) {
+ if (dstColor.isOpaque())
+ dstColor = colorProfile->fromLinear(dstColor);
+ else if (!dstColor.isTransparent())
+ dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
+ }
+ dst = dstColor;
+}
+
static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
} else if (coverage == 255) {
- dest[x] = src;
+ blend_pixel(dest[x], src);
+ } else if (src.isOpaque()) {
+ grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
} else {
- QRgba64 dstColor = dest[x];
- if (colorProfile) {
- if (dstColor.isOpaque())
- dstColor = colorProfile->toLinear(dstColor);
- else if (!dstColor.isTransparent())
- dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
- }
-
- dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - coverage);
- if (colorProfile) {
- if (dstColor.isOpaque())
- dstColor = colorProfile->fromLinear(dstColor);
- else if (!dstColor.isTransparent())
- dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
- }
- dest[x] = dstColor;
+ // First do naive blend with text-color
+ QRgba64 s = dest[x];
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ if (colorProfile)
+ s = colorProfile->toLinear(s);
+ grayBlendPixel(dest[x], coverage, s, colorProfile);
}
}
@@ -5715,12 +5733,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
alignas(8) QRgba64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
@@ -5793,12 +5807,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
@@ -5873,7 +5883,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip, bool useGammaCorrection)
{
- if (useGammaCorrection) {
+ if (useGammaCorrection || !color.isOpaque()) {
qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
return;
}
@@ -5932,12 +5942,8 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
if (!clip) {
quint32 *dest = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
@@ -6032,48 +6038,62 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
#endif
}
-#if QT_CONFIG(raster_64bit)
-static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
+static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
- } else if (coverage == 0xffffffff) {
- dest[x] = src;
+ } else if (coverage == 0xffffffff && qAlpha(src) == 255) {
+ blend_pixel(*dst, src);
+ } else if (!colorProfile) {
+ *dst = rgbBlend(*dst, src, coverage);
+ } else if (*dst < 0xff000000) {
+ // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
+ blend_pixel(*dst, src, qRgbAvg(coverage));
+ } else if (srcLinear.isOpaque()) {
+ rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
- QRgba64 dstColor = dest[x];
- if (dstColor.isOpaque()) {
- if (colorProfile)
- dstColor = colorProfile->toLinear(dstColor);
- dstColor = rgbBlend(dstColor, srcLinear, coverage);
- if (colorProfile)
- dstColor = colorProfile->fromLinear(dstColor);
- dest[x] = dstColor;
- } else {
- // Do a gray alphablend.
- alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
- }
+ // First do naive blend with text-color
+ QRgb s = *dst;
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
+ rgbBlendPixel(dst, coverage, s64, colorProfile);
}
}
-#endif
-static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
+#if QT_CONFIG(raster_64bit)
+static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+{
+ // Do a gammacorrected RGB alphablend...
+ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+ dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
+}
+
+static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
} else if (coverage == 0xffffffff) {
- *dst = src;
- } else if (*dst < 0xff000000) {
- // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
- const int a = qRgbAvg(coverage);
- *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a);
- } else if (!colorProfile) {
- *dst = rgbBlend(*dst, src, coverage);
- } else {
- rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
+ blend_pixel(dest[x], src);
+ } else if (!dest[x].isOpaque()) {
+ // Do a gray alphablend.
+ alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
+ } else if (src.isOpaque()) {
+ rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
+ } else {
+ // First do naive blend with text-color
+ QRgba64 s = dest[x];
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ if (colorProfile)
+ s = colorProfile->toLinear(s);
+ rgbBlendPixel(dest[x], coverage, s, colorProfile);
}
}
-#if QT_CONFIG(raster_64bit)
static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride,
@@ -6088,12 +6108,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
alignas(8) QRgba64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
@@ -6165,12 +6181,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
@@ -6243,12 +6255,8 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
if (!clip) {
quint32 *dst = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
@@ -6774,6 +6782,9 @@ static void qInitDrawhelperFunctions()
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
+ extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst, const uchar *src, int count);
+ qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
+ qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
}
#endif // SSSE3
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 9c5d525722..dd42b96d79 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -671,6 +671,8 @@ static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src)
static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src, const int const_alpha)
{
+ if (const_alpha == 255)
+ return blend_pixel(dst, src);
if (src != 0) {
const quint32 s = BYTE_MUL(src, const_alpha);
dst = s + BYTE_MUL(dst, qAlpha(~s));
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 35d61c3e6c..14d7047bb6 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -40,7 +40,7 @@
#include <private/qdrawhelper_x86_p.h>
-#ifdef QT_COMPILER_SUPPORTS_SSSE3
+#if defined(QT_COMPILER_SUPPORTS_SSSE3)
#include <private/qdrawingprimitive_sse2_p.h>
@@ -254,6 +254,49 @@ void qt_memfill24_ssse3(quint24 *dest, quint24 color, qsizetype count)
}
}
+void QT_FASTCALL rbSwap_888_ssse3(uchar *dst, const uchar *src, int count)
+{
+ int i = 0;
+
+ const static __m128i shuffleMask1 = _mm_setr_epi8(2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, /*!!*/15);
+ const static __m128i shuffleMask2 = _mm_setr_epi8(0, /*!!*/1, 4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11, /*!!*/14, 15);
+ const static __m128i shuffleMask3 = _mm_setr_epi8(/*!!*/0, 3, 2, 1, 6, 5, 4, 9, 8, 7, 12, 11, 10, 15, 14, 13);
+
+ for (; i + 15 < count; i += 16) {
+ __m128i s1 = _mm_loadu_si128((const __m128i *)src);
+ __m128i s2 = _mm_loadu_si128((const __m128i *)(src + 16));
+ __m128i s3 = _mm_loadu_si128((const __m128i *)(src + 32));
+ s1 = _mm_shuffle_epi8(s1, shuffleMask1);
+ s2 = _mm_shuffle_epi8(s2, shuffleMask2);
+ s3 = _mm_shuffle_epi8(s3, shuffleMask3);
+ _mm_storeu_si128((__m128i *)dst, s1);
+ _mm_storeu_si128((__m128i *)(dst + 16), s2);
+ _mm_storeu_si128((__m128i *)(dst + 32), s3);
+
+ // Now fix the last four misplaced values
+ std::swap(dst[15], dst[17]);
+ std::swap(dst[30], dst[32]);
+
+ src += 48;
+ dst += 48;
+ }
+
+ if (src != dst) {
+ SIMD_EPILOGUE(i, count, 15) {
+ dst[0] = src[2];
+ dst[1] = src[1];
+ dst[2] = src[0];
+ dst += 3;
+ src += 3;
+ }
+ } else {
+ SIMD_EPILOGUE(i, count, 15) {
+ std::swap(dst[0], dst[2]);
+ dst += 3;
+ }
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_COMPILER_SUPPORTS_SSSE3
diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp
index 6cb7b57493..18f212f8e9 100644
--- a/src/gui/painting/qicc.cpp
+++ b/src/gui/painting/qicc.cpp
@@ -687,9 +687,6 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
- } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromBt2020()) {
- qCDebug(lcIcc) << "fromIccProfile: BT.2020 primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::Bt2020;
}
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
@@ -765,10 +762,9 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
qCDebug(lcIcc) << "fromIccProfile: Description" << colorspaceDPtr->description;
}
- if (!colorspaceDPtr->identifyColorSpace())
- colorspaceDPtr->id = QColorSpace::Unknown;
- else
- qCDebug(lcIcc) << "fromIccProfile: Named colorspace detected: " << colorSpace->colorSpaceId();
+ colorspaceDPtr->identifyColorSpace();
+ if (colorspaceDPtr->namedColorSpace)
+ qCDebug(lcIcc) << "fromIccProfile: Named colorspace detected: " << QColorSpace::NamedColorSpace(colorspaceDPtr->namedColorSpace);
colorspaceDPtr->iccProfile = data;
diff --git a/src/gui/painting/qicc_p.h b/src/gui/painting/qicc_p.h
index c3220391f4..2a4658b84b 100644
--- a/src/gui/painting/qicc_p.h
+++ b/src/gui/painting/qicc_p.h
@@ -60,8 +60,8 @@ class QColorSpace;
namespace QIcc {
-Q_GUI_EXPORT bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace);
-Q_GUI_EXPORT QByteArray toIccProfile(const QColorSpace &space);
+bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace);
+QByteArray toIccProfile(const QColorSpace &space);
}
diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp
index a1c9f6e417..c98ca8a1fb 100644
--- a/src/gui/painting/qpagesize.cpp
+++ b/src/gui/painting/qpagesize.cpp
@@ -222,8 +222,6 @@ static const int qt_windowsConversion[][2] = {
{DMPAPER_PENV_10_ROTATED, DMPAPER_PENV_10} // Is = DMPAPER_LAST, use as loop terminator
};
-static const int windowsConversionCount = int(sizeof(qt_windowsConversion) / sizeof(qt_windowsConversion[0]));
-
// Standard sizes data
struct StandardPageSize {
QPageSize::PageSizeId id;
@@ -423,9 +421,9 @@ static QPageSize::PageSizeId qt_idForWindowsID(int windowsId, QSize *match = 0)
if (windowsId <= DMPAPER_NONE || windowsId > DMPAPER_LAST)
return QPageSize::Custom;
// Check if one of the unsupported values, convert to valid value if is
- for (int i = 0; i < windowsConversionCount; ++i) {
- if (qt_windowsConversion[i][0] == windowsId) {
- windowsId = qt_windowsConversion[i][1];
+ for (const auto &it : qt_windowsConversion) {
+ if (it[0] == windowsId) {
+ windowsId = it[1];
break;
}
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 5ab5514dd4..8c51981120 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -842,8 +842,8 @@ void QRasterPaintEngine::updateRasterState()
const QPainter::CompositionMode mode = s->composition_mode;
s->flags.fast_text = (s->penData.type == QSpanData::Solid)
&& s->intOpacity == 256
- && (mode == QPainter::CompositionMode_Source
- || (mode == QPainter::CompositionMode_SourceOver
+ && (mode == QPainter::CompositionMode_SourceOver
+ || (mode == QPainter::CompositionMode_Source
&& s->penData.solidColor.isOpaque()));
}
@@ -906,8 +906,11 @@ void QRasterPaintEngine::renderHintsChanged()
s->flags.antialiased = bool(s->renderHints & QPainter::Antialiasing);
#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (s->renderHints & QPainter::HighQualityAntialiasing)
s->flags.antialiased = true;
+QT_WARNING_POP
#endif
s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform);
s->flags.legacy_rounding = !bool(s->renderHints & QPainter::Antialiasing) && bool(s->renderHints & QPainter::Qt4CompatiblePainting);
@@ -2214,7 +2217,7 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)
const QClipData *clip = d->clip();
QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy());
- if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) {
+ if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img, pt, img.rect())) {
if (!clip) {
d->blitImage(pt, img, d->deviceRect);
return;
@@ -2285,7 +2288,12 @@ namespace {
return NoRotation;
}
- inline bool isPixelAligned(const QRectF &rect) {
+ inline bool isPixelAligned(const QPointF &pt)
+ {
+ return QPointF(pt.toPoint()) == pt;
+ }
+ inline bool isPixelAligned(const QRectF &rect)
+ {
return QRectF(rect.toRect()) == rect;
}
}
@@ -2353,17 +2361,12 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
const QClipData *clip = d->clip();
- if (s->matrix.type() > QTransform::TxTranslate
+ if (s->matrix.type() == QTransform::TxRotate
&& !stretch_sr
&& (!clip || clip->hasRectClip)
&& s->intOpacity == 256
&& (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
- || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)
- && d->rasterBuffer->format == img.format()
- && (d->rasterBuffer->format == QImage::Format_RGB16
- || d->rasterBuffer->format == QImage::Format_RGB32
- || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied
- && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))
+ || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source))
{
RotationType rotationType = qRotationType(s->matrix);
const QPixelLayout::BPP plBpp = qPixelLayouts[d->rasterBuffer->format].bpp;
@@ -2371,9 +2374,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
if (rotationType != NoRotation && qMemRotateFunctions[plBpp][rotationType] && img.rect().contains(sr.toAlignedRect())) {
QRectF transformedTargetRect = s->matrix.mapRect(r);
- if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))
- || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr)))
- {
+ if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img, transformedTargetRect.topRight(), sr)) {
QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect);
if (clippedTransformedTargetRect.isNull())
return;
@@ -2507,8 +2508,8 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
fillPath(path, &d->image_filler_xform);
s->matrix = m;
} else {
- if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) {
- QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
+ QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
+ if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img, pt, sr)) {
if (!clip) {
d->blitImage(pt, img, d->deviceRect, sr.toRect());
return;
@@ -2519,7 +2520,6 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
} else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {
SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
if (func) {
- QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
if (!clip) {
d->drawImage(pt, img, func, d->deviceRect, s->intOpacity, sr.toRect());
return;
@@ -3754,12 +3754,22 @@ bool QRasterPaintEnginePrivate::canUseFastImageBlending(QPainter::CompositionMod
&& !image.hasAlphaChannel()));
}
-bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const
+bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image, const QPointF &pt, const QRectF &sr) const
{
Q_Q(const QRasterPaintEngine);
+
+ if (!(mode == QPainter::CompositionMode_Source
+ || (mode == QPainter::CompositionMode_SourceOver
+ && !image.hasAlphaChannel())))
+ return false;
+
const QRasterPaintEngineState *s = q->state();
+ Q_ASSERT(s->matrix.type() <= QTransform::TxTranslate || s->matrix.type() == QTransform::TxRotate);
- if (!s->flags.fast_images || s->intOpacity != 256 || qt_depthForFormat(rasterBuffer->format) < 8)
+ if (s->intOpacity != 256
+ || image.depth() < 8
+ || ((s->renderHints & (QPainter::SmoothPixmapTransform | QPainter::Antialiasing))
+ && (!isPixelAligned(pt) || !isPixelAligned(sr))))
return false;
QImage::Format dFormat = rasterBuffer->format;
@@ -3767,18 +3777,13 @@ bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mo
// Formats must match or source format must be a subset of destination format
if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) {
if ((sFormat == QImage::Format_RGB32 && dFormat == QImage::Format_ARGB32)
- || (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888))
+ || (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888)
+ || (sFormat == QImage::Format_RGBX64 && dFormat == QImage::Format_RGBA64))
sFormat = dFormat;
else
sFormat = qt_maybeAlphaVersionWithSameDepth(sFormat); // this returns premul formats
}
- if (dFormat != sFormat)
- return false;
-
- return s->matrix.type() <= QTransform::TxTranslate
- && (mode == QPainter::CompositionMode_Source
- || (mode == QPainter::CompositionMode_SourceOver
- && !image.hasAlphaChannel()));
+ return (dFormat == sFormat);
}
QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index ec4a35087a..089aadc3f7 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -306,7 +306,7 @@ public:
void recalculateFastImages();
bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
- bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const;
+ bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image, const QPointF &pt, const QRectF &sr) const;
QPaintDevice *device;
QScopedPointer<QOutlineMapper> outlineMapper;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 84b34e390b..3ce54c20be 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1716,8 +1716,8 @@ void QPainter::restore()
static inline void qt_cleanup_painter_state(QPainterPrivate *d)
{
+ qDeleteAll(d->states);
d->states.clear();
- delete d->state;
d->state = 0;
d->engine = 0;
d->device = 0;
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index c71d82546a..45e90bd99b 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -338,7 +338,16 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
}
}
- if (!d_ptr->context->makeCurrent(window)) {
+ bool current = d_ptr->context->makeCurrent(window);
+
+ if (!current && !d_ptr->context->isValid()) {
+ delete d_ptr->blitter;
+ d_ptr->blitter = nullptr;
+ d_ptr->textureId = 0;
+ current = d_ptr->context->create() && d_ptr->context->makeCurrent(window);
+ }
+
+ if (!current) {
qCWarning(lcQpaBackingStore, "composeAndFlush: makeCurrent() failed");
return;
}
@@ -446,14 +455,22 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->setRedBlueSwizzle(false);
}
- // There is no way to tell if the OpenGL-rendered content is premultiplied or not.
- // For compatibility, assume that it is not, and use normal alpha blend always.
- if (d_ptr->premultiplied)
- funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
-
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
+ bool blendIsPremultiplied = d_ptr->premultiplied;
for (int i = 0; i < textures->count(); ++i) {
- if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
+ const QPlatformTextureList::Flags flags = textures->flags(i);
+ if (flags.testFlag(QPlatformTextureList::NeedsPremultipliedAlphaBlending)) {
+ if (!blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = true;
+ }
+ } else {
+ if (blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = false;
+ }
+ }
+ if (flags.testFlag(QPlatformTextureList::StacksOnTop))
blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 414d2bf0de..4f08b0092f 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -81,7 +81,8 @@ class Q_GUI_EXPORT QPlatformTextureList : public QObject
public:
enum Flag {
StacksOnTop = 0x01,
- TextureIsSrgb = 0x02
+ TextureIsSrgb = 0x02,
+ NeedsPremultipliedAlphaBlending = 0x04
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index 51eed962f0..82f5be2b65 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -88,60 +88,6 @@ QT_BEGIN_NAMESPACE
Example of using complex regions:
\snippet code/src_gui_painting_qregion.cpp 0
- \section1 Additional License Information
-
- On Embedded Linux and X11 platforms, parts of this class rely on
- code obtained under the following licenses:
-
- \legalese
- Copyright (c) 1987 X Consortium
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name of the X Consortium shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from the X Consortium.
- \endlegalese
-
- \br
-
- \legalese
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- \endlegalese
-
\sa QPainter::setClipRegion(), QPainter::setClipRect(), QPainterPath
*/
diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h
index ca879de27c..d145dbfbea 100644
--- a/src/gui/painting/qrgba64_p.h
+++ b/src/gui/painting/qrgba64_p.h
@@ -284,6 +284,8 @@ static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src)
static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src, const int const_alpha)
{
+ if (const_alpha == 255)
+ return blend_pixel(dst, src);
if (!src.isTransparent()) {
src = multiplyAlpha255(src, const_alpha);
dst = src + multiplyAlpha65535(dst, 65535 - src.alpha());
diff --git a/src/gui/painting/qt_attribution.json b/src/gui/painting/qt_attribution.json
index 9d3debc1b9..7b16e8c211 100644
--- a/src/gui/painting/qt_attribution.json
+++ b/src/gui/painting/qt_attribution.json
@@ -41,5 +41,20 @@
"LicenseId": "MIT",
"LicenseFile": "WEBGRADIENTS_LICENSE.txt",
"Copyright": "Copyright (c) 2017 itmeo"
+ },
+ {
+ "Id": "xserverhelper",
+ "Name": "X Server helper",
+ "QDocModule": "qtgui",
+ "QtUsage": "Used in Qt GUI (QRegion).",
+ "Files": "qregion.cpp",
+
+ "Description": "Code from X11's region.h, Region.c, poly.h, and PolyReg.c",
+ "Homepage": "https://www.x.org/",
+ "License": "X11 License and Historical Permission Notice and Disclaimer",
+ "LicenseId": "X11 AND HPND",
+ "LicenseFile": "XCONSORTIUM_LICENSE.txt",
+ "Copyright": "Copyright (c) 1987, 1988 X Consortium
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts."
}
]
diff --git a/src/gui/rhi/cs_tdr_p.h b/src/gui/rhi/cs_tdr_p.h
new file mode 100644
index 0000000000..620a4a101d
--- /dev/null
+++ b/src/gui/rhi/cs_tdr_p.h
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Gui module
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CS_TDR_P_H
+#define CS_TDR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+
+#include <qt_windows.h>
+
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ConstantBuffer
+// {
+//
+// uint zero; // Offset: 0 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// uav UAV uint buf u0 1
+// ConstantBuffer cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// no Input
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// no Output
+cs_5_0
+dcl_globalFlags refactoringAllowed
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_uav_typed_buffer (uint,uint,uint,uint) u0
+dcl_input vThreadID.x
+dcl_thread_group 256, 1, 1
+loop
+ breakc_nz cb0[0].x
+ store_uav_typed u0.xyzw, vThreadID.xxxx, cb0[0].xxxx
+endloop
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_killDeviceByTimingOut[] =
+{
+ 68, 88, 66, 67, 217, 62,
+ 220, 38, 136, 51, 86, 245,
+ 161, 96, 18, 35, 141, 17,
+ 26, 13, 1, 0, 0, 0,
+ 164, 2, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 100, 1, 0, 0, 116, 1,
+ 0, 0, 132, 1, 0, 0,
+ 8, 2, 0, 0, 82, 68,
+ 69, 70, 40, 1, 0, 0,
+ 1, 0, 0, 0, 144, 0,
+ 0, 0, 2, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 83, 67, 0, 1, 0, 0,
+ 0, 1, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 124, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0,
+ 1, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 128, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 117, 97,
+ 118, 0, 67, 111, 110, 115,
+ 116, 97, 110, 116, 66, 117,
+ 102, 102, 101, 114, 0, 171,
+ 128, 0, 0, 0, 1, 0,
+ 0, 0, 168, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 208, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0,
+ 2, 0, 0, 0, 220, 0,
+ 0, 0, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 122, 101,
+ 114, 111, 0, 100, 119, 111,
+ 114, 100, 0, 171, 0, 0,
+ 19, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 213, 0, 0, 0, 77, 105,
+ 99, 114, 111, 115, 111, 102,
+ 116, 32, 40, 82, 41, 32,
+ 72, 76, 83, 76, 32, 83,
+ 104, 97, 100, 101, 114, 32,
+ 67, 111, 109, 112, 105, 108,
+ 101, 114, 32, 49, 48, 46,
+ 49, 0, 73, 83, 71, 78,
+ 8, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0,
+ 79, 83, 71, 78, 8, 0,
+ 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 83, 72,
+ 69, 88, 124, 0, 0, 0,
+ 80, 0, 5, 0, 31, 0,
+ 0, 0, 106, 8, 0, 1,
+ 89, 0, 0, 4, 70, 142,
+ 32, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 156, 8,
+ 0, 4, 0, 224, 17, 0,
+ 0, 0, 0, 0, 68, 68,
+ 0, 0, 95, 0, 0, 2,
+ 18, 0, 2, 0, 155, 0,
+ 0, 4, 0, 1, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 48, 0, 0, 1,
+ 3, 0, 4, 4, 10, 128,
+ 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 164, 0,
+ 0, 7, 242, 224, 17, 0,
+ 0, 0, 0, 0, 6, 0,
+ 2, 0, 6, 128, 32, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 22, 0, 0, 1,
+ 62, 0, 0, 1, 83, 84,
+ 65, 84, 148, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0
+};
+
+#endif // Q_OS_WIN
+
+#endif // CS_TDR_P_H
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 4414b61d55..dabad35688 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -439,6 +439,18 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
visible in external GPU debugging tools will not be available and functions
like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid
enabling in production builds as it may involve a performance penalty.
+
+ \value PreferSoftwareRenderer Indicates that backends should prefer
+ choosing an adapter or physical device that renders in software on the CPU.
+ For example, with Direct3D there is typically a "Basic Render Driver"
+ adapter available with \c{DXGI_ADAPTER_FLAG_SOFTWARE}. Setting this flag
+ requests the backend to choose that adapter over any other, as long as no
+ specific adapter was forced by other backend-specific means. With Vulkan
+ this maps to preferring physical devices with
+ \c{VK_PHYSICAL_DEVICE_TYPE_CPU}. When not available, or when it is not
+ possible to decide if an adapter/device is software-based, this flag is
+ ignored. It may also be ignored with graphics APIs that have no concept and
+ means of enumerating adapters/devices.
*/
/*!
@@ -455,8 +467,8 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value FrameOpDeviceLost The graphics device was lost. This can be
recoverable by attempting to repeat the operation (such as, beginFrame())
- and releasing and reinitializing all objects backed by native graphics
- resources.
+ after releasing and reinitializing all objects backed by native graphics
+ resources. See isDeviceLost().
*/
/*!
@@ -551,6 +563,21 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value BaseInstance Indicates that instanced draw commands support the \c
firstInstance argument. When reported as not supported, the firstInstance
value is ignored and the instance ID starts from 0.
+
+ \value TriangleFanTopology Indicates that QRhiGraphicsPipeline::setTopology()
+ supports QRhiGraphicsPipeline::TriangleFan.
+
+ \value ReadBackNonUniformBuffer Indicates that
+ \l{QRhiResourceUpdateBatch::readBackBuffer()}{reading buffer contents} is
+ supported for QRhiBuffer instances with a usage different than
+ UniformBuffer. While this is supported in the majority of cases, it will be
+ unsupported with OpenGL ES older than 3.0.
+
+ \value ReadBackNonBaseMipLevel Indicates that specifying a mip level other
+ than 0 is supported when reading back texture contents. When not supported,
+ specifying a non-zero level in QRhiReadbackDescription leads to returning
+ an all-zero image. In practice this feature will be unsupported with OpenGL
+ ES 2.0, while it will likely be supported everywhere else.
*/
/*!
@@ -673,7 +700,7 @@ bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClear
*/
uint qHash(const QRhiDepthStencilClearValue &v, uint seed) Q_DECL_NOTHROW
{
- return seed * (qFloor(v.depthClearValue() * 100) + v.stencilClearValue());
+ return seed * (uint(qFloor(qreal(v.depthClearValue()) * 100)) + v.stencilClearValue());
}
#ifndef QT_NO_DEBUG_STREAM
@@ -695,8 +722,8 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v)
Used with QRhiCommandBuffer::setViewport().
- \note QRhi assumes OpenGL-style viewport coordinates, meaning x and y are
- bottom-left.
+ QRhi assumes OpenGL-style viewport coordinates, meaning x and y are
+ bottom-left. Negative width or height are not allowed.
Typical usage is like the following:
@@ -725,7 +752,9 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v)
Constructs a viewport description with the rectangle specified by \a x, \a
y, \a w, \a h and the depth range \a minDepth and \a maxDepth.
- \note x and y are assumed to be the bottom-left position.
+ \note \a x and \a y are assumed to be the bottom-left position. \a w and \a
+ h should not be negative, the viewport will be ignored by
+ QRhiCommandBuffer::setViewport() otherwise.
\sa QRhi::clipSpaceCorrMatrix()
*/
@@ -768,7 +797,8 @@ bool operator!=(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW
uint qHash(const QRhiViewport &v, uint seed) Q_DECL_NOTHROW
{
const std::array<float, 4> r = v.viewport();
- return seed + r[0] + r[1] + r[2] + r[3] + qFloor(v.minDepth() * 100) + qFloor(v.maxDepth() * 100);
+ return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3])
+ + uint(qFloor(qreal(v.minDepth()) * 100)) + uint(qFloor(qreal(v.maxDepth()) * 100));
}
#ifndef QT_NO_DEBUG_STREAM
@@ -797,8 +827,12 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v)
only possible with a QRhiGraphicsPipeline that has
QRhiGraphicsPipeline::UsesScissor set.
- \note QRhi assumes OpenGL-style scissor coordinates, meaning x and y are
- bottom-left.
+ QRhi assumes OpenGL-style scissor coordinates, meaning x and y are
+ bottom-left. Negative width or height are not allowed. However, apart from
+ that, the flexible OpenGL semantics apply: negative x and y, partially out
+ of bounds rectangles, etc. will be handled gracefully, clamping as
+ appropriate. Therefore, any rendering logic targeting OpenGL can feed
+ scissor rectangles into QRhiScissor as-is, without any adaptation.
\sa QRhiCommandBuffer::setScissor(), QRhiViewport
*/
@@ -813,7 +847,11 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v)
Constructs a scissor with the rectangle specified by \a x, \a y, \a w, and
\a h.
- \note x and y are assumed to be the bottom-left position.
+ \note \a x and \a y are assumed to be the bottom-left position. Negative \a w
+ or \a h are not allowed, such scissor rectangles will be ignored by
+ QRhiCommandBuffer. Other than that, the flexible OpenGL semantics apply:
+ negative x and y, partially out of bounds rectangles, etc. will be handled
+ gracefully, clamping as appropriate.
*/
QRhiScissor::QRhiScissor(int x, int y, int w, int h)
: m_rect { { x, y, w, h } }
@@ -850,7 +888,7 @@ bool operator!=(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW
uint qHash(const QRhiScissor &v, uint seed) Q_DECL_NOTHROW
{
const std::array<int, 4> r = v.scissor();
- return seed + r[0] + r[1] + r[2] + r[3];
+ return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3]);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -1136,7 +1174,7 @@ bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribut
*/
uint qHash(const QRhiVertexInputAttribute &v, uint seed) Q_DECL_NOTHROW
{
- return seed + v.binding() + v.location() + v.format() + v.offset();
+ return seed + uint(v.binding()) + uint(v.location()) + uint(v.format()) + v.offset();
}
#ifndef QT_NO_DEBUG_STREAM
@@ -1176,8 +1214,7 @@ QDebug operator<<(QDebug dbg, const QRhiVertexInputAttribute &a)
*/
bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW
{
- return a.bindings() == b.bindings()
- && a.attributes() == b.attributes();
+ return a.m_bindings == b.m_bindings && a.m_attributes == b.m_attributes;
}
/*!
@@ -1198,15 +1235,21 @@ bool operator!=(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b)
*/
uint qHash(const QRhiVertexInputLayout &v, uint seed) Q_DECL_NOTHROW
{
- return qHash(v.bindings(), seed) + qHash(v.attributes(), seed);
+ return qHash(v.m_bindings, seed) + qHash(v.m_attributes, seed);
}
#ifndef QT_NO_DEBUG_STREAM
+template<typename T, int N>
+QDebug operator<<(QDebug dbg, const QVarLengthArray<T, N> &vla)
+{
+ return QtPrivate::printSequentialContainer(dbg, "VLA", vla);
+}
+
QDebug operator<<(QDebug dbg, const QRhiVertexInputLayout &v)
{
QDebugStateSaver saver(dbg);
- dbg.nospace() << "QRhiVertexInputLayout(bindings=" << v.bindings()
- << " attributes=" << v.attributes()
+ dbg.nospace() << "QRhiVertexInputLayout(bindings=" << v.m_bindings
+ << " attributes=" << v.m_attributes
<< ')';
return dbg;
}
@@ -1607,28 +1650,20 @@ QRhiTextureUploadDescription::QRhiTextureUploadDescription(const QRhiTextureUplo
}
/*!
- Constructs a texture upload description with the specified list of \a entries.
+ Constructs a texture upload description with the specified \a list of entries.
- \note \a entries can also contain multiple QRhiTextureUploadEntry elements
+ \note \a list can also contain multiple QRhiTextureUploadEntry elements
with the the same layer and level. This makes sense when those uploads are
partial, meaning their subresource description has a source size or image
smaller than the subresource dimensions, and can be more efficient than
issuing separate uploadTexture()'s.
*/
-QRhiTextureUploadDescription::QRhiTextureUploadDescription(const QVector<QRhiTextureUploadEntry> &entries)
- : m_entries(entries)
+QRhiTextureUploadDescription::QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list)
+ : m_entries(list)
{
}
/*!
- Adds \a entry to the list of subresource uploads.
- */
-void QRhiTextureUploadDescription::append(const QRhiTextureUploadEntry &entry)
-{
- m_entries.append(entry);
-}
-
-/*!
\class QRhiTextureCopyDescription
\internal
\inmodule QtGui
@@ -1958,6 +1993,14 @@ QRhiResource::Type QRhiBuffer::resourceType() const
How the renderbuffer is implemented by a backend is not exposed to the
applications. In some cases it may be backed by ordinary textures, while in
others there may be a different kind of native resource used.
+
+ Renderbuffers that are used as (and are only used as) depth-stencil buffers
+ in combination with a QRhiSwapChain's color buffers should have the
+ UsedWithSwapChainOnly flag set. This serves a double purpose: such buffers,
+ depending on the backend and the underlying APIs, be more efficient, and
+ QRhi provides automatic sizing behavior to match the color buffers, which
+ means calling setPixelSize() and build() are not necessary for such
+ renderbuffers.
*/
/*!
@@ -1973,12 +2016,15 @@ QRhiResource::Type QRhiBuffer::resourceType() const
Flag values for flags() and setFlags()
\value UsedWithSwapChainOnly For DepthStencil renderbuffers this indicates
- that the renderbuffer is only used in combination with a QRhiSwapChain and
- never in other ways. Relevant with some backends, while others ignore it.
- With OpenGL where a separate windowing system interface API is in use (EGL,
- GLX, etc.), the flag is important since it avoids creating any actual
- resource as there is already a windowing system provided depth/stencil
- buffer as requested by QSurfaceFormat.
+ that the renderbuffer is only used in combination with a QRhiSwapChain, and
+ never in any other way. This provides automatic sizing and resource
+ rebuilding, so calling setPixelSize() or build() is not needed whenever
+ this flag is set. This flag value may also trigger backend-specific
+ behavior, for example with OpenGL, where a separate windowing system
+ interface API is in use (EGL, GLX, etc.), the flag is especially important
+ as it avoids creating any actual renderbuffer resource as there is already
+ a windowing system provided depth/stencil buffer as requested by
+ QSurfaceFormat.
*/
/*!
@@ -2500,16 +2546,8 @@ QRhiResource::Type QRhiTextureRenderTarget::resourceType() const
be used with the same pipeline, assuming the pipeline was built with one of
them in the first place.
- Creating and then using a new \c srb2 that is very similar to \c srb with
- the exception of referencing another texture could be implemented like the
- following:
-
\badcode
srb2 = rhi->newShaderResourceBindings();
- QVector<QRhiShaderResourceBinding> bindings = srb->bindings();
- bindings[1] = QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, anotherTexture, sampler);
- srb2->setBindings(bindings);
- srb2->build();
...
cb->setGraphicsPipeline(ps);
cb->setShaderResources(srb2); // binds srb2
@@ -2611,43 +2649,10 @@ bool QRhiShaderResourceBindings::isLayoutCompatible(const QRhiShaderResourceBind
\internal
*/
QRhiShaderResourceBinding::QRhiShaderResourceBinding()
- : d(new QRhiShaderResourceBindingPrivate)
-{
-}
-
-/*!
- \internal
- */
-void QRhiShaderResourceBinding::detach()
{
- qAtomicDetach(d);
-}
-
-/*!
- \internal
- */
-QRhiShaderResourceBinding::QRhiShaderResourceBinding(const QRhiShaderResourceBinding &other)
- : d(other.d)
-{
- d->ref.ref();
-}
-
-/*!
- \internal
- */
-QRhiShaderResourceBinding &QRhiShaderResourceBinding::operator=(const QRhiShaderResourceBinding &other)
-{
- qAtomicAssign(d, other.d);
- return *this;
-}
-
-/*!
- Destructor.
- */
-QRhiShaderResourceBinding::~QRhiShaderResourceBinding()
-{
- if (!d->ref.deref())
- delete d;
+ // Zero out everything, including possible padding, because will use
+ // qHashBits on it.
+ memset(&d.u, 0, sizeof(d.u));
}
/*!
@@ -2664,8 +2669,7 @@ QRhiShaderResourceBinding::~QRhiShaderResourceBinding()
*/
bool QRhiShaderResourceBinding::isLayoutCompatible(const QRhiShaderResourceBinding &other) const
{
- return (d == other.d)
- || (d->binding == other.d->binding && d->stage == other.d->stage && d->type == other.d->type);
+ return d.binding == other.d.binding && d.stage == other.d.stage && d.type == other.d.type;
}
/*!
@@ -2678,15 +2682,13 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer(
int binding, StageFlags stage, QRhiBuffer *buf)
{
QRhiShaderResourceBinding b;
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- Q_ASSERT(d->ref.loadRelaxed() == 1);
- d->binding = binding;
- d->stage = stage;
- d->type = UniformBuffer;
- d->u.ubuf.buf = buf;
- d->u.ubuf.offset = 0;
- d->u.ubuf.maybeSize = 0; // entire buffer
- d->u.ubuf.hasDynamicOffset = false;
+ b.d.binding = binding;
+ b.d.stage = stage;
+ b.d.type = UniformBuffer;
+ b.d.u.ubuf.buf = buf;
+ b.d.u.ubuf.offset = 0;
+ b.d.u.ubuf.maybeSize = 0; // entire buffer
+ b.d.u.ubuf.hasDynamicOffset = false;
return b;
}
@@ -2707,9 +2709,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer(
{
Q_ASSERT(size > 0);
QRhiShaderResourceBinding b = uniformBuffer(binding, stage, buf);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->u.ubuf.offset = offset;
- d->u.ubuf.maybeSize = size;
+ b.d.u.ubuf.offset = offset;
+ b.d.u.ubuf.maybeSize = size;
return b;
}
@@ -2728,8 +2729,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBufferWithDynamicOff
int binding, StageFlags stage, QRhiBuffer *buf, int size)
{
QRhiShaderResourceBinding b = uniformBuffer(binding, stage, buf, 0, size);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->u.ubuf.hasDynamicOffset = true;
+ b.d.u.ubuf.hasDynamicOffset = true;
return b;
}
@@ -2742,13 +2742,11 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::sampledTexture(
int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
{
QRhiShaderResourceBinding b;
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- Q_ASSERT(d->ref.loadRelaxed() == 1);
- d->binding = binding;
- d->stage = stage;
- d->type = SampledTexture;
- d->u.stex.tex = tex;
- d->u.stex.sampler = sampler;
+ b.d.binding = binding;
+ b.d.stage = stage;
+ b.d.type = SampledTexture;
+ b.d.u.stex.tex = tex;
+ b.d.u.stex.sampler = sampler;
return b;
}
@@ -2764,13 +2762,11 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::imageLoad(
int binding, StageFlags stage, QRhiTexture *tex, int level)
{
QRhiShaderResourceBinding b;
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- Q_ASSERT(d->ref.loadRelaxed() == 1);
- d->binding = binding;
- d->stage = stage;
- d->type = ImageLoad;
- d->u.simage.tex = tex;
- d->u.simage.level = level;
+ b.d.binding = binding;
+ b.d.stage = stage;
+ b.d.type = ImageLoad;
+ b.d.u.simage.tex = tex;
+ b.d.u.simage.level = level;
return b;
}
@@ -2786,8 +2782,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::imageStore(
int binding, StageFlags stage, QRhiTexture *tex, int level)
{
QRhiShaderResourceBinding b = imageLoad(binding, stage, tex, level);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->type = ImageStore;
+ b.d.type = ImageStore;
return b;
}
@@ -2803,8 +2798,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::imageLoadStore(
int binding, StageFlags stage, QRhiTexture *tex, int level)
{
QRhiShaderResourceBinding b = imageLoad(binding, stage, tex, level);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->type = ImageLoadStore;
+ b.d.type = ImageLoadStore;
return b;
}
@@ -2818,14 +2812,12 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoad(
int binding, StageFlags stage, QRhiBuffer *buf)
{
QRhiShaderResourceBinding b;
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- Q_ASSERT(d->ref.loadRelaxed() == 1);
- d->binding = binding;
- d->stage = stage;
- d->type = BufferLoad;
- d->u.sbuf.buf = buf;
- d->u.sbuf.offset = 0;
- d->u.sbuf.maybeSize = 0; // entire buffer
+ b.d.binding = binding;
+ b.d.stage = stage;
+ b.d.type = BufferLoad;
+ b.d.u.sbuf.buf = buf;
+ b.d.u.sbuf.offset = 0;
+ b.d.u.sbuf.maybeSize = 0; // entire buffer
return b;
}
@@ -2841,9 +2833,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoad(
{
Q_ASSERT(size > 0);
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->u.sbuf.offset = offset;
- d->u.sbuf.maybeSize = size;
+ b.d.u.sbuf.offset = offset;
+ b.d.u.sbuf.maybeSize = size;
return b;
}
@@ -2857,8 +2848,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferStore(
int binding, StageFlags stage, QRhiBuffer *buf)
{
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->type = BufferStore;
+ b.d.type = BufferStore;
return b;
}
@@ -2874,9 +2864,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferStore(
{
Q_ASSERT(size > 0);
QRhiShaderResourceBinding b = bufferStore(binding, stage, buf);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->u.sbuf.offset = offset;
- d->u.sbuf.maybeSize = size;
+ b.d.u.sbuf.offset = offset;
+ b.d.u.sbuf.maybeSize = size;
return b;
}
@@ -2890,8 +2879,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoadStore(
int binding, StageFlags stage, QRhiBuffer *buf)
{
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->type = BufferLoadStore;
+ b.d.type = BufferLoadStore;
return b;
}
@@ -2907,9 +2895,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoadStore(
{
Q_ASSERT(size > 0);
QRhiShaderResourceBinding b = bufferLoadStore(binding, stage, buf);
- QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
- d->u.sbuf.offset = offset;
- d->u.sbuf.maybeSize = size;
+ b.d.u.sbuf.offset = offset;
+ b.d.u.sbuf.maybeSize = size;
return b;
}
@@ -2925,28 +2912,32 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoadStore(
*/
bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW
{
- if (a.d == b.d)
+ const QRhiShaderResourceBinding::Data *da = a.data();
+ const QRhiShaderResourceBinding::Data *db = b.data();
+
+ if (da == db)
return true;
- if (a.d->binding != b.d->binding
- || a.d->stage != b.d->stage
- || a.d->type != b.d->type)
+
+ if (da->binding != db->binding
+ || da->stage != db->stage
+ || da->type != db->type)
{
return false;
}
- switch (a.d->type) {
+ switch (da->type) {
case QRhiShaderResourceBinding::UniformBuffer:
- if (a.d->u.ubuf.buf != b.d->u.ubuf.buf
- || a.d->u.ubuf.offset != b.d->u.ubuf.offset
- || a.d->u.ubuf.maybeSize != b.d->u.ubuf.maybeSize)
+ if (da->u.ubuf.buf != db->u.ubuf.buf
+ || da->u.ubuf.offset != db->u.ubuf.offset
+ || da->u.ubuf.maybeSize != db->u.ubuf.maybeSize)
{
return false;
}
break;
case QRhiShaderResourceBinding::SampledTexture:
- if (a.d->u.stex.tex != b.d->u.stex.tex
- || a.d->u.stex.sampler != b.d->u.stex.sampler)
+ if (da->u.stex.tex != db->u.stex.tex
+ || da->u.stex.sampler != db->u.stex.sampler)
{
return false;
}
@@ -2956,8 +2947,8 @@ bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
case QRhiShaderResourceBinding::ImageStore:
Q_FALLTHROUGH();
case QRhiShaderResourceBinding::ImageLoadStore:
- if (a.d->u.simage.tex != b.d->u.simage.tex
- || a.d->u.simage.level != b.d->u.simage.level)
+ if (da->u.simage.tex != db->u.simage.tex
+ || da->u.simage.level != db->u.simage.level)
{
return false;
}
@@ -2967,9 +2958,9 @@ bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
case QRhiShaderResourceBinding::BufferStore:
Q_FALLTHROUGH();
case QRhiShaderResourceBinding::BufferLoadStore:
- if (a.d->u.sbuf.buf != b.d->u.sbuf.buf
- || a.d->u.sbuf.offset != b.d->u.sbuf.offset
- || a.d->u.sbuf.maybeSize != b.d->u.sbuf.maybeSize)
+ if (da->u.sbuf.buf != db->u.sbuf.buf
+ || da->u.sbuf.offset != db->u.sbuf.offset
+ || da->u.sbuf.maybeSize != db->u.sbuf.maybeSize)
{
return false;
}
@@ -3000,16 +2991,16 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
*/
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
{
- const char *u = reinterpret_cast<const char *>(&b.d->u);
- return seed + b.d->binding + 10 * b.d->stage + 100 * b.d->type
- + qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed);
+ const QRhiShaderResourceBinding::Data *d = b.data();
+ return seed + uint(d->binding) + 10 * uint(d->stage) + 100 * uint(d->type)
+ + qHashBits(&d->u, sizeof(d->u), seed);
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QRhiShaderResourceBinding &b)
{
- const QRhiShaderResourceBindingPrivate *d = b.d;
QDebugStateSaver saver(dbg);
+ const QRhiShaderResourceBinding::Data *d = b.data();
dbg.nospace() << "QRhiShaderResourceBinding("
<< "binding=" << d->binding
<< " stage=" << d->stage
@@ -3093,9 +3084,13 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBindings &srb)
\inmodule QtGui
\brief Graphics pipeline state resource.
+ \note Setting the shader stages is mandatory. There must be at least one
+ stage, and there must be a vertex stage.
+
\note Setting the shader resource bindings is mandatory. The referenced
QRhiShaderResourceBindings must already be built by the time build() is
- called.
+ called. Associating with a QRhiShaderResourceBindings that has no bindings
+ is also valid, as long as no shader in any stage expects any resources.
\note Setting the render pass descriptor is mandatory. To obtain a
QRhiRenderPassDescriptor that can be passed to setRenderPassDescriptor(),
@@ -3104,8 +3099,6 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBindings &srb)
\note Setting the vertex input layout is mandatory.
- \note Setting the shader stages is mandatory.
-
\note sampleCount() defaults to 1 and must match the sample count of the
render target's color and depth stencil attachments.
@@ -3147,6 +3140,7 @@ QDebug operator<<(QDebug dbg, const QRhiShaderResourceBindings &srb)
\value Triangles (default)
\value TriangleStrip
+ \value TriangleFan (only available if QRhi::TriangleFanTopology is supported)
\value Lines
\value LineStrip
\value Points
@@ -3328,7 +3322,7 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
{
sc = rhi->newSwapChain();
ds = rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil,
- QSize(), // no need to set the size yet
+ QSize(), // no need to set the size here due to UsedWithSwapChainOnly
1,
QRhiRenderBuffer::UsedWithSwapChainOnly);
sc->setWindow(window);
@@ -3340,9 +3334,6 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
void resizeSwapChain()
{
- const QSize outputSize = sc->surfacePixelSize();
- ds->setPixelSize(outputSize);
- ds->build();
hasSwapChain = sc->buildOrResize();
}
@@ -3457,10 +3448,18 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
Flag values to describe swapchain properties
\value SurfaceHasPreMulAlpha Indicates that the target surface has
- transparency with premultiplied alpha.
+ transparency with premultiplied alpha. For example, this is what Qt Quick
+ uses when the alpha channel is enabled on the target QWindow, because the
+ scenegraph rendrerer always outputs fragments with alpha multiplied into
+ the red, green, and blue values. To ensure identical behavior across
+ platforms, always set QSurfaceFormat::alphaBufferSize() to a non-zero value
+ on the target QWindow whenever this flag is set on the swapchain.
\value SurfaceHasNonPreMulAlpha Indicates the target surface has
- transparencyt with non-premultiplied alpha.
+ transparency with non-premultiplied alpha. Be aware that this may not be
+ supported on some systems, if the system compositor always expects content
+ with premultiplied alpha. In that case the behavior with this flag set is
+ expected to be equivalent to SurfaceHasPreMulAlpha.
\value sRGB Requests to pick an sRGB format for the swapchain and/or its
render target views, where applicable. Note that this implies that sRGB
@@ -3528,10 +3527,24 @@ QRhiResource::Type QRhiSwapChain::resourceType() const
\return The size of the window's associated surface or layer. Do not assume
this is the same as QWindow::size() * QWindow::devicePixelRatio().
- Can be called before buildOrResize() (but with window() already set), which
- allows setting the correct size for the depth-stencil buffer that is then
- used together with the swapchain's color buffers. Also used in combination
- with currentPixelSize() to detect size changes.
+ \note Can also be called before buildOrResize(), if at least window() is
+ already set) This in combination with currentPixelSize() allows to detect
+ when a swapchain needs to be resized. However, watch out for the fact that
+ the size of the underlying native object (surface, layer, or similar) is
+ "live", so whenever this function is called, it returns the latest value
+ reported by the underlying implementation, without any atomicity guarantee.
+ Therefore, using this function to determine pixel sizes for graphics
+ resources that are used in a frame is strongly discouraged. Rely on
+ currentPixelSize() instead which returns a size that is atomic and will not
+ change between buildOrResize() invocations.
+
+ \note For depth-stencil buffers used in combination with the swapchain's
+ color buffers, it is strongly recommended to rely on the automatic sizing
+ and rebuilding behavior provided by the
+ QRhiRenderBuffer:UsedWithSwapChainOnly flag. Avoid querying the surface
+ size via this function just to get a size that can be passed to
+ QRhiRenderBuffer::setPixelSize() as that would suffer from the lack of
+ atomicity as described above.
\sa currentPixelSize()
*/
@@ -3823,8 +3836,8 @@ void QRhiImplementation::compressedFormatInfo(QRhiTexture::Format format, const
break;
}
- const quint32 wblocks = (size.width() + xdim - 1) / xdim;
- const quint32 hblocks = (size.height() + ydim - 1) / ydim;
+ const quint32 wblocks = uint((size.width() + xdim - 1) / xdim);
+ const quint32 hblocks = uint((size.height() + ydim - 1) / ydim);
if (bpl)
*bpl = wblocks * blockSize;
@@ -3880,9 +3893,9 @@ void QRhiImplementation::textureFormatInfo(QRhiTexture::Format format, const QSi
}
if (bpl)
- *bpl = size.width() * bpc;
+ *bpl = uint(size.width()) * bpc;
if (byteSize)
- *byteSize = size.width() * size.height() * bpc;
+ *byteSize = uint(size.width() * size.height()) * bpc;
}
// Approximate because it excludes subresource alignment or multisampling.
@@ -3892,15 +3905,55 @@ quint32 QRhiImplementation::approxByteSizeForTexture(QRhiTexture::Format format,
quint32 approxSize = 0;
for (int level = 0; level < mipCount; ++level) {
quint32 byteSize = 0;
- const QSize size(qFloor(float(qMax(1, baseSize.width() >> level))),
- qFloor(float(qMax(1, baseSize.height() >> level))));
+ const QSize size(qFloor(qreal(qMax(1, baseSize.width() >> level))),
+ qFloor(qreal(qMax(1, baseSize.height() >> level))));
textureFormatInfo(format, size, nullptr, &byteSize);
approxSize += byteSize;
}
- approxSize *= layerCount;
+ approxSize *= uint(layerCount);
return approxSize;
}
+bool QRhiImplementation::sanityCheckGraphicsPipeline(QRhiGraphicsPipeline *ps)
+{
+ if (ps->cbeginShaderStages() == ps->cendShaderStages()) {
+ qWarning("Cannot build a graphics pipeline without any stages");
+ return false;
+ }
+
+ bool hasVertexStage = false;
+ for (auto it = ps->cbeginShaderStages(), itEnd = ps->cendShaderStages(); it != itEnd; ++it) {
+ if (!it->shader().isValid()) {
+ qWarning("Empty shader passed to graphics pipeline");
+ return false;
+ }
+ if (it->type() == QRhiShaderStage::Vertex) {
+ hasVertexStage = true;
+ const QRhiVertexInputLayout inputLayout = ps->vertexInputLayout();
+ if (inputLayout.cbeginAttributes() == inputLayout.cendAttributes()) {
+ qWarning("Vertex stage present without any vertex inputs");
+ return false;
+ }
+ }
+ }
+ if (!hasVertexStage) {
+ qWarning("Cannot build a graphics pipeline without a vertex stage");
+ return false;
+ }
+
+ if (!ps->renderPassDescriptor()) {
+ qWarning("Cannot build a graphics pipeline without a QRhiRenderPassDescriptor");
+ return false;
+ }
+
+ if (!ps->shaderResourceBindings()) {
+ qWarning("Cannot build a graphics pipeline without QRhiShaderResourceBindings");
+ return false;
+ }
+
+ return true;
+}
+
/*!
\internal
*/
@@ -4176,7 +4229,7 @@ void QRhiResourceUpdateBatch::merge(QRhiResourceUpdateBatch *other)
void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
{
if (size > 0)
- d->dynamicBufferUpdates.append({ buf, offset, size, data });
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::dynamicUpdate(buf, offset, size, data));
}
/*!
@@ -4190,7 +4243,7 @@ void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, int offset, i
void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
{
if (size > 0)
- d->staticBufferUploads.append({ buf, offset, size, data });
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::staticUpload(buf, offset, size, data));
}
/*!
@@ -4200,7 +4253,28 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, int offset, in
void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *data)
{
if (buf->size() > 0)
- d->staticBufferUploads.append({ buf, 0, 0, data });
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::staticUpload(buf, 0, 0, data));
+}
+
+/*!
+ Enqueues reading back a region of the QRhiBuffer \a buf. The size of the
+ region is specified by \a size in bytes, \a offset is the offset in bytes
+ to start reading from.
+
+ A readback is asynchronous. \a result contains a callback that is invoked
+ when the operation has completed. The data is provided in
+ QRhiBufferReadbackResult::data. Upon successful completion that QByteArray
+ will have a size equal to \a size. On failure the QByteArray will be empty.
+
+ \note Reading buffers with a usage different than QRhiBuffer::UniformBuffer
+ is supported only when the QRhi::ReadBackNonUniformBuffer feature is
+ reported as supported.
+
+ \a readBackTexture(), QRhi::isFeatureSupported()
+ */
+void QRhiResourceUpdateBatch::readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
+{
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::read(buf, offset, size, result));
}
/*!
@@ -4212,8 +4286,8 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *da
*/
void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
{
- if (!desc.entries().isEmpty())
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::textureUpload(tex, desc));
+ if (desc.cbeginEntries() != desc.cendEntries())
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::upload(tex, desc));
}
/*!
@@ -4238,7 +4312,7 @@ void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QImage &imag
*/
void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc)
{
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::textureCopy(dst, src, desc));
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::copy(dst, src, desc));
}
/*!
@@ -4290,7 +4364,7 @@ void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, co
*/
void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::textureRead(rb, result));
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::read(rb, result));
}
/*!
@@ -4302,7 +4376,7 @@ void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb,
*/
void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex, int layer)
{
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::textureMipGen(tex, layer));
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex, layer));
}
/*!
@@ -4351,8 +4425,7 @@ void QRhiResourceUpdateBatchPrivate::free()
{
Q_ASSERT(poolIndex >= 0 && rhi->resUpdPool[poolIndex] == q);
- dynamicBufferUpdates.clear();
- staticBufferUploads.clear();
+ bufferOps.clear();
textureOps.clear();
rhi->resUpdPoolMap.clearBit(poolIndex);
@@ -4361,9 +4434,13 @@ void QRhiResourceUpdateBatchPrivate::free()
void QRhiResourceUpdateBatchPrivate::merge(QRhiResourceUpdateBatchPrivate *other)
{
- dynamicBufferUpdates += other->dynamicBufferUpdates;
- staticBufferUploads += other->staticBufferUploads;
- textureOps += other->textureOps;
+ bufferOps.reserve(bufferOps.size() + other->bufferOps.size());
+ for (const BufferOp &op : qAsConst(other->bufferOps))
+ bufferOps.append(op);
+
+ textureOps.reserve(textureOps.size() + other->textureOps.size());
+ for (const TextureOp &op : qAsConst(other->textureOps))
+ textureOps.append(op);
}
/*!
@@ -5001,10 +5078,17 @@ const QRhiNativeHandles *QRhi::nativeHandles()
has to ensure external OpenGL code provided by the application can still
run like it did before with direct usage of OpenGL, as long as the QRhi is
using the OpenGL backend.
+
+ \return false when failed, similarly to QOpenGLContext::makeCurrent(). When
+ the operation failed, isDeviceLost() can be called to determine if there
+ was a loss of context situation. Such a check is equivalent to checking via
+ QOpenGLContext::isValid().
+
+ \sa QOpenGLContext::makeCurrent(), QOpenGLContext::isValid()
*/
-void QRhi::makeThreadLocalNativeContextCurrent()
+bool QRhi::makeThreadLocalNativeContextCurrent()
{
- d->makeThreadLocalNativeContextCurrent();
+ return d->makeThreadLocalNativeContextCurrent();
}
/*!
@@ -5020,6 +5104,70 @@ QRhiProfiler *QRhi::profiler()
}
/*!
+ Attempts to release resources in the backend's caches. This can include both
+ CPU and GPU resources. Only memory and resources that can be recreated
+ automatically are in scope. As an example, if the backend's
+ QRhiGraphicsPipeline implementation maintains a cache of shader compilation
+ results, calling this function leads to emptying that cache, thus
+ potentially freeing up memory and graphics resources.
+
+ Calling this function makes sense in resource constrained environments,
+ where at a certain point there is a need to ensure minimal resource usage,
+ at the expense of performance.
+ */
+void QRhi::releaseCachedResources()
+{
+ d->releaseCachedResources();
+}
+
+/*!
+ \return true if the graphics device was lost.
+
+ The loss of the device is typically detected in beginFrame(), endFrame() or
+ QRhiSwapChain::buildOrResize(), depending on the backend and the underlying
+ native APIs. The most common is endFrame() because that is where presenting
+ happens. With some backends QRhiSwapChain::buildOrResize() can also fail
+ due to a device loss. Therefore this function is provided as a generic way
+ to check if a device loss was detected by a previous operation.
+
+ When the device is lost, no further operations should be done via the QRhi.
+ Rather, all QRhi resources should be released, followed by destroying the
+ QRhi. A new QRhi can then be attempted to be created. If successful, all
+ graphics resources must be reinitialized. If not, try again later,
+ repeatedly.
+
+ While simple applications may decide to not care about device loss,
+ on the commonly used desktop platforms a device loss can happen
+ due to a variety of reasons, including physically disconnecting the
+ graphics adapter, disabling the device or driver, uninstalling or upgrading
+ the graphics driver, or due to errors that lead to a graphics device reset.
+ Some of these can happen under perfectly normal circumstances as well, for
+ example the upgrade of the graphics driver to a newer version is a common
+ task that can happen at any time while a Qt application is running. Users
+ may very well expect applications to be able to survive this, even when the
+ application is actively using an API like OpenGL or Direct3D.
+
+ Qt's own frameworks built on top of QRhi, such as, Qt Quick, can be
+ expected to handle and take appropriate measures when a device loss occurs.
+ If the data for graphics resources, such as textures and buffers, are still
+ available on the CPU side, such an event may not be noticeable on the
+ application level at all since graphics resources can seamlessly be
+ reinitialized then. However, applications and libraries working directly
+ with QRhi are expected to be prepared to check and handle device loss
+ situations themselves.
+
+ \note With OpenGL, applications may need to opt-in to context reset
+ notifications by setting QSurfaceFormat::ResetNotification on the
+ QOpenGLContext. This is typically done by enabling the flag in
+ QRhiGles2InitParams::format. Keep in mind however that some systems may
+ generate context resets situations even when this flag is not set.
+ */
+bool QRhi::isDeviceLost() const
+{
+ return d->isDeviceLost();
+}
+
+/*!
\return a new graphics pipeline resource.
\sa QRhiResource::release()
@@ -5180,7 +5328,17 @@ QRhiSwapChain *QRhi::newSwapChain()
\endlist
- \sa endFrame(), beginOffscreenFrame()
+ \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
+ value on failure. Some of these should be treated as soft, "try again
+ later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
+ the swapchain is to be resized or updated by calling
+ QRhiSwapChain::buildOrResize(). The application should then attempt to
+ generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
+ lost but this may also be recoverable by releasing all resources, including
+ the QRhi itself, and then recreating all resources. See isDeviceLost() for
+ further discussion.
+
+ \sa endFrame(), beginOffscreenFrame(), isDeviceLost()
*/
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags)
{
@@ -5205,7 +5363,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
Passing QRhi::SkipPresent skips queuing the Present command or calling
swapBuffers.
- \sa beginFrame()
+ \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
+ value on failure. Some of these should be treated as soft, "try again
+ later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
+ the swapchain is to be resized or updated by calling
+ QRhiSwapChain::buildOrResize(). The application should then attempt to
+ generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
+ lost but this may also be recoverable by releasing all resources, including
+ the QRhi itself, and then recreating all resources. See isDeviceLost() for
+ further discussion.
+
+ \sa beginFrame(), isDeviceLost()
*/
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags)
{
@@ -5419,7 +5587,7 @@ static inline QRhiPassResourceTracker::BufferStage earlierStage(QRhiPassResource
void QRhiPassResourceTracker::registerBuffer(QRhiBuffer *buf, int slot, BufferAccess *access, BufferStage *stage,
const UsageState &state)
{
- auto it = std::find_if(m_buffers.begin(), m_buffers.end(), [buf](const Buffer &b) { return b.buf == buf; });
+ auto it = m_buffers.find(buf);
if (it != m_buffers.end()) {
if (it->access != *access) {
const QByteArray name = buf->name();
@@ -5435,12 +5603,11 @@ void QRhiPassResourceTracker::registerBuffer(QRhiBuffer *buf, int slot, BufferAc
}
Buffer b;
- b.buf = buf;
b.slot = slot;
b.access = *access;
b.stage = *stage;
b.stateAtPassBegin = state; // first use -> initial state
- m_buffers.append(b);
+ m_buffers.insert(buf, b);
}
static inline QRhiPassResourceTracker::TextureStage earlierStage(QRhiPassResourceTracker::TextureStage a,
@@ -5459,7 +5626,7 @@ static inline bool isImageLoadStore(QRhiPassResourceTracker::TextureAccess acces
void QRhiPassResourceTracker::registerTexture(QRhiTexture *tex, TextureAccess *access, TextureStage *stage,
const UsageState &state)
{
- auto it = std::find_if(m_textures.begin(), m_textures.end(), [tex](const Texture &t) { return t.tex == tex; });
+ auto it = m_textures.find(tex);
if (it != m_textures.end()) {
if (it->access != *access) {
// Different subresources of a texture may be used for both load
@@ -5483,11 +5650,10 @@ void QRhiPassResourceTracker::registerTexture(QRhiTexture *tex, TextureAccess *a
}
Texture t;
- t.tex = tex;
t.access = *access;
t.stage = *stage;
t.stateAtPassBegin = state; // first use -> initial state
- m_textures.append(t);
+ m_textures.insert(tex, t);
}
QRhiPassResourceTracker::BufferStage QRhiPassResourceTracker::toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages)
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 2d36c19e99..907924c788 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -52,6 +52,7 @@
#include <QSize>
#include <QMatrix4x4>
#include <QVector>
+#include <QVarLengthArray>
#include <QThread>
#include <QColor>
#include <QImage>
@@ -71,7 +72,6 @@ class QRhiCommandBuffer;
class QRhiResourceUpdateBatch;
class QRhiResourceUpdateBatchPrivate;
class QRhiProfiler;
-class QRhiShaderResourceBindingPrivate;
class Q_GUI_EXPORT QRhiDepthStencilClearValue
{
@@ -239,15 +239,42 @@ class Q_GUI_EXPORT QRhiVertexInputLayout
public:
QRhiVertexInputLayout() = default;
- QVector<QRhiVertexInputBinding> bindings() const { return m_bindings; }
- void setBindings(const QVector<QRhiVertexInputBinding> &v) { m_bindings = v; }
-
- QVector<QRhiVertexInputAttribute> attributes() const { return m_attributes; }
- void setAttributes(const QVector<QRhiVertexInputAttribute> &v) { m_attributes = v; }
+ void setBindings(std::initializer_list<QRhiVertexInputBinding> list) { m_bindings = list; }
+ template<typename InputIterator>
+ void setBindings(InputIterator first, InputIterator last)
+ {
+ m_bindings.clear();
+ std::copy(first, last, std::back_inserter(m_bindings));
+ }
+ void setBindings(const QVector<QRhiVertexInputBinding> &bindings) // compat., to be removed
+ {
+ setBindings(bindings.cbegin(), bindings.cend());
+ }
+ const QRhiVertexInputBinding *cbeginBindings() const { return m_bindings.cbegin(); }
+ const QRhiVertexInputBinding *cendBindings() const { return m_bindings.cend(); }
+ const QRhiVertexInputBinding *bindingAt(int index) const { return &m_bindings.at(index); }
+
+ void setAttributes(std::initializer_list<QRhiVertexInputAttribute> list) { m_attributes = list; }
+ template<typename InputIterator>
+ void setAttributes(InputIterator first, InputIterator last)
+ {
+ m_attributes.clear();
+ std::copy(first, last, std::back_inserter(m_attributes));
+ }
+ void setAttributes(const QVector<QRhiVertexInputAttribute> &attributes) // compat., to be removed
+ {
+ setAttributes(attributes.cbegin(), attributes.cend());
+ }
+ const QRhiVertexInputAttribute *cbeginAttributes() const { return m_attributes.cbegin(); }
+ const QRhiVertexInputAttribute *cendAttributes() const { return m_attributes.cend(); }
private:
- QVector<QRhiVertexInputBinding> m_bindings;
- QVector<QRhiVertexInputAttribute> m_attributes;
+ QVarLengthArray<QRhiVertexInputBinding, 8> m_bindings;
+ QVarLengthArray<QRhiVertexInputAttribute, 8> m_attributes;
+
+ friend Q_GUI_EXPORT bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW;
+ friend Q_GUI_EXPORT uint qHash(const QRhiVertexInputLayout &v, uint seed) Q_DECL_NOTHROW;
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &);
};
Q_DECLARE_TYPEINFO(QRhiVertexInputLayout, Q_MOVABLE_TYPE);
@@ -320,10 +347,6 @@ public:
Q_DECLARE_FLAGS(StageFlags, StageFlag)
QRhiShaderResourceBinding();
- QRhiShaderResourceBinding(const QRhiShaderResourceBinding &other);
- QRhiShaderResourceBinding &operator=(const QRhiShaderResourceBinding &other);
- ~QRhiShaderResourceBinding();
- void detach();
bool isLayoutCompatible(const QRhiShaderResourceBinding &other) const;
@@ -344,19 +367,49 @@ public:
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf);
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
+ struct Data
+ {
+ int binding;
+ QRhiShaderResourceBinding::StageFlags stage;
+ QRhiShaderResourceBinding::Type type;
+ struct UniformBufferData {
+ QRhiBuffer *buf;
+ int offset;
+ int maybeSize;
+ bool hasDynamicOffset;
+ };
+ struct SampledTextureData {
+ QRhiTexture *tex;
+ QRhiSampler *sampler;
+ };
+ struct StorageImageData {
+ QRhiTexture *tex;
+ int level;
+ };
+ struct StorageBufferData {
+ QRhiBuffer *buf;
+ int offset;
+ int maybeSize;
+ };
+ union {
+ UniformBufferData ubuf;
+ SampledTextureData stex;
+ StorageImageData simage;
+ StorageBufferData sbuf;
+ } u;
+ };
+
+ Data *data() { return &d; }
+ const Data *data() const { return &d; }
+
private:
- QRhiShaderResourceBindingPrivate *d;
- friend class QRhiShaderResourceBindingPrivate;
- friend Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &, const QRhiShaderResourceBinding &) Q_DECL_NOTHROW;
- friend Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &, const QRhiShaderResourceBinding &) Q_DECL_NOTHROW;
- friend Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &, uint) Q_DECL_NOTHROW;
-#ifndef QT_NO_DEBUG_STREAM
- friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBinding &);
-#endif
+ Data d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBinding::StageFlags)
+Q_DECLARE_TYPEINFO(QRhiShaderResourceBinding, Q_MOVABLE_TYPE);
+
Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &b, uint seed = 0) Q_DECL_NOTHROW;
@@ -412,8 +465,16 @@ public:
QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiRenderBuffer *depthStencilBuffer);
QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiTexture *depthTexture);
- QVector<QRhiColorAttachment> colorAttachments() const { return m_colorAttachments; }
- void setColorAttachments(const QVector<QRhiColorAttachment> &att) { m_colorAttachments = att; }
+ void setColorAttachments(std::initializer_list<QRhiColorAttachment> list) { m_colorAttachments = list; }
+ template<typename InputIterator>
+ void setColorAttachments(InputIterator first, InputIterator last)
+ {
+ m_colorAttachments.clear();
+ std::copy(first, last, std::back_inserter(m_colorAttachments));
+ }
+ const QRhiColorAttachment *cbeginColorAttachments() const { return m_colorAttachments.cbegin(); }
+ const QRhiColorAttachment *cendColorAttachments() const { return m_colorAttachments.cend(); }
+ const QRhiColorAttachment *colorAttachmentAt(int index) const { return &m_colorAttachments.at(index); }
QRhiRenderBuffer *depthStencilBuffer() const { return m_depthStencilBuffer; }
void setDepthStencilBuffer(QRhiRenderBuffer *renderBuffer) { m_depthStencilBuffer = renderBuffer; }
@@ -422,7 +483,7 @@ public:
void setDepthTexture(QRhiTexture *texture) { m_depthTexture = texture; }
private:
- QVector<QRhiColorAttachment> m_colorAttachments;
+ QVarLengthArray<QRhiColorAttachment, 8> m_colorAttachments;
QRhiRenderBuffer *m_depthStencilBuffer = nullptr;
QRhiTexture *m_depthTexture = nullptr;
};
@@ -489,14 +550,23 @@ class Q_GUI_EXPORT QRhiTextureUploadDescription
public:
QRhiTextureUploadDescription() = default;
QRhiTextureUploadDescription(const QRhiTextureUploadEntry &entry);
- QRhiTextureUploadDescription(const QVector<QRhiTextureUploadEntry> &entries);
-
- QVector<QRhiTextureUploadEntry> entries() const { return m_entries; }
- void setEntries(const QVector<QRhiTextureUploadEntry> &entries) { m_entries = entries; }
- void append(const QRhiTextureUploadEntry &entry);
+ QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list);
+ QRhiTextureUploadDescription(const QVector<QRhiTextureUploadEntry> &entries) // compat., to be removed
+ : m_entries(entries.cbegin(), entries.cend())
+ { }
+
+ void setEntries(std::initializer_list<QRhiTextureUploadEntry> list) { m_entries = list; }
+ template<typename InputIterator>
+ void setEntries(InputIterator first, InputIterator last)
+ {
+ m_entries.clear();
+ std::copy(first, last, std::back_inserter(m_entries));
+ }
+ const QRhiTextureUploadEntry *cbeginEntries() const { return m_entries.cbegin(); }
+ const QRhiTextureUploadEntry *cendEntries() const { return m_entries.cend(); }
private:
- QVector<QRhiTextureUploadEntry> m_entries;
+ QVarLengthArray<QRhiTextureUploadEntry, 16> m_entries;
};
Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription, Q_MOVABLE_TYPE);
@@ -900,8 +970,22 @@ class Q_GUI_EXPORT QRhiShaderResourceBindings : public QRhiResource
public:
QRhiResource::Type resourceType() const override;
- QVector<QRhiShaderResourceBinding> bindings() const { return m_bindings; }
- void setBindings(const QVector<QRhiShaderResourceBinding> &b) { m_bindings = b; }
+ void setBindings(std::initializer_list<QRhiShaderResourceBinding> list) { m_bindings = list; }
+
+ template<typename InputIterator>
+ void setBindings(InputIterator first, InputIterator last)
+ {
+ m_bindings.clear();
+ std::copy(first, last, std::back_inserter(m_bindings));
+ }
+
+ void setBindings(const QVector<QRhiShaderResourceBinding> &bindings) // compat., to be removed
+ {
+ setBindings(bindings.cbegin(), bindings.cend());
+ }
+
+ const QRhiShaderResourceBinding *cbeginBindings() const { return m_bindings.cbegin(); }
+ const QRhiShaderResourceBinding *cendBindings() const { return m_bindings.cend(); }
bool isLayoutCompatible(const QRhiShaderResourceBindings *other) const;
@@ -909,7 +993,7 @@ public:
protected:
QRhiShaderResourceBindings(QRhiImplementation *rhi);
- QVector<QRhiShaderResourceBinding> m_bindings;
+ QVarLengthArray<QRhiShaderResourceBinding, 8> m_bindings;
#ifndef QT_NO_DEBUG_STREAM
friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
#endif
@@ -932,6 +1016,7 @@ public:
enum Topology {
Triangles,
TriangleStrip,
+ TriangleFan,
Lines,
LineStrip,
Points
@@ -1040,8 +1125,15 @@ public:
FrontFace frontFace() const { return m_frontFace; }
void setFrontFace(FrontFace f) { m_frontFace = f; }
- QVector<TargetBlend> targetBlends() const { return m_targetBlends; }
- void setTargetBlends(const QVector<TargetBlend> &blends) { m_targetBlends = blends; }
+ void setTargetBlends(std::initializer_list<TargetBlend> list) { m_targetBlends = list; }
+ template<typename InputIterator>
+ void setTargetBlends(InputIterator first, InputIterator last)
+ {
+ m_targetBlends.clear();
+ std::copy(first, last, std::back_inserter(m_targetBlends));
+ }
+ const TargetBlend *cbeginTargetBlends() const { return m_targetBlends.cbegin(); }
+ const TargetBlend *cendTargetBlends() const { return m_targetBlends.cend(); }
bool hasDepthTest() const { return m_depthTest; }
void setDepthTest(bool enable) { m_depthTest = enable; }
@@ -1073,8 +1165,19 @@ public:
float lineWidth() const { return m_lineWidth; }
void setLineWidth(float width) { m_lineWidth = width; }
- QVector<QRhiShaderStage> shaderStages() const { return m_shaderStages; }
- void setShaderStages(const QVector<QRhiShaderStage> &stages) { m_shaderStages = stages; }
+ void setShaderStages(std::initializer_list<QRhiShaderStage> list) { m_shaderStages = list; }
+ template<typename InputIterator>
+ void setShaderStages(InputIterator first, InputIterator last)
+ {
+ m_shaderStages.clear();
+ std::copy(first, last, std::back_inserter(m_shaderStages));
+ }
+ void setShaderStages(const QVector<QRhiShaderStage> &stages) // compat., to be removed
+ {
+ setShaderStages(stages.cbegin(), stages.cend());
+ }
+ const QRhiShaderStage *cbeginShaderStages() const { return m_shaderStages.cbegin(); }
+ const QRhiShaderStage *cendShaderStages() const { return m_shaderStages.cend(); }
QRhiVertexInputLayout vertexInputLayout() const { return m_vertexInputLayout; }
void setVertexInputLayout(const QRhiVertexInputLayout &layout) { m_vertexInputLayout = layout; }
@@ -1093,7 +1196,7 @@ protected:
Topology m_topology = Triangles;
CullMode m_cullMode = None;
FrontFace m_frontFace = CCW;
- QVector<TargetBlend> m_targetBlends;
+ QVarLengthArray<TargetBlend, 8> m_targetBlends;
bool m_depthTest = false;
bool m_depthWrite = false;
CompareOp m_depthOp = Less;
@@ -1104,7 +1207,7 @@ protected:
quint32 m_stencilWriteMask = 0xFF;
int m_sampleCount = 1;
float m_lineWidth = 1.0f;
- QVector<QRhiShaderStage> m_shaderStages;
+ QVarLengthArray<QRhiShaderStage, 4> m_shaderStages;
QRhiVertexInputLayout m_vertexInputLayout;
QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
@@ -1251,6 +1354,12 @@ struct Q_GUI_EXPORT QRhiReadbackResult
QByteArray data;
}; // non-movable due to the std::function
+struct Q_GUI_EXPORT QRhiBufferReadbackResult
+{
+ std::function<void()> completed = nullptr;
+ QByteArray data;
+};
+
class Q_GUI_EXPORT QRhiResourceUpdateBatch
{
public:
@@ -1263,6 +1372,7 @@ public:
void updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
void uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
void uploadStaticBuffer(QRhiBuffer *buf, const void *data);
+ void readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result);
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc);
void uploadTexture(QRhiTexture *tex, const QImage &image);
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription());
@@ -1294,7 +1404,8 @@ public:
enum Flag {
EnableProfiling = 1 << 0,
- EnableDebugMarkers = 1 << 1
+ EnableDebugMarkers = 1 << 1,
+ PreferSoftwareRenderer = 1 << 2
};
Q_DECLARE_FLAGS(Flags, Flag)
@@ -1322,7 +1433,10 @@ public:
WideLines,
VertexShaderPointSize,
BaseVertex,
- BaseInstance
+ BaseInstance,
+ TriangleFanTopology,
+ ReadBackNonUniformBuffer,
+ ReadBackNonBaseMipLevel
};
enum BeginFrameFlag {
@@ -1413,13 +1527,17 @@ public:
int resourceLimit(ResourceLimit limit) const;
const QRhiNativeHandles *nativeHandles();
- void makeThreadLocalNativeContextCurrent();
+ bool makeThreadLocalNativeContextCurrent();
QRhiProfiler *profiler();
static const int MAX_LAYERS = 6; // cubemaps only
static const int MAX_LEVELS = 16; // a width and/or height of 65536 should be enough for everyone
+ void releaseCachedResources();
+
+ bool isDeviceLost() const;
+
protected:
QRhi();
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 0914cf268b..baffe28202 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -156,7 +156,9 @@ public:
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
virtual const QRhiNativeHandles *nativeHandles() = 0;
virtual void sendVMemStatsToProfiler() = 0;
- virtual void makeThreadLocalNativeContextCurrent() = 0;
+ virtual bool makeThreadLocalNativeContextCurrent() = 0;
+ virtual void releaseCachedResources() = 0;
+ virtual bool isDeviceLost() const = 0;
bool isCompressedFormat(QRhiTexture::Format format) const;
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
@@ -203,8 +205,12 @@ public:
cleanupCallbacks.append(callback);
}
+ bool sanityCheckGraphicsPipeline(QRhiGraphicsPipeline *ps);
+
QRhi *q;
+ static const int MAX_SHADER_CACHE_ENTRIES = 128;
+
protected:
bool debugMarkers = false;
int currentFrameSlot = 0; // for vk, mtl, and similar. unused by gl and d3d11.
@@ -214,7 +220,7 @@ private:
QRhi::Implementation implType;
QThread *implThread;
QRhiProfiler profiler;
- QVector<QRhiResourceUpdateBatch *> resUpdPool;
+ QVarLengthArray<QRhiResourceUpdateBatch *, 4> resUpdPool;
QBitArray resUpdPoolMap;
QSet<QRhiResource *> resources;
QSet<QRhiResource *> pendingReleaseAndDestroyResources;
@@ -229,27 +235,37 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T,
T *x, T *y, T *w, T *h)
{
// x,y are bottom-left in QRhiScissor and QRhiViewport but top-left in
- // Vulkan/Metal/D3D. We also need proper clamping since some
- // validation/debug layers are allergic to out of bounds scissor or
- // viewport rects.
+ // Vulkan/Metal/D3D. Our input is an OpenGL-style scissor rect where both
+ // negative x or y, and partly or completely out of bounds rects are
+ // allowed. The only thing the input here cannot have is a negative width
+ // or height. We must handle all other input gracefully, clamping to a zero
+ // width or height rect in the worst case, and ensuring the resulting rect
+ // is inside the rendertarget's bounds because some APIs' validation/debug
+ // layers are allergic to out of bounds scissor or viewport rects.
const T outputWidth = outputSize.width();
const T outputHeight = outputSize.height();
const T inputWidth = r[2];
const T inputHeight = r[3];
- *x = qMax<T>(0, r[0]);
- *y = qMax<T>(0, outputHeight - (r[1] + inputHeight));
- *w = inputWidth;
- *h = inputHeight;
-
- if (*x >= outputWidth || *y >= outputHeight)
+ if (inputWidth < 0 || inputHeight < 0)
return false;
+ *x = r[0];
+ *y = outputHeight - (r[1] + inputHeight);
+
+ const T widthOffset = *x < 0 ? -*x : 0;
+ const T heightOffset = *y < 0 ? -*y : 0;
+
+ *x = qBound<T>(0, *x, outputWidth - 1);
+ *y = qBound<T>(0, *y, outputHeight - 1);
+ *w = qMax<T>(0, inputWidth - widthOffset);
+ *h = qMax<T>(0, inputHeight - heightOffset);
+
if (*x + *w > outputWidth)
- *w = outputWidth - *x;
+ *w = qMax<T>(0, outputWidth - *x - 1);
if (*y + *h > outputHeight)
- *h = outputHeight - *y;
+ *h = qMax<T>(0, outputHeight - *y - 1);
return true;
}
@@ -257,26 +273,49 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T,
class QRhiResourceUpdateBatchPrivate
{
public:
- struct DynamicBufferUpdate {
- DynamicBufferUpdate() { }
- DynamicBufferUpdate(QRhiBuffer *buf_, int offset_, int size_, const void *data_)
- : buf(buf_), offset(offset_), data(reinterpret_cast<const char *>(data_), size_)
- { }
-
- QRhiBuffer *buf = nullptr;
- int offset = 0;
+ struct BufferOp {
+ enum Type {
+ DynamicUpdate,
+ StaticUpload,
+ Read
+ };
+ Type type;
+ QRhiBuffer *buf;
+ int offset;
QByteArray data;
- };
+ int readSize;
+ QRhiBufferReadbackResult *result;
- struct StaticBufferUpload {
- StaticBufferUpload() { }
- StaticBufferUpload(QRhiBuffer *buf_, int offset_, int size_, const void *data_)
- : buf(buf_), offset(offset_), data(reinterpret_cast<const char *>(data_), size_ ? size_ : buf_->size())
- { }
+ static BufferOp dynamicUpdate(QRhiBuffer *buf, int offset, int size, const void *data)
+ {
+ BufferOp op;
+ op.type = DynamicUpdate;
+ op.buf = buf;
+ op.offset = offset;
+ op.data = QByteArray(reinterpret_cast<const char *>(data), size ? size : buf->size());
+ return op;
+ }
- QRhiBuffer *buf = nullptr;
- int offset = 0;
- QByteArray data;
+ static BufferOp staticUpload(QRhiBuffer *buf, int offset, int size, const void *data)
+ {
+ BufferOp op;
+ op.type = StaticUpload;
+ op.buf = buf;
+ op.offset = offset;
+ op.data = QByteArray(reinterpret_cast<const char *>(data), size ? size : buf->size());
+ return op;
+ }
+
+ static BufferOp read(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
+ {
+ BufferOp op;
+ op.type = Read;
+ op.buf = buf;
+ op.offset = offset;
+ op.readSize = size;
+ op.result = result;
+ return op;
+ }
};
struct TextureOp {
@@ -284,74 +323,62 @@ public:
Upload,
Copy,
Read,
- MipGen
+ GenMips
};
Type type;
- struct SUpload {
- QRhiTexture *tex = nullptr;
- // Specifying multiple uploads for a subresource must be supported.
- // In the backend this can then end up, where applicable, as a
- // single, batched copy operation with only one set of barriers.
- // This helps when doing for example glyph cache fills.
- QVector<QRhiTextureSubresourceUploadDescription> subresDesc[QRhi::MAX_LAYERS][QRhi::MAX_LEVELS];
- } upload;
- struct SCopy {
- QRhiTexture *dst = nullptr;
- QRhiTexture *src = nullptr;
- QRhiTextureCopyDescription desc;
- } copy;
- struct SRead {
- QRhiReadbackDescription rb;
- QRhiReadbackResult *result;
- } read;
- struct SMipGen {
- QRhiTexture *tex = nullptr;
- int layer = 0;
- } mipgen;
-
- static TextureOp textureUpload(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
+ QRhiTexture *dst;
+ // Specifying multiple uploads for a subresource must be supported.
+ // In the backend this can then end up, where applicable, as a
+ // single, batched copy operation with only one set of barriers.
+ // This helps when doing for example glyph cache fills.
+ QVector<QRhiTextureSubresourceUploadDescription> subresDesc[QRhi::MAX_LAYERS][QRhi::MAX_LEVELS];
+ QRhiTexture *src;
+ QRhiTextureCopyDescription desc;
+ QRhiReadbackDescription rb;
+ QRhiReadbackResult *result;
+ int layer;
+
+ static TextureOp upload(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
{
TextureOp op;
op.type = Upload;
- op.upload.tex = tex;
- const QVector<QRhiTextureUploadEntry> &entries(desc.entries());
- for (const QRhiTextureUploadEntry &entry : entries)
- op.upload.subresDesc[entry.layer()][entry.level()].append(entry.description());
+ op.dst = tex;
+ for (auto it = desc.cbeginEntries(), itEnd = desc.cendEntries(); it != itEnd; ++it)
+ op.subresDesc[it->layer()][it->level()].append(it->description());
return op;
}
- static TextureOp textureCopy(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc)
+ static TextureOp copy(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc)
{
TextureOp op;
op.type = Copy;
- op.copy.dst = dst;
- op.copy.src = src;
- op.copy.desc = desc;
+ op.dst = dst;
+ op.src = src;
+ op.desc = desc;
return op;
}
- static TextureOp textureRead(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
+ static TextureOp read(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
TextureOp op;
op.type = Read;
- op.read.rb = rb;
- op.read.result = result;
+ op.rb = rb;
+ op.result = result;
return op;
}
- static TextureOp textureMipGen(QRhiTexture *tex, int layer)
+ static TextureOp genMips(QRhiTexture *tex, int layer)
{
TextureOp op;
- op.type = MipGen;
- op.mipgen.tex = tex;
- op.mipgen.layer = layer;
+ op.type = GenMips;
+ op.dst = tex;
+ op.layer = layer;
return op;
}
};
- QVector<DynamicBufferUpdate> dynamicBufferUpdates;
- QVector<StaticBufferUpload> staticBufferUploads;
- QVector<TextureOp> textureOps;
+ QVarLengthArray<BufferOp, 1024> bufferOps;
+ QVarLengthArray<TextureOp, 256> textureOps;
QRhiResourceUpdateBatch *q = nullptr;
QRhiImplementation *rhi = nullptr;
@@ -363,61 +390,9 @@ public:
static QRhiResourceUpdateBatchPrivate *get(QRhiResourceUpdateBatch *b) { return b->d; }
};
-Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::StaticBufferUpload, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::BufferOp, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureOp, Q_MOVABLE_TYPE);
-class Q_GUI_EXPORT QRhiShaderResourceBindingPrivate
-{
-public:
- QRhiShaderResourceBindingPrivate()
- : ref(1)
- {
- }
-
- QRhiShaderResourceBindingPrivate(const QRhiShaderResourceBindingPrivate *other)
- : ref(1),
- binding(other->binding),
- stage(other->stage),
- type(other->type),
- u(other->u)
- {
- }
-
- static QRhiShaderResourceBindingPrivate *get(QRhiShaderResourceBinding *s) { return s->d; }
- static const QRhiShaderResourceBindingPrivate *get(const QRhiShaderResourceBinding *s) { return s->d; }
-
- QAtomicInt ref;
- int binding;
- QRhiShaderResourceBinding::StageFlags stage;
- QRhiShaderResourceBinding::Type type;
- struct UniformBufferData {
- QRhiBuffer *buf;
- int offset;
- int maybeSize;
- bool hasDynamicOffset;
- };
- struct SampledTextureData {
- QRhiTexture *tex;
- QRhiSampler *sampler;
- };
- struct StorageImageData {
- QRhiTexture *tex;
- int level;
- };
- struct StorageBufferData {
- QRhiBuffer *buf;
- int offset;
- int maybeSize;
- };
- union {
- UniformBufferData ubuf;
- SampledTextureData stex;
- StorageImageData simage;
- StorageBufferData sbuf;
- } u;
-};
-
template<typename T>
struct QRhiBatchedBindings
{
@@ -540,28 +515,32 @@ public:
const UsageState &state);
struct Buffer {
- QRhiBuffer *buf;
int slot;
BufferAccess access;
BufferStage stage;
UsageState stateAtPassBegin;
};
- const QVector<Buffer> *buffers() const { return &m_buffers; }
+
+ using BufferIterator = QHash<QRhiBuffer *, Buffer>::const_iterator;
+ BufferIterator cbeginBuffers() const { return m_buffers.cbegin(); }
+ BufferIterator cendBuffers() const { return m_buffers.cend(); }
struct Texture {
- QRhiTexture *tex;
TextureAccess access;
TextureStage stage;
UsageState stateAtPassBegin;
};
- const QVector<Texture> *textures() const { return &m_textures; }
+
+ using TextureIterator = QHash<QRhiTexture *, Texture>::const_iterator;
+ TextureIterator cbeginTextures() const { return m_textures.cbegin(); }
+ TextureIterator cendTextures() const { return m_textures.cend(); }
static BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages);
static TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages);
private:
- QVector<Buffer> m_buffers;
- QVector<Texture> m_textures;
+ QHash<QRhiBuffer *, Buffer> m_buffers;
+ QHash<QRhiTexture *, Texture> m_textures;
};
Q_DECLARE_TYPEINFO(QRhiPassResourceTracker::Buffer, Q_MOVABLE_TYPE);
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 3e136cdb80..717f3e6d6c 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -36,6 +36,7 @@
#include "qrhid3d11_p_p.h"
#include "qshader_p.h"
+#include "cs_tdr_p.h"
#include <QWindow>
#include <QOperatingSystemVersion>
#include <qmath.h>
@@ -118,10 +119,20 @@ QT_BEGIN_NAMESPACE
\c{ID3D11Texture2D *}.
*/
+// help mingw with its ancient sdk headers
+#ifndef DXGI_ADAPTER_FLAG_SOFTWARE
+#define DXGI_ADAPTER_FLAG_SOFTWARE 2
+#endif
+
QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice)
- : ofr(this)
+ : ofr(this),
+ deviceCurse(this)
{
debugLayer = params->enableDebugLayer;
+
+ deviceCurse.framesToActivate = params->framesUntilKillingDeviceViaTdr;
+ deviceCurse.permanent = params->repeatDeviceKill;
+
importedDevice = importDevice != nullptr;
if (importedDevice) {
dev = reinterpret_cast<ID3D11Device *>(importDevice->dev);
@@ -155,7 +166,7 @@ static QString comErrorMessage(HRESULT hr)
}
template <class Int>
-static inline Int aligned(Int v, Int byteAlign)
+inline Int aligned(Int v, Int byteAlign)
{
return (v + byteAlign - 1) & ~(byteAlign - 1);
}
@@ -166,7 +177,7 @@ static IDXGIFactory1 *createDXGIFactory2()
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **);
QSystemLibrary dxgilib(QStringLiteral("dxgi"));
- if (auto createDXGIFactory2 = (PtrCreateDXGIFactory2)dxgilib.resolve("CreateDXGIFactory2")) {
+ if (auto createDXGIFactory2 = reinterpret_cast<PtrCreateDXGIFactory2>(dxgilib.resolve("CreateDXGIFactory2"))) {
const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result));
if (FAILED(hr)) {
qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr)));
@@ -221,11 +232,29 @@ bool QRhiD3D11::create(QRhi::Flags flags)
int requestedAdapterIndex = -1;
if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX"))
requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
- for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
+
+ if (requestedAdapterIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) {
+ for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
+ DXGI_ADAPTER_DESC1 desc;
+ adapter->GetDesc1(&desc);
+ adapter->Release();
+ if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
+ requestedAdapterIndex = adapterIndex;
+ break;
+ }
+ }
+ }
+
+ for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags);
+ const QString name = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description));
+ qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (vendor 0x%X device 0x%X flags 0x%X)",
+ adapterIndex,
+ qPrintable(name),
+ desc.VendorId,
+ desc.DeviceId,
+ desc.Flags);
if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) {
adapterToUse = adapter;
qCDebug(QRHI_LOG_INFO, " using this adapter");
@@ -261,16 +290,33 @@ bool QRhiD3D11::create(QRhi::Flags flags)
if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations))))
annotations = nullptr;
+ deviceLost = false;
+
nativeHandlesStruct.dev = dev;
nativeHandlesStruct.context = context;
+ if (deviceCurse.framesToActivate > 0)
+ deviceCurse.initResources();
+
return true;
}
+void QRhiD3D11::clearShaderCache()
+{
+ for (Shader &s : m_shaderCache)
+ s.s->Release();
+
+ m_shaderCache.clear();
+}
+
void QRhiD3D11::destroy()
{
finishActiveReadbacks();
+ clearShaderCache();
+
+ deviceCurse.releaseResources();
+
if (annotations) {
annotations->Release();
annotations = nullptr;
@@ -322,9 +368,9 @@ DXGI_SAMPLE_DESC QRhiD3D11::effectiveSampleCount(int sampleCount) const
return desc;
}
- desc.Count = s;
+ desc.Count = UINT(s);
if (s > 1)
- desc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
+ desc.Quality = UINT(D3D11_STANDARD_MULTISAMPLE_PATTERN);
else
desc.Quality = 0;
@@ -423,6 +469,12 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::BaseInstance:
return true;
+ case QRhi::TriangleFanTopology:
+ return false;
+ case QRhi::ReadBackNonUniformBuffer:
+ return true;
+ case QRhi::ReadBackNonBaseMipLevel:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -456,9 +508,20 @@ void QRhiD3D11::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiD3D11::makeThreadLocalNativeContextCurrent()
+bool QRhiD3D11::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
+}
+
+void QRhiD3D11::releaseCachedResources()
+{
+ clearShaderCache();
+}
+
+bool QRhiD3D11::isDeviceLost() const
+{
+ return deviceLost;
}
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -541,7 +604,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
bool hasDynamicOffsetInSrb = false;
bool srbUpdate = false;
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
@@ -640,7 +703,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
- const uint binding = dynOfs.first;
+ const uint binding = uint(dynOfs.first);
Q_ASSERT(aligned(dynOfs.second, quint32(256)) == dynOfs.second);
const uint offsetInConstants = dynOfs.second / 16;
*p++ = binding;
@@ -685,13 +748,14 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
cmd.cmd = QD3D11CommandBuffer::Command::BindVertexBuffers;
cmd.args.bindVertexBuffers.startSlot = startBinding;
cmd.args.bindVertexBuffers.slotCount = bindingCount;
- const QVector<QRhiVertexInputBinding> inputBindings =
- QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline)->m_vertexInputLayout.bindings();
- for (int i = 0, ie = qMin(bindingCount, inputBindings.count()); i != ie; ++i) {
+ QD3D11GraphicsPipeline *psD = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
+ const QRhiVertexInputLayout &inputLayout(psD->m_vertexInputLayout);
+ const int inputBindingCount = inputLayout.cendBindings() - inputLayout.cbeginBindings();
+ for (int i = 0, ie = qMin(bindingCount, inputBindingCount); i != ie; ++i) {
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, bindings[i].first);
cmd.args.bindVertexBuffers.buffers[i] = bufD->buffer;
cmd.args.bindVertexBuffers.offsets[i] = bindings[i].second;
- cmd.args.bindVertexBuffers.strides[i] = inputBindings[i].stride();
+ cmd.args.bindVertexBuffers.strides[i] = inputLayout.bindingAt(i)->stride();
}
cbD->commands.append(cmd);
}
@@ -776,10 +840,10 @@ void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
- cmd.args.blendConstants.c[0] = c.redF();
- cmd.args.blendConstants.c[1] = c.greenF();
- cmd.args.blendConstants.c[2] = c.blueF();
- cmd.args.blendConstants.c[3] = c.alphaF();
+ cmd.args.blendConstants.c[0] = float(c.redF());
+ cmd.args.blendConstants.c[1] = float(c.greenF());
+ cmd.args.blendConstants.c[2] = float(c.blueF());
+ cmd.args.blendConstants.c[3] = float(c.alphaF());
cbD->commands.append(cmd);
}
@@ -977,8 +1041,14 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
if (!flags.testFlag(QRhi::SkipPresent)) {
const UINT presentFlags = 0;
HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags);
- if (FAILED(hr))
+ if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
+ qWarning("Device loss detected in Present()");
+ deviceLost = true;
+ return QRhi::FrameOpDeviceLost;
+ } else if (FAILED(hr)) {
qWarning("Failed to present: %s", qPrintable(comErrorMessage(hr)));
+ return QRhi::FrameOpError;
+ }
// move on to the next buffer
swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT;
@@ -988,6 +1058,20 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
swapChainD->frameCount += 1;
contextState.currentSwapChain = nullptr;
+
+ if (deviceCurse.framesToActivate > 0) {
+ deviceCurse.framesLeft -= 1;
+ if (deviceCurse.framesLeft == 0) {
+ deviceCurse.framesLeft = deviceCurse.framesToActivate;
+ if (!deviceCurse.permanent)
+ deviceCurse.framesToActivate = -1;
+
+ deviceCurse.activate();
+ } else if (deviceCurse.framesLeft % 100 == 0) {
+ qDebug("Impending doom: %d frames left", deviceCurse.framesLeft);
+ }
+ }
+
return QRhi::FrameOpSuccess;
}
@@ -1161,7 +1245,7 @@ QRhi::FrameOpResult QRhiD3D11::finish()
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
{
- UINT subres = D3D11CalcSubresource(level, layer, texD->mipLevelCount);
+ UINT subres = D3D11CalcSubresource(UINT(level), UINT(layer), texD->mipLevelCount);
const QPoint dp = subresDesc.destinationTopLeft();
D3D11_BOX box;
box.front = 0;
@@ -1192,13 +1276,13 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
} else {
cmd.args.updateSubRes.src = cbD->retainImage(img);
}
- box.left = dp.x();
- box.top = dp.y();
- box.right = dp.x() + size.width();
- box.bottom = dp.y() + size.height();
+ box.left = UINT(dp.x());
+ box.top = UINT(dp.y());
+ box.right = UINT(dp.x() + size.width());
+ box.bottom = UINT(dp.y() + size.height());
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
- cmd.args.updateSubRes.srcRowPitch = bpl;
+ cmd.args.updateSubRes.srcRowPitch = UINT(bpl);
} else if (!subresDesc.data().isEmpty() && isCompressedFormat(texD->m_format)) {
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
@@ -1208,10 +1292,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
// Everything must be a multiple of the block width and
// height, so e.g. a mip level of size 2x2 will be 4x4 when it
// comes to the actual data.
- box.left = aligned(dp.x(), blockDim.width());
- box.top = aligned(dp.y(), blockDim.height());
- box.right = aligned(dp.x() + size.width(), blockDim.width());
- box.bottom = aligned(dp.y() + size.height(), blockDim.height());
+ box.left = UINT(aligned(dp.x(), blockDim.width()));
+ box.top = UINT(aligned(dp.y(), blockDim.height()));
+ box.right = UINT(aligned(dp.x() + size.width(), blockDim.width()));
+ box.bottom = UINT(aligned(dp.y() + size.height(), blockDim.height()));
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
@@ -1220,12 +1304,11 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
quint32 bpl = 0;
- QSize blockDim;
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
- box.left = dp.x();
- box.top = dp.y();
- box.right = dp.x() + size.width();
- box.bottom = dp.y() + size.height();
+ box.left = UINT(dp.x());
+ box.top = UINT(dp.y());
+ box.right = UINT(dp.x() + size.width());
+ box.bottom = UINT(dp.y() + size.height());
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
@@ -1244,84 +1327,128 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
- QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
- Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
- memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), u.data.size());
- bufD->hasPendingDynamicUpdates = true;
- }
-
- for (const QRhiResourceUpdateBatchPrivate::StaticBufferUpload &u : ud->staticBufferUploads) {
- QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
- Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
- Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
- QD3D11CommandBuffer::Command cmd;
- cmd.cmd = QD3D11CommandBuffer::Command::UpdateSubRes;
- cmd.args.updateSubRes.dst = bufD->buffer;
- cmd.args.updateSubRes.dstSubRes = 0;
- cmd.args.updateSubRes.src = cbD->retainData(u.data);
- cmd.args.updateSubRes.srcRowPitch = 0;
- // Specify the region (even when offset is 0 and all data is provided)
- // since the ID3D11Buffer's size is rounded up to be a multiple of 256
- // while the data we have has the original size.
- D3D11_BOX box;
- box.left = u.offset;
- box.top = box.front = 0;
- box.back = box.bottom = 1;
- box.right = u.offset + u.data.size(); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
- cmd.args.updateSubRes.hasDstBox = true;
- cmd.args.updateSubRes.dstBox = box;
- cbD->commands.append(cmd);
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
+ QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
+ Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
+ memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
+ bufD->hasPendingDynamicUpdates = true;
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload) {
+ QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
+ Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
+ Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
+ QD3D11CommandBuffer::Command cmd;
+ cmd.cmd = QD3D11CommandBuffer::Command::UpdateSubRes;
+ cmd.args.updateSubRes.dst = bufD->buffer;
+ cmd.args.updateSubRes.dstSubRes = 0;
+ cmd.args.updateSubRes.src = cbD->retainData(u.data);
+ cmd.args.updateSubRes.srcRowPitch = 0;
+ // Specify the region (even when offset is 0 and all data is provided)
+ // since the ID3D11Buffer's size is rounded up to be a multiple of 256
+ // while the data we have has the original size.
+ D3D11_BOX box;
+ box.left = UINT(u.offset);
+ box.top = box.front = 0;
+ box.back = box.bottom = 1;
+ box.right = UINT(u.offset + u.data.size()); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
+ cmd.args.updateSubRes.hasDstBox = true;
+ cmd.args.updateSubRes.dstBox = box;
+ cbD->commands.append(cmd);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
+ QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
+ if (bufD->m_type == QRhiBuffer::Dynamic) {
+ u.result->data.resize(u.readSize);
+ memcpy(u.result->data.data(), bufD->dynBuf.constData() + u.offset, size_t(u.readSize));
+ } else {
+ BufferReadback readback;
+ readback.result = u.result;
+ readback.byteSize = u.readSize;
+
+ D3D11_BUFFER_DESC desc;
+ memset(&desc, 0, sizeof(desc));
+ desc.ByteWidth = readback.byteSize;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ HRESULT hr = dev->CreateBuffer(&desc, nullptr, &readback.stagingBuf);
+ if (FAILED(hr)) {
+ qWarning("Failed to create buffer: %s", qPrintable(comErrorMessage(hr)));
+ continue;
+ }
+ QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(readback.stagingBuf)), bufD, readback.byteSize));
+
+ QD3D11CommandBuffer::Command cmd;
+ cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
+ cmd.args.copySubRes.dst = readback.stagingBuf;
+ cmd.args.copySubRes.dstSubRes = 0;
+ cmd.args.copySubRes.dstX = 0;
+ cmd.args.copySubRes.dstY = 0;
+ cmd.args.copySubRes.src = bufD->buffer;
+ cmd.args.copySubRes.srcSubRes = 0;
+ cmd.args.copySubRes.hasSrcBox = true;
+ D3D11_BOX box;
+ box.left = UINT(u.offset);
+ box.top = box.front = 0;
+ box.back = box.bottom = 1;
+ box.right = UINT(u.offset + u.readSize);
+ cmd.args.copySubRes.srcBox = box;
+ cbD->commands.append(cmd);
+
+ activeBufferReadbacks.append(readback);
+ }
+ if (u.result->completed)
+ u.result->completed();
+ }
}
for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
- QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.upload.tex);
+ QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.dst);
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
- for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.upload.subresDesc[layer][level]))
+ for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
enqueueSubresUpload(texD, cbD, layer, level, subresDesc);
}
}
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Copy) {
- Q_ASSERT(u.copy.src && u.copy.dst);
- QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src);
- QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst);
- UINT srcSubRes = D3D11CalcSubresource(u.copy.desc.sourceLevel(), u.copy.desc.sourceLayer(), srcD->mipLevelCount);
- UINT dstSubRes = D3D11CalcSubresource(u.copy.desc.destinationLevel(), u.copy.desc.destinationLayer(), dstD->mipLevelCount);
- const QPoint dp = u.copy.desc.destinationTopLeft();
- const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
- const QPoint sp = u.copy.desc.sourceTopLeft();
+ Q_ASSERT(u.src && u.dst);
+ QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.src);
+ QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.dst);
+ UINT srcSubRes = D3D11CalcSubresource(UINT(u.desc.sourceLevel()), UINT(u.desc.sourceLayer()), srcD->mipLevelCount);
+ UINT dstSubRes = D3D11CalcSubresource(UINT(u.desc.destinationLevel()), UINT(u.desc.destinationLayer()), dstD->mipLevelCount);
+ const QPoint dp = u.desc.destinationTopLeft();
+ const QSize mipSize = q->sizeForMipLevel(u.desc.sourceLevel(), srcD->m_pixelSize);
+ const QSize copySize = u.desc.pixelSize().isEmpty() ? mipSize : u.desc.pixelSize();
+ const QPoint sp = u.desc.sourceTopLeft();
D3D11_BOX srcBox;
- srcBox.left = sp.x();
- srcBox.top = sp.y();
+ srcBox.left = UINT(sp.x());
+ srcBox.top = UINT(sp.y());
srcBox.front = 0;
// back, right, bottom are exclusive
- srcBox.right = srcBox.left + size.width();
- srcBox.bottom = srcBox.top + size.height();
+ srcBox.right = srcBox.left + UINT(copySize.width());
+ srcBox.bottom = srcBox.top + UINT(copySize.height());
srcBox.back = 1;
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
cmd.args.copySubRes.dst = dstD->tex;
cmd.args.copySubRes.dstSubRes = dstSubRes;
- cmd.args.copySubRes.dstX = dp.x();
- cmd.args.copySubRes.dstY = dp.y();
+ cmd.args.copySubRes.dstX = UINT(dp.x());
+ cmd.args.copySubRes.dstY = UINT(dp.y());
cmd.args.copySubRes.src = srcD->tex;
cmd.args.copySubRes.srcSubRes = srcSubRes;
cmd.args.copySubRes.hasSrcBox = true;
cmd.args.copySubRes.srcBox = srcBox;
cbD->commands.append(cmd);
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
- ActiveReadback aRb;
- aRb.desc = u.read.rb;
- aRb.result = u.read.result;
+ TextureReadback readback;
+ readback.desc = u.rb;
+ readback.result = u.result;
ID3D11Resource *src;
DXGI_FORMAT dxgiFormat;
QSize pixelSize;
QRhiTexture::Format format;
UINT subres = 0;
- QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.read.rb.texture());
+ QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.rb.texture());
QD3D11SwapChain *swapChainD = nullptr;
if (texD) {
@@ -1331,9 +1458,9 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
src = texD->tex;
dxgiFormat = texD->dxgiFormat;
- pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize;
+ pixelSize = q->sizeForMipLevel(u.rb.level(), texD->m_pixelSize);
format = texD->m_format;
- subres = D3D11CalcSubresource(u.read.rb.level(), u.read.rb.layer(), texD->mipLevelCount);
+ subres = D3D11CalcSubresource(UINT(u.rb.level()), UINT(u.rb.layer()), texD->mipLevelCount);
} else {
Q_ASSERT(contextState.currentSwapChain);
swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain);
@@ -1356,14 +1483,14 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
if (format == QRhiTexture::UnknownFormat)
continue;
}
- quint32 bufSize = 0;
+ quint32 byteSize = 0;
quint32 bpl = 0;
- textureFormatInfo(format, pixelSize, &bpl, &bufSize);
+ textureFormatInfo(format, pixelSize, &bpl, &byteSize);
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = pixelSize.width();
- desc.Height = pixelSize.height();
+ desc.Width = UINT(pixelSize.width());
+ desc.Height = UINT(pixelSize.height());
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = dxgiFormat;
@@ -1376,9 +1503,9 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr)));
return;
}
- QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(stagingTex)),
+ QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(stagingTex)),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
- bufSize));
+ byteSize));
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
@@ -1391,18 +1518,18 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copySubRes.hasSrcBox = false;
cbD->commands.append(cmd);
- aRb.stagingTex = stagingTex;
- aRb.bufSize = bufSize;
- aRb.bpl = bpl;
- aRb.pixelSize = pixelSize;
- aRb.format = format;
+ readback.stagingTex = stagingTex;
+ readback.byteSize = byteSize;
+ readback.bpl = bpl;
+ readback.pixelSize = pixelSize;
+ readback.format = format;
- activeReadbacks.append(aRb);
- } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::MipGen) {
- Q_ASSERT(u.mipgen.tex->flags().testFlag(QRhiTexture::UsedWithGenerateMips));
+ activeTextureReadbacks.append(readback);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
+ Q_ASSERT(u.dst->flags().testFlag(QRhiTexture::UsedWithGenerateMips));
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::GenMip;
- cmd.args.genMip.srv = QRHI_RES(QD3D11Texture, u.mipgen.tex)->srv;
+ cmd.args.genMip.srv = QRHI_RES(QD3D11Texture, u.dst)->srv;
cbD->commands.append(cmd);
}
}
@@ -1415,37 +1542,58 @@ void QRhiD3D11::finishActiveReadbacks()
QVarLengthArray<std::function<void()>, 4> completedCallbacks;
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (int i = activeReadbacks.count() - 1; i >= 0; --i) {
- const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]);
- aRb.result->format = aRb.format;
- aRb.result->pixelSize = aRb.pixelSize;
- aRb.result->data.resize(aRb.bufSize);
+ for (int i = activeTextureReadbacks.count() - 1; i >= 0; --i) {
+ const QRhiD3D11::TextureReadback &readback(activeTextureReadbacks[i]);
+ readback.result->format = readback.format;
+ readback.result->pixelSize = readback.pixelSize;
D3D11_MAPPED_SUBRESOURCE mp;
- HRESULT hr = context->Map(aRb.stagingTex, 0, D3D11_MAP_READ, 0, &mp);
- if (FAILED(hr)) {
+ HRESULT hr = context->Map(readback.stagingTex, 0, D3D11_MAP_READ, 0, &mp);
+ if (SUCCEEDED(hr)) {
+ readback.result->data.resize(int(readback.byteSize));
+ // nothing says the rows are tightly packed in the texture, must take
+ // the stride into account
+ char *dst = readback.result->data.data();
+ char *src = static_cast<char *>(mp.pData);
+ for (int y = 0, h = readback.pixelSize.height(); y != h; ++y) {
+ memcpy(dst, src, readback.bpl);
+ dst += readback.bpl;
+ src += mp.RowPitch;
+ }
+ context->Unmap(readback.stagingTex, 0);
+ } else {
qWarning("Failed to map readback staging texture: %s", qPrintable(comErrorMessage(hr)));
- aRb.stagingTex->Release();
- continue;
}
- // nothing says the rows are tightly packed in the texture, must take
- // the stride into account
- char *dst = aRb.result->data.data();
- char *src = static_cast<char *>(mp.pData);
- for (int y = 0, h = aRb.pixelSize.height(); y != h; ++y) {
- memcpy(dst, src, aRb.bpl);
- dst += aRb.bpl;
- src += mp.RowPitch;
+
+ readback.stagingTex->Release();
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(readback.stagingTex))));
+
+ if (readback.result->completed)
+ completedCallbacks.append(readback.result->completed);
+
+ activeTextureReadbacks.removeAt(i);
+ }
+
+ for (int i = activeBufferReadbacks.count() - 1; i >= 0; --i) {
+ const QRhiD3D11::BufferReadback &readback(activeBufferReadbacks[i]);
+
+ D3D11_MAPPED_SUBRESOURCE mp;
+ HRESULT hr = context->Map(readback.stagingBuf, 0, D3D11_MAP_READ, 0, &mp);
+ if (SUCCEEDED(hr)) {
+ readback.result->data.resize(int(readback.byteSize));
+ memcpy(readback.result->data.data(), mp.pData, readback.byteSize);
+ context->Unmap(readback.stagingBuf, 0);
+ } else {
+ qWarning("Failed to map readback staging texture: %s", qPrintable(comErrorMessage(hr)));
}
- context->Unmap(aRb.stagingTex, 0);
- aRb.stagingTex->Release();
- QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.stagingTex))));
+ readback.stagingBuf->Release();
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(readback.stagingBuf))));
- if (aRb.result->completed)
- completedCallbacks.append(aRb.result->completed);
+ if (readback.result->completed)
+ completedCallbacks.append(readback.result->completed);
- activeReadbacks.removeAt(i);
+ activeBufferReadbacks.removeAt(i);
}
for (auto f : completedCallbacks)
@@ -1509,10 +1657,10 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
- clearCmd.args.clear.c[0] = colorClearValue.redF();
- clearCmd.args.clear.c[1] = colorClearValue.greenF();
- clearCmd.args.clear.c[2] = colorClearValue.blueF();
- clearCmd.args.clear.c[3] = colorClearValue.alphaF();
+ clearCmd.args.clear.c[0] = float(colorClearValue.redF());
+ clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
+ clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
+ clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
cbD->commands.append(clearCmd);
@@ -1530,9 +1678,10 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (cbD->currentTarget->resourceType() == QRhiResource::TextureRenderTarget) {
QD3D11TextureRenderTarget *rtTex = QRHI_RES(QD3D11TextureRenderTarget, cbD->currentTarget);
- const QVector<QRhiColorAttachment> colorAttachments = rtTex->m_desc.colorAttachments();
- for (int att = 0, attCount = colorAttachments.count(); att != attCount; ++att) {
- const QRhiColorAttachment &colorAtt(colorAttachments[att]);
+ for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments();
+ it != itEnd; ++it)
+ {
+ const QRhiColorAttachment &colorAtt(*it);
if (!colorAtt.resolveTexture())
continue;
@@ -1543,8 +1692,8 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
cmd.args.resolveSubRes.dst = dstTexD->tex;
- cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(colorAtt.resolveLevel(),
- colorAtt.resolveLayer(),
+ cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
+ UINT(colorAtt.resolveLayer()),
dstTexD->mipLevelCount);
if (srcTexD) {
cmd.args.resolveSubRes.src = srcTexD->tex;
@@ -1571,7 +1720,7 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
continue;
}
}
- cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, colorAtt.layer(), 1);
+ cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, UINT(colorAtt.layer()), 1);
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
cbD->commands.append(cmd);
}
@@ -1638,9 +1787,9 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
- cmd.args.dispatch.x = x;
- cmd.args.dispatch.y = y;
- cmd.args.dispatch.z = z;
+ cmd.args.dispatch.x = UINT(x);
+ cmd.args.dispatch.y = UINT(y);
+ cmd.args.dispatch.z = UINT(z);
cbD->commands.append(cmd);
}
@@ -1670,7 +1819,7 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
srbD->csUAVs.clear();
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
@@ -1682,11 +1831,11 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
// dynamic ubuf offsets are not considered here, those are baked in
// at a later stage, which is good as vsubufoffsets and friends are
// per-srb, not per-setShaderResources call
- const uint offsetInConstants = b->u.ubuf.offset / 16;
+ const uint offsetInConstants = uint(b->u.ubuf.offset) / 16;
// size must be 16 mult. (in constants, i.e. multiple of 256 bytes).
// We can round up if needed since the buffers's actual size
// (ByteWidth) is always a multiple of 256.
- const uint sizeInConstants = aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16;
+ const uint sizeInConstants = uint(aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16);
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
srbD->vsubufs.feed(b->binding, bufD->buffer);
srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
@@ -1804,7 +1953,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
D3D11_MAPPED_SUBRESOURCE mp;
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
if (SUCCEEDED(hr)) {
- memcpy(mp.pData, bufD->dynBuf.constData(), bufD->dynBuf.size());
+ memcpy(mp.pData, bufD->dynBuf.constData(), size_t(bufD->dynBuf.size()));
context->Unmap(bufD->buffer, 0);
} else {
qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr)));
@@ -1817,13 +1966,13 @@ static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
QRhiBatchedBindings<UINT> *ubufoffsets,
const uint *dynOfsPairs, int dynOfsPairCount)
{
- const UINT count = ubufs->batches[batchIndex].resources.count();
+ const int count = ubufs->batches[batchIndex].resources.count();
const UINT startBinding = ubufs->batches[batchIndex].startBinding;
*offsets = ubufoffsets->batches[batchIndex].resources;
- for (UINT b = 0; b < count; ++b) {
+ for (int b = 0; b < count; ++b) {
for (int di = 0; di < dynOfsPairCount; ++di) {
const uint binding = dynOfsPairs[2 * di];
- if (binding == startBinding + b) {
+ if (binding == startBinding + UINT(b)) {
const uint offsetInConstants = dynOfsPairs[2 * di + 1];
(*offsets)[b] = offsetInConstants;
break;
@@ -1838,37 +1987,37 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
{
if (!offsetOnlyChange) {
for (const auto &batch : srbD->vssamplers.batches)
- context->VSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->VSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->vsshaderresources.batches) {
- context->VSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->VSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.vsHighestActiveSrvBinding = qMax<int>(contextState.vsHighestActiveSrvBinding,
- batch.startBinding + batch.resources.count() - 1);
+ int(batch.startBinding) + batch.resources.count() - 1);
}
for (const auto &batch : srbD->fssamplers.batches)
- context->PSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->PSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->fsshaderresources.batches) {
- context->PSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->PSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.fsHighestActiveSrvBinding = qMax<int>(contextState.fsHighestActiveSrvBinding,
- batch.startBinding + batch.resources.count() - 1);
+ int(batch.startBinding) + batch.resources.count() - 1);
}
for (const auto &batch : srbD->cssamplers.batches)
- context->CSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->CSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->csshaderresources.batches) {
- context->CSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->CSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.csHighestActiveSrvBinding = qMax<int>(contextState.csHighestActiveSrvBinding,
- batch.startBinding + batch.resources.count() - 1);
+ int(batch.startBinding) + batch.resources.count() - 1);
}
}
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) {
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
- srbD->vsubufs.batches[i].resources.count(),
+ UINT(srbD->vsubufs.batches[i].resources.count()),
srbD->vsubufs.batches[i].resources.constData(),
srbD->vsubufoffsets.batches[i].resources.constData(),
srbD->vsubufsizes.batches[i].resources.constData());
@@ -1876,7 +2025,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount);
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
- srbD->vsubufs.batches[i].resources.count(),
+ UINT(srbD->vsubufs.batches[i].resources.count()),
srbD->vsubufs.batches[i].resources.constData(),
offsets.constData(),
srbD->vsubufsizes.batches[i].resources.constData());
@@ -1886,7 +2035,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->fsubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) {
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
- srbD->fsubufs.batches[i].resources.count(),
+ UINT(srbD->fsubufs.batches[i].resources.count()),
srbD->fsubufs.batches[i].resources.constData(),
srbD->fsubufoffsets.batches[i].resources.constData(),
srbD->fsubufsizes.batches[i].resources.constData());
@@ -1894,7 +2043,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount);
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
- srbD->fsubufs.batches[i].resources.count(),
+ UINT(srbD->fsubufs.batches[i].resources.count()),
srbD->fsubufs.batches[i].resources.constData(),
offsets.constData(),
srbD->fsubufsizes.batches[i].resources.constData());
@@ -1904,7 +2053,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->csubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) {
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
- srbD->csubufs.batches[i].resources.count(),
+ UINT(srbD->csubufs.batches[i].resources.count()),
srbD->csubufs.batches[i].resources.constData(),
srbD->csubufoffsets.batches[i].resources.constData(),
srbD->csubufsizes.batches[i].resources.constData());
@@ -1912,7 +2061,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount);
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
- srbD->csubufs.batches[i].resources.count(),
+ UINT(srbD->csubufs.batches[i].resources.count()),
srbD->csubufs.batches[i].resources.constData(),
offsets.constData(),
srbD->csubufsizes.batches[i].resources.constData());
@@ -1921,13 +2070,13 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->csUAVs.batches.count(); i != ie; ++i) {
const uint startBinding = srbD->csUAVs.batches[i].startBinding;
- const uint count = srbD->csUAVs.batches[i].resources.count();
+ const uint count = uint(srbD->csUAVs.batches[i].resources.count());
context->CSSetUnorderedAccessViews(startBinding,
count,
srbD->csUAVs.batches[i].resources.constData(),
nullptr);
contextState.csHighestActiveUavBinding = qMax<int>(contextState.csHighestActiveUavBinding,
- startBinding + count - 1);
+ int(startBinding + count - 1));
}
}
@@ -1951,7 +2100,7 @@ void QRhiD3D11::resetShaderResources()
QVarLengthArray<UINT, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> nulloffsets(count);
for (int i = 0; i < count; ++i)
nulloffsets[i] = 0;
- context->IASetVertexBuffers(0, count, nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
+ context->IASetVertexBuffers(0, UINT(count), nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
contextState.vsHighestActiveVertexBufferBinding = -1;
}
@@ -1964,15 +2113,15 @@ void QRhiD3D11::resetShaderResources()
for (int i = 0; i < nullsrvs.count(); ++i)
nullsrvs[i] = nullptr;
if (contextState.vsHighestActiveSrvBinding >= 0) {
- context->VSSetShaderResources(0, contextState.vsHighestActiveSrvBinding + 1, nullsrvs.constData());
+ context->VSSetShaderResources(0, UINT(contextState.vsHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.vsHighestActiveSrvBinding = -1;
}
if (contextState.fsHighestActiveSrvBinding >= 0) {
- context->PSSetShaderResources(0, contextState.fsHighestActiveSrvBinding + 1, nullsrvs.constData());
+ context->PSSetShaderResources(0, UINT(contextState.fsHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.fsHighestActiveSrvBinding = -1;
}
if (contextState.csHighestActiveSrvBinding >= 0) {
- context->CSSetShaderResources(0, contextState.csHighestActiveSrvBinding + 1, nullsrvs.constData());
+ context->CSSetShaderResources(0, UINT(contextState.csHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.csHighestActiveSrvBinding = -1;
}
}
@@ -1983,7 +2132,7 @@ void QRhiD3D11::resetShaderResources()
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount);
for (int i = 0; i < nulluavCount; ++i)
nulluavs[i] = nullptr;
- context->CSSetUnorderedAccessViews(0, nulluavCount, nulluavs.constData(), nullptr);
+ context->CSSetUnorderedAccessViews(0, UINT(nulluavCount), nulluavs.constData(), nullptr);
contextState.csHighestActiveUavBinding = -1;
}
}
@@ -2005,7 +2154,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
// writing the first timestamp only afterwards.
context->Begin(tsDisjoint);
QD3D11RenderTargetData *rtD = rtData(&timestampSwapChain->rt);
- context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
+ context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
context->End(tsStart); // just record a timestamp, no Begin needed
}
}
@@ -2018,7 +2167,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
case QD3D11CommandBuffer::Command::SetRenderTarget:
{
QD3D11RenderTargetData *rtD = rtData(cmd.args.setRenderTarget.rt);
- context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
+ context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
}
break;
case QD3D11CommandBuffer::Command::Clear:
@@ -2034,7 +2183,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil)
ds |= D3D11_CLEAR_STENCIL;
if (ds)
- context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, cmd.args.clear.s);
+ context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, UINT8(cmd.args.clear.s));
}
break;
case QD3D11CommandBuffer::Command::Viewport:
@@ -2064,8 +2213,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
contextState.vsHighestActiveVertexBufferBinding = qMax<int>(
contextState.vsHighestActiveVertexBufferBinding,
cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1);
- context->IASetVertexBuffers(cmd.args.bindVertexBuffers.startSlot,
- cmd.args.bindVertexBuffers.slotCount,
+ context->IASetVertexBuffers(UINT(cmd.args.bindVertexBuffers.startSlot),
+ UINT(cmd.args.bindVertexBuffers.slotCount),
cmd.args.bindVertexBuffers.buffers,
cmd.args.bindVertexBuffers.strides,
cmd.args.bindVertexBuffers.offsets);
@@ -2208,7 +2357,7 @@ static inline uint toD3DBufferUsage(QRhiBuffer::UsageFlags usage)
u |= D3D11_BIND_CONSTANT_BUFFER;
if (usage.testFlag(QRhiBuffer::StorageBuffer))
u |= D3D11_BIND_UNORDERED_ACCESS;
- return u;
+ return uint(u);
}
bool QD3D11Buffer::build()
@@ -2231,7 +2380,7 @@ bool QD3D11Buffer::build()
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.ByteWidth = roundedSize;
+ desc.ByteWidth = UINT(roundedSize);
desc.Usage = m_type == Dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
desc.BindFlags = toD3DBufferUsage(m_usage);
desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
@@ -2250,10 +2399,10 @@ bool QD3D11Buffer::build()
}
if (!m_objectName.isEmpty())
- buffer->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
+ buffer->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF;
- QRHI_PROF_F(newBuffer(this, roundedSize, m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
+ QRHI_PROF_F(newBuffer(this, quint32(roundedSize), m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
generation += 1;
rhiD->registerResource(this);
@@ -2271,7 +2420,7 @@ ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
desc.Format = DXGI_FORMAT_R32_TYPELESS;
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
desc.Buffer.FirstElement = 0;
- desc.Buffer.NumElements = aligned(m_size, 4) / 4;
+ desc.Buffer.NumElements = UINT(aligned(m_size, 4) / 4);
desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
QRHI_RES_RHI(QRhiD3D11);
@@ -2332,8 +2481,8 @@ bool QD3D11RenderBuffer::build()
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = m_pixelSize.width();
- desc.Height = m_pixelSize.height();
+ desc.Width = UINT(m_pixelSize.width());
+ desc.Height = UINT(m_pixelSize.height());
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc = sampleDesc;
@@ -2382,10 +2531,10 @@ bool QD3D11RenderBuffer::build()
}
if (!m_objectName.isEmpty())
- tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF;
- QRHI_PROF_F(newRenderBuffer(this, false, false, sampleDesc.Count));
+ QRHI_PROF_F(newRenderBuffer(this, false, false, int(sampleDesc.Count)));
rhiD->registerResource(this);
return true;
@@ -2475,7 +2624,7 @@ bool QD3D11Texture::prepareBuild(QSize *adjustedSize)
QRHI_RES_RHI(QRhiD3D11);
dxgiFormat = toD3DTextureFormat(m_format, m_flags);
- mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
+ mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
if (sampleDesc.Count > 1) {
if (isCube) {
@@ -2561,8 +2710,8 @@ bool QD3D11Texture::build()
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = size.width();
- desc.Height = size.height();
+ desc.Width = UINT(size.width());
+ desc.Height = UINT(size.height());
desc.MipLevels = mipLevelCount;
desc.ArraySize = isCube ? 6 : 1;
desc.Format = dxgiFormat;
@@ -2582,10 +2731,10 @@ bool QD3D11Texture::build()
return false;
if (!m_objectName.isEmpty())
- tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, sampleDesc.Count));
+ QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, int(sampleDesc.Count)));
owns = true;
rhiD->registerResource(this);
@@ -2607,7 +2756,7 @@ bool QD3D11Texture::buildFrom(const QRhiNativeHandles *src)
return false;
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, sampleDesc.Count));
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, int(sampleDesc.Count)));
owns = false;
QRHI_RES_RHI(QRhiD3D11);
@@ -2631,12 +2780,12 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
desc.Format = dxgiFormat;
if (isCube) {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
- desc.Texture2DArray.MipSlice = level;
+ desc.Texture2DArray.MipSlice = UINT(level);
desc.Texture2DArray.FirstArraySlice = 0;
desc.Texture2DArray.ArraySize = 6;
} else {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
- desc.Texture2D.MipSlice = level;
+ desc.Texture2D.MipSlice = UINT(level);
}
QRHI_RES_RHI(QRhiD3D11);
@@ -2877,17 +3026,20 @@ bool QD3D11TextureRenderTarget::build()
if (rtv[0] || dsv)
release();
- const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
- Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture());
+ const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments();
+ Q_ASSERT(hasColorAttachments || m_desc.depthTexture());
Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture());
const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();
QRHI_RES_RHI(QRhiD3D11);
- d.colorAttCount = colorAttachments.count();
- for (int i = 0; i < d.colorAttCount; ++i) {
- QRhiTexture *texture = colorAttachments[i].texture();
- QRhiRenderBuffer *rb = colorAttachments[i].renderBuffer();
+ d.colorAttCount = 0;
+ int attIndex = 0;
+ for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
+ d.colorAttCount += 1;
+ const QRhiColorAttachment &colorAtt(*it);
+ QRhiTexture *texture = colorAtt.texture();
+ QRhiRenderBuffer *rb = colorAtt.renderBuffer();
Q_ASSERT(texture || rb);
if (texture) {
QD3D11Texture *texD = QRHI_RES(QD3D11Texture, texture);
@@ -2896,34 +3048,34 @@ bool QD3D11TextureRenderTarget::build()
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = colorAttachments[i].level();
- rtvDesc.Texture2DArray.FirstArraySlice = colorAttachments[i].layer();
+ rtvDesc.Texture2DArray.MipSlice = UINT(colorAtt.level());
+ rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAtt.layer());
rtvDesc.Texture2DArray.ArraySize = 1;
} else {
if (texD->sampleDesc.Count > 1) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
} else {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = colorAttachments[i].level();
+ rtvDesc.Texture2D.MipSlice = UINT(colorAtt.level());
}
}
- HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]);
+ HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[attIndex]);
if (FAILED(hr)) {
qWarning("Failed to create rtv: %s", qPrintable(comErrorMessage(hr)));
return false;
}
- ownsRtv[i] = true;
- if (i == 0) {
+ ownsRtv[attIndex] = true;
+ if (attIndex == 0) {
d.pixelSize = texD->pixelSize();
- d.sampleCount = texD->sampleDesc.Count;
+ d.sampleCount = int(texD->sampleDesc.Count);
}
} else if (rb) {
QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb);
- ownsRtv[i] = false;
- rtv[i] = rbD->rtv;
- if (i == 0) {
+ ownsRtv[attIndex] = false;
+ rtv[attIndex] = rbD->rtv;
+ if (attIndex == 0) {
d.pixelSize = rbD->pixelSize();
- d.sampleCount = rbD->sampleDesc.Count;
+ d.sampleCount = int(rbD->sampleDesc.Count);
}
}
}
@@ -2945,7 +3097,7 @@ bool QD3D11TextureRenderTarget::build()
}
if (d.colorAttCount == 0) {
d.pixelSize = depthTexD->pixelSize();
- d.sampleCount = depthTexD->sampleDesc.Count;
+ d.sampleCount = int(depthTexD->sampleDesc.Count);
}
} else {
ownsDsv = false;
@@ -2953,7 +3105,7 @@ bool QD3D11TextureRenderTarget::build()
dsv = depthRbD->dsv;
if (d.colorAttCount == 0) {
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
- d.sampleCount = depthRbD->sampleDesc.Count;
+ d.sampleCount = int(depthRbD->sampleDesc.Count);
}
}
d.dsAttCount = 1;
@@ -3006,11 +3158,11 @@ bool QD3D11ShaderResourceBindings::build()
if (!sortedBindings.isEmpty())
release();
- sortedBindings = m_bindings;
+ std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
std::sort(sortedBindings.begin(), sortedBindings.end(),
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
{
- return QRhiShaderResourceBindingPrivate::get(&a)->binding < QRhiShaderResourceBindingPrivate::get(&b)->binding;
+ return a.data()->binding < b.data()->binding;
});
boundResourceData.resize(sortedBindings.count());
@@ -3177,9 +3329,9 @@ static inline D3D11_PRIMITIVE_TOPOLOGY toD3DTopology(QRhiGraphicsPipeline::Topol
}
}
-static inline uint toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
+static inline UINT8 toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
{
- uint f = 0;
+ UINT8 f = 0;
if (c.testFlag(QRhiGraphicsPipeline::R))
f |= D3D11_COLOR_WRITE_ENABLE_RED;
if (c.testFlag(QRhiGraphicsPipeline::G))
@@ -3314,22 +3466,22 @@ static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Varian
ID3DBlob *bytecode = nullptr;
ID3DBlob *errors = nullptr;
- HRESULT hr = d3dCompile(hlslSource.shader().constData(), hlslSource.shader().size(),
+ HRESULT hr = d3dCompile(hlslSource.shader().constData(), SIZE_T(hlslSource.shader().size()),
nullptr, nullptr, nullptr,
hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors);
if (FAILED(hr) || !bytecode) {
qWarning("HLSL shader compilation failed: 0x%x", uint(hr));
if (errors) {
*error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()),
- errors->GetBufferSize());
+ int(errors->GetBufferSize()));
errors->Release();
}
return QByteArray();
}
QByteArray result;
- result.resize(bytecode->GetBufferSize());
- memcpy(result.data(), bytecode->GetBufferPointer(), result.size());
+ result.resize(int(bytecode->GetBufferSize()));
+ memcpy(result.data(), bytecode->GetBufferPointer(), size_t(result.size()));
bytecode->Release();
return result;
}
@@ -3340,6 +3492,8 @@ bool QD3D11GraphicsPipeline::build()
release();
QRHI_RES_RHI(QRhiD3D11);
+ if (!rhiD->sanityCheckGraphicsPipeline(this))
+ return false;
D3D11_RASTERIZER_DESC rastDesc;
memset(&rastDesc, 0, sizeof(rastDesc));
@@ -3361,8 +3515,8 @@ bool QD3D11GraphicsPipeline::build()
dsDesc.DepthFunc = toD3DCompareOp(m_depthOp);
dsDesc.StencilEnable = m_stencilTest;
if (m_stencilTest) {
- dsDesc.StencilReadMask = m_stencilReadMask;
- dsDesc.StencilWriteMask = m_stencilWriteMask;
+ dsDesc.StencilReadMask = UINT8(m_stencilReadMask);
+ dsDesc.StencilWriteMask = UINT8(m_stencilWriteMask);
dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp);
dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp);
dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp);
@@ -3409,58 +3563,86 @@ bool QD3D11GraphicsPipeline::build()
QByteArray vsByteCode;
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
- QString error;
- QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
- if (bytecode.isEmpty()) {
- qWarning("HLSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- switch (shaderStage.type()) {
- case QRhiShaderStage::Vertex:
- hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
- if (FAILED(hr)) {
- qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ auto cacheIt = rhiD->m_shaderCache.constFind(shaderStage);
+ if (cacheIt != rhiD->m_shaderCache.constEnd()) {
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ vs = static_cast<ID3D11VertexShader *>(cacheIt->s);
+ vs->AddRef();
+ vsByteCode = cacheIt->bytecode;
+ break;
+ case QRhiShaderStage::Fragment:
+ fs = static_cast<ID3D11PixelShader *>(cacheIt->s);
+ fs->AddRef();
+ break;
+ default:
+ break;
}
- vsByteCode = bytecode;
- break;
- case QRhiShaderStage::Fragment:
- hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
- if (FAILED(hr)) {
- qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
+ } else {
+ QString error;
+ const QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
+ if (bytecode.isEmpty()) {
+ qWarning("HLSL shader compilation failed: %s", qPrintable(error));
return false;
}
- break;
- default:
- break;
+
+ if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ rhiD->clearShaderCache();
+ }
+
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ hr = rhiD->dev->CreateVertexShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &vs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ vsByteCode = bytecode;
+ rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(vs, bytecode));
+ vs->AddRef();
+ break;
+ case QRhiShaderStage::Fragment:
+ hr = rhiD->dev->CreatePixelShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &fs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(fs, bytecode));
+ fs->AddRef();
+ break;
+ default:
+ break;
+ }
}
}
d3dTopology = toD3DTopology(m_topology);
if (!vsByteCode.isEmpty()) {
- const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
- const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
QVarLengthArray<D3D11_INPUT_ELEMENT_DESC, 4> inputDescs;
- for (const QRhiVertexInputAttribute &attribute : attributes) {
+ for (auto it = m_vertexInputLayout.cbeginAttributes(), itEnd = m_vertexInputLayout.cendAttributes();
+ it != itEnd; ++it)
+ {
D3D11_INPUT_ELEMENT_DESC desc;
memset(&desc, 0, sizeof(desc));
// the output from SPIRV-Cross uses TEXCOORD<location> as the semantic
desc.SemanticName = "TEXCOORD";
- desc.SemanticIndex = attribute.location();
- desc.Format = toD3DAttributeFormat(attribute.format());
- desc.InputSlot = attribute.binding();
- desc.AlignedByteOffset = attribute.offset();
- const QRhiVertexInputBinding &binding(bindings[attribute.binding()]);
- if (binding.classification() == QRhiVertexInputBinding::PerInstance) {
+ desc.SemanticIndex = UINT(it->location());
+ desc.Format = toD3DAttributeFormat(it->format());
+ desc.InputSlot = UINT(it->binding());
+ desc.AlignedByteOffset = it->offset();
+ const QRhiVertexInputBinding *inputBinding = m_vertexInputLayout.bindingAt(it->binding());
+ if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance) {
desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
- desc.InstanceDataStepRate = binding.instanceStepRate();
+ desc.InstanceDataStepRate = UINT(inputBinding->instanceStepRate());
} else {
desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
}
inputDescs.append(desc);
}
- hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), inputDescs.count(), vsByteCode, vsByteCode.size(), &inputLayout);
+ hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), UINT(inputDescs.count()),
+ vsByteCode, SIZE_T(vsByteCode.size()), &inputLayout);
if (FAILED(hr)) {
qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr)));
return false;
@@ -3502,19 +3684,31 @@ bool QD3D11ComputePipeline::build()
QRHI_RES_RHI(QRhiD3D11);
- QString error;
- QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
- if (bytecode.isEmpty()) {
- qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
- return false;
- }
+ auto cacheIt = rhiD->m_shaderCache.constFind(m_shaderStage);
+ if (cacheIt != rhiD->m_shaderCache.constEnd()) {
+ cs = static_cast<ID3D11ComputeShader *>(cacheIt->s);
+ } else {
+ QString error;
+ const QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
+ if (bytecode.isEmpty()) {
+ qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
- HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
- if (FAILED(hr)) {
- qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &cs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+
+ if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES)
+ rhiD->clearShaderCache();
+
+ rhiD->m_shaderCache.insert(m_shaderStage, QRhiD3D11::Shader(cs, bytecode));
}
+ cs->AddRef();
+
generation += 1;
rhiD->registerResource(this);
return true;
@@ -3637,8 +3831,8 @@ bool QD3D11SwapChain::newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI
{
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = size.width();
- desc.Height = size.height();
+ desc.Width = UINT(size.width());
+ desc.Height = UINT(size.height());
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = format;
@@ -3694,11 +3888,23 @@ bool QD3D11SwapChain::buildOrResize()
const UINT swapChainFlags = 0;
QRHI_RES_RHI(QRhiD3D11);
- const bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
+ bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
if (!swapChain) {
HWND hwnd = reinterpret_cast<HWND>(window->winId());
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
+ // Take a shortcut for alpha: our QWindow is OpenGLSurface so whatever
+ // the platform plugin does to enable transparency for OpenGL window
+ // will be sufficient for us too on the legacy (DISCARD) path. For
+ // FLIP_DISCARD we'd need to use DirectComposition (create a
+ // IDCompositionDevice/Target/Visual), avoid that for now.
+ if (m_flags.testFlag(SurfaceHasPreMulAlpha) || m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
+ useFlipDiscard = false;
+ if (window->requestedFormat().alphaBufferSize() <= 0)
+ qWarning("Swapchain says surface has alpha but the window has no alphaBufferSize set. "
+ "This may lead to problems.");
+ }
+
HRESULT hr;
if (useFlipDiscard) {
// We use FLIP_DISCARD which implies a buffer count of 2 (as opposed to the
@@ -3709,18 +3915,17 @@ bool QD3D11SwapChain::buildOrResize()
DXGI_SWAP_CHAIN_DESC1 desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = pixelSize.width();
- desc.Height = pixelSize.height();
+ desc.Width = UINT(pixelSize.width());
+ desc.Height = UINT(pixelSize.height());
desc.Format = colorFormat;
desc.SampleDesc.Count = 1;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = BUFFER_COUNT;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
- if (m_flags.testFlag(SurfaceHasPreMulAlpha))
- desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
- else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha))
- desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
+ // Do not bother with AlphaMode, if won't work unless we go through
+ // DirectComposition. Instead, we just take the other (DISCARD)
+ // path for now when alpha is requested.
desc.Flags = swapChainFlags;
IDXGISwapChain1 *sc1;
@@ -3735,8 +3940,8 @@ bool QD3D11SwapChain::buildOrResize()
DXGI_SWAP_CHAIN_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.BufferDesc.Width = pixelSize.width();
- desc.BufferDesc.Height = pixelSize.height();
+ desc.BufferDesc.Width = UINT(pixelSize.width());
+ desc.BufferDesc.Height = UINT(pixelSize.height());
desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1;
desc.BufferDesc.Format = colorFormat;
@@ -3758,9 +3963,13 @@ bool QD3D11SwapChain::buildOrResize()
} else {
releaseBuffers();
const UINT count = useFlipDiscard ? BUFFER_COUNT : 1;
- HRESULT hr = swapChain->ResizeBuffers(count, pixelSize.width(), pixelSize.height(),
+ HRESULT hr = swapChain->ResizeBuffers(count, UINT(pixelSize.width()), UINT(pixelSize.height()),
colorFormat, swapChainFlags);
- if (FAILED(hr)) {
+ if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
+ qWarning("Device loss detected in ResizeBuffers()");
+ rhiD->deviceLost = true;
+ return false;
+ } else if (FAILED(hr)) {
qWarning("Failed to resize D3D11 swapchain: %s", qPrintable(comErrorMessage(hr)));
return false;
}
@@ -3808,9 +4017,16 @@ bool QD3D11SwapChain::buildOrResize()
m_depthStencil->sampleCount(), m_sampleCount);
}
if (m_depthStencil && m_depthStencil->pixelSize() != pixelSize) {
- qWarning("Depth-stencil buffer's size (%dx%d) does not match the surface size (%dx%d). Expect problems.",
- m_depthStencil->pixelSize().width(), m_depthStencil->pixelSize().height(),
- pixelSize.width(), pixelSize.height());
+ if (m_depthStencil->flags().testFlag(QRhiRenderBuffer::UsedWithSwapChainOnly)) {
+ m_depthStencil->setPixelSize(pixelSize);
+ if (!m_depthStencil->build())
+ qWarning("Failed to rebuild swapchain's associated depth-stencil buffer for size %dx%d",
+ pixelSize.width(), pixelSize.height());
+ } else {
+ qWarning("Depth-stencil buffer's size (%dx%d) does not match the surface size (%dx%d). Expect problems.",
+ m_depthStencil->pixelSize().width(), m_depthStencil->pixelSize().height(),
+ pixelSize.width(), pixelSize.height());
+ }
}
currentFrameSlot = 0;
@@ -3821,13 +4037,13 @@ bool QD3D11SwapChain::buildOrResize()
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc);
rtD->d.pixelSize = pixelSize;
- rtD->d.dpr = window->devicePixelRatio();
- rtD->d.sampleCount = sampleDesc.Count;
+ rtD->d.dpr = float(window->devicePixelRatio());
+ rtD->d.sampleCount = int(sampleDesc.Count);
rtD->d.colorAttCount = 1;
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
QRHI_PROF;
- QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, sampleDesc.Count));
+ QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, int(sampleDesc.Count)));
if (rhiP) {
D3D11_QUERY_DESC queryDesc;
memset(&queryDesc, 0, sizeof(queryDesc));
@@ -3861,4 +4077,34 @@ bool QD3D11SwapChain::buildOrResize()
return true;
}
+void QRhiD3D11::DeviceCurse::initResources()
+{
+ framesLeft = framesToActivate;
+
+ HRESULT hr = q->dev->CreateComputeShader(g_killDeviceByTimingOut, sizeof(g_killDeviceByTimingOut), nullptr, &cs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
+ return;
+ }
+}
+
+void QRhiD3D11::DeviceCurse::releaseResources()
+{
+ if (cs) {
+ cs->Release();
+ cs = nullptr;
+ }
+}
+
+void QRhiD3D11::DeviceCurse::activate()
+{
+ if (!cs)
+ return;
+
+ qDebug("Activating Curse. Goodbye Cruel World.");
+
+ q->context->CSSetShader(cs, nullptr, 0);
+ q->context->Dispatch(256, 1, 1);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/rhi/qrhid3d11_p.h b/src/gui/rhi/qrhid3d11_p.h
index 3e2e492d9c..5df1843b1e 100644
--- a/src/gui/rhi/qrhid3d11_p.h
+++ b/src/gui/rhi/qrhid3d11_p.h
@@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams
{
bool enableDebugLayer = false;
+
+ int framesUntilKillingDeviceViaTdr = -1;
+ bool repeatDeviceKill = false;
};
struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 582146315d..26de34ae0a 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -199,7 +199,7 @@ struct QD3D11ShaderResourceBindings : public QRhiShaderResourceBindings
void release() override;
bool build() override;
- QVector<QRhiShaderResourceBinding> sortedBindings;
+ QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
uint generation = 0;
// Keep track of the generation number of each referenced QRhi* to be able
@@ -230,7 +230,7 @@ struct QD3D11ShaderResourceBindings : public QRhiShaderResourceBindings
BoundStorageBufferData sbuf;
};
};
- QVector<BoundResourceData> boundResourceData;
+ QVarLengthArray<BoundResourceData, 8> boundResourceData;
QRhiBatchedBindings<ID3D11Buffer *> vsubufs;
QRhiBatchedBindings<UINT> vsubufoffsets;
@@ -631,7 +631,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
@@ -646,6 +648,7 @@ public:
DXGI_SAMPLE_DESC effectiveSampleCount(int sampleCount) const;
void finishActiveReadbacks();
void reportLiveObjects(ID3D11Device *device);
+ void clearShaderCache();
bool debugLayer = false;
bool importedDevice = false;
@@ -656,6 +659,7 @@ public:
IDXGIFactory1 *dxgiFactory = nullptr;
bool hasDxgi2 = false;
bool supportsFlipDiscardSwapchain = false;
+ bool deviceLost = false;
QRhiD3D11NativeHandles nativeHandlesStruct;
struct {
@@ -674,19 +678,47 @@ public:
QD3D11CommandBuffer cbWrapper;
} ofr;
- struct ActiveReadback {
+ struct TextureReadback {
QRhiReadbackDescription desc;
QRhiReadbackResult *result;
ID3D11Texture2D *stagingTex;
- quint32 bufSize;
+ quint32 byteSize;
quint32 bpl;
QSize pixelSize;
QRhiTexture::Format format;
};
- QVector<ActiveReadback> activeReadbacks;
+ QVector<TextureReadback> activeTextureReadbacks;
+ struct BufferReadback {
+ QRhiBufferReadbackResult *result;
+ quint32 byteSize;
+ ID3D11Buffer *stagingBuf;
+ };
+ QVector<BufferReadback> activeBufferReadbacks;
+
+ struct Shader {
+ Shader() = default;
+ Shader(IUnknown *s, const QByteArray &bytecode) : s(s), bytecode(bytecode) { }
+ IUnknown *s;
+ QByteArray bytecode;
+ };
+ QHash<QRhiShaderStage, Shader> m_shaderCache;
+
+ struct DeviceCurse {
+ DeviceCurse(QRhiD3D11 *impl) : q(impl) { }
+ QRhiD3D11 *q;
+ int framesToActivate = -1;
+ bool permanent = false;
+ int framesLeft = 0;
+ ID3D11ComputeShader *cs = nullptr;
+
+ void initResources();
+ void releaseResources();
+ void activate();
+ } deviceCurse;
};
-Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QRhiD3D11::TextureReadback, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QRhiD3D11::BufferReadback, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index f4e711e33e..e355979626 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -39,6 +39,7 @@
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QtGui/private/qopenglextensions_p.h>
+#include <QtGui/private/qopenglprogrambinarycache_p.h>
#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -275,6 +276,12 @@ QT_BEGIN_NAMESPACE
#define GL_POINT_SPRITE 0x8861
#endif
+#ifndef GL_MAP_READ_BIT
+#define GL_MAP_READ_BIT 0x0001
+#endif
+
+Q_DECLARE_LOGGING_CATEGORY(lcOpenGLProgramDiskCache)
+
/*!
Constructs a new QRhiGles2InitParams.
@@ -371,7 +378,12 @@ bool QRhiGles2::ensureContext(QSurface *surface) const
return true;
if (!ctx->makeCurrent(surface)) {
- qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
+ if (ctx->isValid()) {
+ qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
+ } else {
+ qWarning("QRhiGles2: Context is lost.");
+ contextLost = true;
+ }
return false;
}
@@ -484,6 +496,15 @@ bool QRhiGles2::create(QRhi::Flags flags)
else
caps.textureCompareMode = true;
+ // proper as in ES 3.0 (glMapBufferRange), not the old glMapBuffer
+ // extension(s) (which is not in ES 3.0...messy)
+ caps.properMapBuffer = f->hasOpenGLExtension(QOpenGLExtensions::MapBufferRange);
+
+ if (caps.gles)
+ caps.nonBaseLevelFramebufferTexture = caps.ctxMajor >= 3; // ES 3.0
+ else
+ caps.nonBaseLevelFramebufferTexture = true;
+
if (!caps.gles) {
f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
f->glEnable(GL_POINT_SPRITE);
@@ -491,6 +512,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
nativeHandlesStruct.context = ctx;
+ contextLost = false;
+
return true;
}
@@ -502,6 +525,10 @@ void QRhiGles2::destroy()
ensureContext();
executeDeferredReleases();
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader);
+ m_shaderCache.clear();
+
if (!importedContext) {
delete ctx;
ctx = nullptr;
@@ -572,7 +599,9 @@ QRhiBuffer *QRhiGles2::createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlag
int QRhiGles2::ubufAlignment() const
{
- return 256;
+ // No real uniform buffers are used so no need to pretend there is any
+ // alignment requirement.
+ return 1;
}
bool QRhiGles2::isYUpInFramebuffer() const
@@ -650,7 +679,7 @@ static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRh
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
if (isCompressedFormat(format))
- return supportedCompressedFormats.contains(toGlCompressedTextureFormat(format, flags));
+ return supportedCompressedFormats.contains(GLint(toGlCompressedTextureFormat(format, flags)));
switch (format) {
case QRhiTexture::D16:
@@ -716,6 +745,12 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return caps.baseVertex;
case QRhi::BaseInstance:
return false; // not in ES 3.2, so won't bother
+ case QRhi::TriangleFanTopology:
+ return true;
+ case QRhi::ReadBackNonUniformBuffer:
+ return !caps.gles || caps.properMapBuffer;
+ case QRhi::ReadBackNonBaseMipLevel:
+ return caps.nonBaseLevelFramebufferTexture;
default:
Q_UNREACHABLE();
return false;
@@ -749,12 +784,28 @@ void QRhiGles2::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiGles2::makeThreadLocalNativeContextCurrent()
+bool QRhiGles2::makeThreadLocalNativeContextCurrent()
{
if (inFrame && !ofr.active)
- ensureContext(currentSwapChain->surface);
+ return ensureContext(currentSwapChain->surface);
else
- ensureContext();
+ return ensureContext();
+}
+
+void QRhiGles2::releaseCachedResources()
+{
+ if (!ensureContext())
+ return;
+
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader);
+
+ m_shaderCache.clear();
+}
+
+bool QRhiGles2::isDeviceLost() const
+{
+ return contextLost;
}
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -836,7 +887,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
bool hasDynamicOffsetInSrb = false;
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->m_bindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
// no BufUniformRead / AccessUniform because no real uniform buffers are used
@@ -915,7 +966,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
- *p++ = dynOfs.first;
+ *p++ = uint(dynOfs.first);
*p++ = dynOfs.second;
}
} else {
@@ -977,8 +1028,12 @@ void QRhiGles2::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Viewport;
const std::array<float, 4> r = viewport.viewport();
- cmd.args.viewport.x = qMax(0.0f, r[0]);
- cmd.args.viewport.y = qMax(0.0f, r[1]);
+ // A negative width or height is an error. A negative x or y is not.
+ if (r[2] < 0.0f || r[3] < 0.0f)
+ return;
+
+ cmd.args.viewport.x = r[0];
+ cmd.args.viewport.y = r[1];
cmd.args.viewport.w = r[2];
cmd.args.viewport.h = r[3];
cmd.args.viewport.d0 = viewport.minDepth();
@@ -994,8 +1049,12 @@ void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Scissor;
const std::array<int, 4> r = scissor.scissor();
- cmd.args.scissor.x = qMax(0, r[0]);
- cmd.args.scissor.y = qMax(0, r[1]);
+ // A negative width or height is an error. A negative x or y is not.
+ if (r[2] < 0 || r[3] < 0)
+ return;
+
+ cmd.args.scissor.x = r[0];
+ cmd.args.scissor.y = r[1];
cmd.args.scissor.w = r[2];
cmd.args.scissor.h = r[3];
cbD->commands.append(cmd);
@@ -1008,10 +1067,10 @@ void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
- cmd.args.blendConstants.r = c.redF();
- cmd.args.blendConstants.g = c.greenF();
- cmd.args.blendConstants.b = c.blueF();
- cmd.args.blendConstants.a = c.alphaF();
+ cmd.args.blendConstants.r = float(c.redF());
+ cmd.args.blendConstants.g = float(c.greenF());
+ cmd.args.blendConstants.b = float(c.blueF());
+ cmd.args.blendConstants.a = float(c.alphaF());
cbD->commands.append(cmd);
}
@@ -1141,7 +1200,7 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
if (!ensureContext(swapChainD->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
currentSwapChain = swapChainD;
@@ -1164,7 +1223,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext(swapChainD->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&swapChainD->cb);
@@ -1188,7 +1247,7 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi:
{
Q_UNUSED(flags);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
ofr.active = true;
@@ -1210,7 +1269,7 @@ QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper);
@@ -1224,14 +1283,14 @@ QRhi::FrameOpResult QRhiGles2::finish()
Q_ASSERT(!currentSwapChain);
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper);
ofr.cbWrapper.resetCommands();
} else {
Q_ASSERT(currentSwapChain);
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext(currentSwapChain->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&currentSwapChain->cb);
currentSwapChain->cb.resetCommands();
}
@@ -1299,7 +1358,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
}
cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture;
- cmd.args.subImage.faceTarget = faceTargetBase + layer;
+ cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.subImage.level = level;
cmd.args.subImage.dx = dp.x();
cmd.args.subImage.dy = dp.y();
@@ -1318,7 +1377,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
cmd.args.compressedSubImage.target = texD->target;
cmd.args.compressedSubImage.texture = texD->texture;
- cmd.args.compressedSubImage.faceTarget = faceTargetBase + layer;
+ cmd.args.compressedSubImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.compressedSubImage.level = level;
cmd.args.compressedSubImage.dx = dp.x();
cmd.args.compressedSubImage.dy = dp.y();
@@ -1333,7 +1392,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
cmd.args.compressedImage.target = texD->target;
cmd.args.compressedImage.texture = texD->texture;
- cmd.args.compressedImage.faceTarget = faceTargetBase + layer;
+ cmd.args.compressedImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.compressedImage.level = level;
cmd.args.compressedImage.glintformat = texD->glintformat;
cmd.args.compressedImage.w = size.width();
@@ -1351,7 +1410,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture;
- cmd.args.subImage.faceTarget = faceTargetBase + layer;
+ cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.subImage.level = level;
cmd.args.subImage.dx = dp.x();
cmd.args.subImage.dy = dp.y();
@@ -1375,65 +1434,83 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
- for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
- QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
- Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
- if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
- memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size());
- } else {
- trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
- QGles2CommandBuffer::Command cmd;
- cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
- cmd.args.bufferSubData.target = bufD->targetForDataOps;
- cmd.args.bufferSubData.buffer = bufD->buffer;
- cmd.args.bufferSubData.offset = u.offset;
- cmd.args.bufferSubData.size = u.data.size();
- cmd.args.bufferSubData.data = cbD->retainData(u.data);
- cbD->commands.append(cmd);
- }
- }
-
- for (const QRhiResourceUpdateBatchPrivate::StaticBufferUpload &u : ud->staticBufferUploads) {
- QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
- Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
- Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
- if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
- memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size());
- } else {
- trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
- QGles2CommandBuffer::Command cmd;
- cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
- cmd.args.bufferSubData.target = bufD->targetForDataOps;
- cmd.args.bufferSubData.buffer = bufD->buffer;
- cmd.args.bufferSubData.offset = u.offset;
- cmd.args.bufferSubData.size = u.data.size();
- cmd.args.bufferSubData.data = cbD->retainData(u.data);
- cbD->commands.append(cmd);
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
+ QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
+ Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
+ if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
+ memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
+ } else {
+ trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
+ QGles2CommandBuffer::Command cmd;
+ cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
+ cmd.args.bufferSubData.target = bufD->targetForDataOps;
+ cmd.args.bufferSubData.buffer = bufD->buffer;
+ cmd.args.bufferSubData.offset = u.offset;
+ cmd.args.bufferSubData.size = u.data.size();
+ cmd.args.bufferSubData.data = cbD->retainData(u.data);
+ cbD->commands.append(cmd);
+ }
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload) {
+ QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
+ Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
+ Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
+ if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
+ memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
+ } else {
+ trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
+ QGles2CommandBuffer::Command cmd;
+ cmd.cmd = QGles2CommandBuffer::Command::BufferSubData;
+ cmd.args.bufferSubData.target = bufD->targetForDataOps;
+ cmd.args.bufferSubData.buffer = bufD->buffer;
+ cmd.args.bufferSubData.offset = u.offset;
+ cmd.args.bufferSubData.size = u.data.size();
+ cmd.args.bufferSubData.data = cbD->retainData(u.data);
+ cbD->commands.append(cmd);
+ }
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
+ QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
+ if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
+ u.result->data.resize(u.readSize);
+ memcpy(u.result->data.data(), bufD->ubuf.constData() + u.offset, size_t(u.readSize));
+ if (u.result->completed)
+ u.result->completed();
+ } else {
+ QGles2CommandBuffer::Command cmd;
+ cmd.cmd = QGles2CommandBuffer::Command::GetBufferSubData;
+ cmd.args.getBufferSubData.result = u.result;
+ cmd.args.getBufferSubData.target = bufD->targetForDataOps;
+ cmd.args.getBufferSubData.buffer = bufD->buffer;
+ cmd.args.getBufferSubData.offset = u.offset;
+ cmd.args.getBufferSubData.size = u.readSize;
+ cbD->commands.append(cmd);
+ }
}
}
for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
- QGles2Texture *texD = QRHI_RES(QGles2Texture, u.upload.tex);
+ QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst);
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
- for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.upload.subresDesc[layer][level]))
+ for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
enqueueSubresUpload(texD, cbD, layer, level, subresDesc);
}
}
texD->specified = true;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Copy) {
- Q_ASSERT(u.copy.src && u.copy.dst);
- QGles2Texture *srcD = QRHI_RES(QGles2Texture, u.copy.src);
- QGles2Texture *dstD = QRHI_RES(QGles2Texture, u.copy.dst);
+ Q_ASSERT(u.src && u.dst);
+ QGles2Texture *srcD = QRHI_RES(QGles2Texture, u.src);
+ QGles2Texture *dstD = QRHI_RES(QGles2Texture, u.dst);
trackedImageBarrier(cbD, srcD, QGles2Texture::AccessRead);
trackedImageBarrier(cbD, dstD, QGles2Texture::AccessUpdate);
- const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
+ const QSize mipSize = q->sizeForMipLevel(u.desc.sourceLevel(), srcD->m_pixelSize);
+ const QSize copySize = u.desc.pixelSize().isEmpty() ? mipSize : u.desc.pixelSize();
// do not translate coordinates, even if sp is bottom-left from gl's pov
- const QPoint sp = u.copy.desc.sourceTopLeft();
- const QPoint dp = u.copy.desc.destinationTopLeft();
+ const QPoint sp = u.desc.sourceTopLeft();
+ const QPoint dp = u.desc.destinationTopLeft();
const GLenum srcFaceTargetBase = srcD->m_flags.testFlag(QRhiTexture::CubeMap)
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : srcD->target;
@@ -1443,42 +1520,44 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::CopyTex;
- cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + u.copy.desc.sourceLayer();
+ cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + uint(u.desc.sourceLayer());
cmd.args.copyTex.srcTexture = srcD->texture;
- cmd.args.copyTex.srcLevel = u.copy.desc.sourceLevel();
+ cmd.args.copyTex.srcLevel = u.desc.sourceLevel();
cmd.args.copyTex.srcX = sp.x();
cmd.args.copyTex.srcY = sp.y();
cmd.args.copyTex.dstTarget = dstD->target;
cmd.args.copyTex.dstTexture = dstD->texture;
- cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + u.copy.desc.destinationLayer();
- cmd.args.copyTex.dstLevel = u.copy.desc.destinationLevel();
+ cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + uint(u.desc.destinationLayer());
+ cmd.args.copyTex.dstLevel = u.desc.destinationLevel();
cmd.args.copyTex.dstX = dp.x();
cmd.args.copyTex.dstY = dp.y();
- cmd.args.copyTex.w = size.width();
- cmd.args.copyTex.h = size.height();
+ cmd.args.copyTex.w = copySize.width();
+ cmd.args.copyTex.h = copySize.height();
cbD->commands.append(cmd);
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
- cmd.args.readPixels.result = u.read.result;
- QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture());
- trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
+ cmd.args.readPixels.result = u.result;
+ QGles2Texture *texD = QRHI_RES(QGles2Texture, u.rb.texture());
+ if (texD)
+ trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
cmd.args.readPixels.texture = texD ? texD->texture : 0;
if (texD) {
- cmd.args.readPixels.w = texD->m_pixelSize.width();
- cmd.args.readPixels.h = texD->m_pixelSize.height();
+ const QSize readImageSize = q->sizeForMipLevel(u.rb.level(), texD->m_pixelSize);
+ cmd.args.readPixels.w = readImageSize.width();
+ cmd.args.readPixels.h = readImageSize.height();
cmd.args.readPixels.format = texD->m_format;
const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
- cmd.args.readPixels.readTarget = faceTargetBase + u.read.rb.layer();
- cmd.args.readPixels.level = u.read.rb.level();
+ cmd.args.readPixels.readTarget = faceTargetBase + uint(u.rb.layer());
+ cmd.args.readPixels.level = u.rb.level();
}
cbD->commands.append(cmd);
- } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::MipGen) {
- QGles2Texture *texD = QRHI_RES(QGles2Texture, u.mipgen.tex);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
+ QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst);
trackedImageBarrier(cbD, texD, QGles2Texture::AccessFramebuffer);
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::GenMip;
@@ -1498,6 +1577,8 @@ static inline GLenum toGlTopology(QRhiGraphicsPipeline::Topology t)
return GL_TRIANGLES;
case QRhiGraphicsPipeline::TriangleStrip:
return GL_TRIANGLE_STRIP;
+ case QRhiGraphicsPipeline::TriangleFan:
+ return GL_TRIANGLE_FAN;
case QRhiGraphicsPipeline::Lines:
return GL_LINES;
case QRhiGraphicsPipeline::LineStrip:
@@ -1833,7 +1914,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glBindVertexArray(0);
break;
case QGles2CommandBuffer::Command::Viewport:
- f->glViewport(cmd.args.viewport.x, cmd.args.viewport.y, cmd.args.viewport.w, cmd.args.viewport.h);
+ f->glViewport(GLint(cmd.args.viewport.x), GLint(cmd.args.viewport.y), GLsizei(cmd.args.viewport.w), GLsizei(cmd.args.viewport.h));
f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1);
break;
case QGles2CommandBuffer::Command::Scissor:
@@ -1846,8 +1927,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
{
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
if (psD) {
- f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask);
- f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask);
+ f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
+ f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
} else {
qWarning("No graphics pipeline active for setStencilRef; ignored");
}
@@ -1857,21 +1938,22 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
{
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.bindVertexBuffer.ps);
if (psD) {
- const QVector<QRhiVertexInputBinding> bindings = psD->m_vertexInputLayout.bindings();
- const QVector<QRhiVertexInputAttribute> attributes = psD->m_vertexInputLayout.attributes();
- for (const QRhiVertexInputAttribute &a : attributes) {
- const int bindingIdx = a.binding();
+ for (auto it = psD->m_vertexInputLayout.cbeginAttributes(), itEnd = psD->m_vertexInputLayout.cendAttributes();
+ it != itEnd; ++it)
+ {
+ const int bindingIdx = it->binding();
if (bindingIdx != cmd.args.bindVertexBuffer.binding)
continue;
// we do not support more than one vertex buffer
f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer);
- const int stride = bindings[bindingIdx].stride();
+ const QRhiVertexInputBinding *inputBinding = psD->m_vertexInputLayout.bindingAt(bindingIdx);
+ const int stride = int(inputBinding->stride());
int size = 1;
GLenum type = GL_FLOAT;
bool normalize = false;
- switch (a.format()) {
+ switch (it->format()) {
case QRhiVertexInputAttribute::Float4:
type = GL_FLOAT;
size = 4;
@@ -1907,16 +1989,13 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
break;
}
- const int locationIdx = a.location();
- quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset;
- f->glVertexAttribPointer(locationIdx, size, type, normalize, stride,
+ const int locationIdx = it->location();
+ quint32 ofs = it->offset() + cmd.args.bindVertexBuffer.offset;
+ f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride,
reinterpret_cast<const GLvoid *>(quintptr(ofs)));
- f->glEnableVertexAttribArray(locationIdx);
- if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance
- && caps.instancing)
- {
- f->glVertexAttribDivisor(locationIdx, bindings[bindingIdx].instanceStepRate());
- }
+ f->glEnableVertexAttribArray(GLuint(locationIdx));
+ if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance && caps.instancing)
+ f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(inputBinding->instanceStepRate()));
}
} else {
qWarning("No graphics pipeline active for setVertexInput; ignored");
@@ -1934,10 +2013,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
if (psD) {
if (cmd.args.draw.instanceCount == 1 || !caps.instancing) {
- f->glDrawArrays(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount);
+ f->glDrawArrays(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount));
} else {
- f->glDrawArraysInstanced(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount,
- cmd.args.draw.instanceCount);
+ f->glDrawArraysInstanced(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount),
+ GLsizei(cmd.args.draw.instanceCount));
}
} else {
qWarning("No graphics pipeline active for draw; ignored");
@@ -1953,30 +2032,30 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) {
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
f->glDrawElementsBaseVertex(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs,
cmd.args.drawIndexed.baseVertex);
} else {
f->glDrawElements(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs);
}
} else {
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
f->glDrawElementsInstancedBaseVertex(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs,
- cmd.args.drawIndexed.instanceCount,
+ GLsizei(cmd.args.drawIndexed.instanceCount),
cmd.args.drawIndexed.baseVertex);
} else {
f->glDrawElementsInstanced(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs,
- cmd.args.drawIndexed.instanceCount);
+ GLsizei(cmd.args.drawIndexed.instanceCount));
}
}
} else {
@@ -2001,7 +2080,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
QVarLengthArray<GLenum, 8> bufs;
for (int i = 0; i < colorAttCount; ++i)
- bufs.append(GL_COLOR_ATTACHMENT0 + i);
+ bufs.append(GL_COLOR_ATTACHMENT0 + uint(i));
f->glDrawBuffers(colorAttCount, bufs.constData());
}
} else {
@@ -2029,7 +2108,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glClearDepthf(cmd.args.clear.d);
}
if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT)
- f->glClearStencil(cmd.args.clear.s);
+ f->glClearStencil(GLint(cmd.args.clear.s));
f->glClear(cmd.args.clear.mask);
break;
case QGles2CommandBuffer::Command::BufferSubData:
@@ -2037,6 +2116,33 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glBufferSubData(cmd.args.bufferSubData.target, cmd.args.bufferSubData.offset, cmd.args.bufferSubData.size,
cmd.args.bufferSubData.data);
break;
+ case QGles2CommandBuffer::Command::GetBufferSubData:
+ {
+ QRhiBufferReadbackResult *result = cmd.args.getBufferSubData.result;
+ f->glBindBuffer(cmd.args.getBufferSubData.target, cmd.args.getBufferSubData.buffer);
+ if (caps.gles) {
+ if (caps.properMapBuffer) {
+ void *p = f->glMapBufferRange(cmd.args.getBufferSubData.target,
+ cmd.args.getBufferSubData.offset,
+ cmd.args.getBufferSubData.size,
+ GL_MAP_READ_BIT);
+ if (p) {
+ result->data.resize(cmd.args.getBufferSubData.size);
+ memcpy(result->data.data(), p, size_t(cmd.args.getBufferSubData.size));
+ f->glUnmapBuffer(cmd.args.getBufferSubData.target);
+ }
+ }
+ } else {
+ result->data.resize(cmd.args.getBufferSubData.size);
+ f->glGetBufferSubData(cmd.args.getBufferSubData.target,
+ cmd.args.getBufferSubData.offset,
+ cmd.args.getBufferSubData.size,
+ result->data.data());
+ }
+ if (result->completed)
+ result->completed();
+ }
+ break;
case QGles2CommandBuffer::Command::CopyTex:
{
GLuint fbo;
@@ -2058,23 +2164,31 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
QRhiReadbackResult *result = cmd.args.readPixels.result;
GLuint tex = cmd.args.readPixels.texture;
GLuint fbo = 0;
+ int mipLevel = 0;
if (tex) {
result->pixelSize = QSize(cmd.args.readPixels.w, cmd.args.readPixels.h);
result->format = cmd.args.readPixels.format;
- f->glGenFramebuffers(1, &fbo);
- f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- cmd.args.readPixels.readTarget, cmd.args.readPixels.texture, cmd.args.readPixels.level);
+ mipLevel = cmd.args.readPixels.level;
+ if (mipLevel == 0 || caps.nonBaseLevelFramebufferTexture) {
+ f->glGenFramebuffers(1, &fbo);
+ f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ cmd.args.readPixels.readTarget, cmd.args.readPixels.texture, mipLevel);
+ }
} else {
result->pixelSize = currentSwapChain->pixelSize;
result->format = QRhiTexture::RGBA8;
// readPixels handles multisample resolving implicitly
}
result->data.resize(result->pixelSize.width() * result->pixelSize.height() * 4);
- // With GLES (2.0?) GL_RGBA is the only mandated readback format, so stick with it.
- f->glReadPixels(0, 0, result->pixelSize.width(), result->pixelSize.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- result->data.data());
+ if (mipLevel == 0 || caps.nonBaseLevelFramebufferTexture) {
+ // With GLES (2.0?) GL_RGBA is the only mandated readback format, so stick with it.
+ f->glReadPixels(0, 0, result->pixelSize.width(), result->pixelSize.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ result->data.data());
+ } else {
+ result->data.fill('\0');
+ }
if (fbo) {
f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
f->glDeleteFramebuffers(1, &fbo);
@@ -2145,7 +2259,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
{
GLbitfield barriers = 0;
QRhiPassResourceTracker &tracker(cbD->passResTrackers[cmd.args.barriersForPass.trackerIndex]);
- const QVector<QRhiPassResourceTracker::Buffer> *buffers = tracker.buffers();
// we only care about after-write, not any other accesses, and
// cannot tell if something was written in a shader several passes
// ago: now the previously written resource may be used with an
@@ -2153,17 +2266,16 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
// barrier in theory. Hence setting all barrier bits whenever
// something previously written is used for the first time in a
// subsequent pass.
- for (const QRhiPassResourceTracker::Buffer &b : *buffers) {
- QGles2Buffer::Access accessBeforePass = QGles2Buffer::Access(b.stateAtPassBegin.access);
+ for (auto it = tracker.cbeginBuffers(), itEnd = tracker.cendBuffers(); it != itEnd; ++it) {
+ QGles2Buffer::Access accessBeforePass = QGles2Buffer::Access(it->stateAtPassBegin.access);
if (accessBeforePass == QGles2Buffer::AccessStorageWrite
|| accessBeforePass == QGles2Buffer::AccessStorageReadWrite)
{
barriers |= GL_ALL_BARRIER_BITS;
}
}
- const QVector<QRhiPassResourceTracker::Texture> *textures = tracker.textures();
- for (const QRhiPassResourceTracker::Texture &t : *textures) {
- QGles2Texture::Access accessBeforePass = QGles2Texture::Access(t.stateAtPassBegin.access);
+ for (auto it = tracker.cbeginTextures(), itEnd = tracker.cendTextures(); it != itEnd; ++it) {
+ QGles2Texture::Access accessBeforePass = QGles2Texture::Access(it->stateAtPassBegin.access);
if (accessBeforePass == QGles2Texture::AccessStorageWrite
|| accessBeforePass == QGles2Texture::AccessStorageReadWrite)
{
@@ -2222,6 +2334,7 @@ void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps)
}
} else {
f->glDisable(GL_BLEND);
+ f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
if (psD->m_depthTest)
f->glEnable(GL_DEPTH_TEST);
@@ -2264,7 +2377,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
int texUnit = 0;
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->m_bindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
@@ -2273,7 +2386,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
if (dynOfsCount) {
for (int j = 0; j < dynOfsCount; ++j) {
if (dynOfsPairs[2 * j] == uint(b->binding)) {
- viewOffset = dynOfsPairs[2 * j + 1];
+ viewOffset = int(dynOfsPairs[2 * j + 1]);
break;
}
}
@@ -2364,20 +2477,20 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
for (QGles2SamplerDescription &sampler : samplers) {
if (sampler.binding == b->binding) {
- f->glActiveTexture(GL_TEXTURE0 + texUnit);
+ f->glActiveTexture(GL_TEXTURE0 + uint(texUnit));
f->glBindTexture(texD->target, texD->texture);
if (texD->samplerState != samplerD->d) {
- f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, samplerD->d.glminfilter);
- f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, samplerD->d.glmagfilter);
- f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, samplerD->d.glwraps);
- f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, samplerD->d.glwrapt);
+ f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, GLint(samplerD->d.glminfilter));
+ f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, GLint(samplerD->d.glmagfilter));
+ f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, GLint(samplerD->d.glwraps));
+ f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, GLint(samplerD->d.glwrapt));
// 3D textures not supported by GLES 2.0 or by us atm...
//f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
if (caps.textureCompareMode) {
if (samplerD->d.gltexcomparefunc != GL_NEVER) {
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, samplerD->d.gltexcomparefunc);
+ f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, GLint(samplerD->d.gltexcomparefunc));
} else {
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
@@ -2404,7 +2517,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
access = GL_READ_ONLY;
else if (b->type == QRhiShaderResourceBinding::ImageStore)
access = GL_WRITE_ONLY;
- f->glBindImageTexture(b->binding, texD->texture,
+ f->glBindImageTexture(GLuint(b->binding), texD->texture,
b->u.simage.level, layered, 0,
access, texD->glsizedintformat);
}
@@ -2417,9 +2530,9 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
{
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0)
- f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer);
+ f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer);
else
- f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer,
+ f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer,
b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size);
}
break;
@@ -2470,10 +2583,12 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt,
fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer;
fbCmd.args.bindFramebuffer.colorAttCount = rtD->colorAttCount;
- const QVector<QRhiColorAttachment> colorAttachments = rtTex->m_desc.colorAttachments();
- for (const QRhiColorAttachment &colorAttachment : colorAttachments) {
- QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAttachment.texture());
- QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAttachment.resolveTexture());
+ for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments();
+ it != itEnd; ++it)
+ {
+ const QRhiColorAttachment &colorAtt(*it);
+ QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAtt.texture());
+ QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
if (texD) {
trackedRegisterTexture(&passResTracker, texD,
QRhiPassResourceTracker::TexColorOutput,
@@ -2541,10 +2656,10 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
- clearCmd.args.clear.c[0] = colorClearValue.redF();
- clearCmd.args.clear.c[1] = colorClearValue.greenF();
- clearCmd.args.clear.c[2] = colorClearValue.blueF();
- clearCmd.args.clear.c[3] = colorClearValue.alphaF();
+ clearCmd.args.clear.c[0] = float(colorClearValue.redF());
+ clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
+ clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
+ clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
cbD->commands.append(clearCmd);
@@ -2562,10 +2677,9 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (cbD->currentTarget->resourceType() == QRhiResource::TextureRenderTarget) {
QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, cbD->currentTarget);
- const QVector<QRhiColorAttachment> colorAttachments = rtTex->m_desc.colorAttachments();
- if (!colorAttachments.isEmpty()) {
+ if (rtTex->m_desc.cbeginColorAttachments() != rtTex->m_desc.cendColorAttachments()) {
// handle only 1 color attachment and only (msaa) renderbuffer
- const QRhiColorAttachment &colorAtt(colorAttachments[0]);
+ const QRhiColorAttachment &colorAtt(*rtTex->m_desc.cbeginColorAttachments());
if (colorAtt.resolveTexture()) {
Q_ASSERT(colorAtt.renderBuffer());
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, colorAtt.renderBuffer());
@@ -2582,7 +2696,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
: colorTexD->target;
- cmd.args.blitFromRb.target = faceTargetBase + colorAtt.resolveLayer();
+ cmd.args.blitFromRb.target = faceTargetBase + uint(colorAtt.resolveLayer());
cmd.args.blitFromRb.texture = colorTexD->texture;
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
cbD->commands.append(cmd);
@@ -2649,9 +2763,9 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
- cmd.args.dispatch.x = x;
- cmd.args.dispatch.y = y;
- cmd.args.dispatch.z = z;
+ cmd.args.dispatch.x = GLuint(x);
+ cmd.args.dispatch.y = GLuint(y);
+ cmd.args.dispatch.z = GLuint(z);
cbD->commands.append(cmd);
}
@@ -2670,10 +2784,8 @@ static inline GLenum toGlShaderType(QRhiShaderStage::Type type)
}
}
-bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage,
- QShaderDescription *desc, int *glslVersionUsed)
+QByteArray QRhiGles2::shaderSource(const QRhiShaderStage &shaderStage, int *glslVersion)
{
- GLuint shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
const QShader bakedShader = shaderStage.shader();
QVector<int> versionsToTry;
QByteArray source;
@@ -2691,8 +2803,8 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage
QShaderVersion ver(v, QShaderVersion::GlslEs);
source = bakedShader.shader({ QShader::GlslShader, ver, shaderStage.shaderVariant() }).shader();
if (!source.isEmpty()) {
- if (glslVersionUsed)
- *glslVersionUsed = v;
+ if (glslVersion)
+ *glslVersion = v;
break;
}
}
@@ -2721,8 +2833,8 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage
for (int v : versionsToTry) {
source = bakedShader.shader({ QShader::GlslShader, v, shaderStage.shaderVariant() }).shader();
if (!source.isEmpty()) {
- if (glslVersionUsed)
- *glslVersionUsed = v;
+ if (glslVersion)
+ *glslVersion = v;
break;
}
}
@@ -2730,32 +2842,51 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage
if (source.isEmpty()) {
qWarning() << "No GLSL shader code found (versions tried: " << versionsToTry
<< ") in baked shader" << bakedShader;
- return false;
}
+ return source;
+}
- const char *srcStr = source.constData();
- const GLint srcLength = source.count();
- f->glShaderSource(shader, 1, &srcStr, &srcLength);
- f->glCompileShader(shader);
- GLint compiled = 0;
- f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- if (!compiled) {
- GLint infoLogLength = 0;
- f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
- QByteArray log;
- if (infoLogLength > 1) {
- GLsizei length = 0;
- log.resize(infoLogLength);
- f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
- }
- qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
+bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage, int *glslVersion)
+{
+ const QByteArray source = shaderSource(shaderStage, glslVersion);
+ if (source.isEmpty())
return false;
+
+ GLuint shader;
+ auto cacheIt = m_shaderCache.constFind(shaderStage);
+ if (cacheIt != m_shaderCache.constEnd()) {
+ shader = *cacheIt;
+ } else {
+ shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
+ const char *srcStr = source.constData();
+ const GLint srcLength = source.count();
+ f->glShaderSource(shader, 1, &srcStr, &srcLength);
+ f->glCompileShader(shader);
+ GLint compiled = 0;
+ f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLogLength = 0;
+ f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+ QByteArray log;
+ if (infoLogLength > 1) {
+ GLsizei length = 0;
+ log.resize(infoLogLength);
+ f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
+ }
+ qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
+ return false;
+ }
+ if (m_shaderCache.count() >= MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader); // does not actually get released yet when attached to a not-yet-released program
+ m_shaderCache.clear();
+ }
+ m_shaderCache.insert(shaderStage, shader);
}
f->glAttachShader(program, shader);
- f->glDeleteShader(shader);
- *desc = bakedShader.description();
return true;
}
@@ -2791,7 +2922,7 @@ void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::Uniform
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
if (uniform.glslLocation >= 0) {
uniform.binding = ub.binding;
- uniform.offset = blockMember.offset;
+ uniform.offset = uint(blockMember.offset);
uniform.size = blockMember.size;
dst->append(uniform);
}
@@ -2810,6 +2941,68 @@ void QRhiGles2::gatherSamplers(GLuint program, const QShaderDescription::InOutVa
}
}
+bool QRhiGles2::isProgramBinaryDiskCacheEnabled() const
+{
+ static QOpenGLProgramBinarySupportCheckWrapper checker;
+ return checker.get(ctx)->isSupported();
+}
+
+static QOpenGLProgramBinaryCache qrhi_programBinaryCache;
+
+static inline QShader::Stage toShaderStage(QRhiShaderStage::Type type)
+{
+ switch (type) {
+ case QRhiShaderStage::Vertex:
+ return QShader::VertexStage;
+ case QRhiShaderStage::Fragment:
+ return QShader::FragmentStage;
+ case QRhiShaderStage::Compute:
+ return QShader::ComputeStage;
+ default:
+ Q_UNREACHABLE();
+ return QShader::VertexStage;
+ }
+}
+
+QRhiGles2::DiskCacheResult QRhiGles2::tryLoadFromDiskCache(const QRhiShaderStage *stages, int stageCount,
+ GLuint program, QByteArray *cacheKey)
+{
+ QRhiGles2::DiskCacheResult result = QRhiGles2::DiskCacheMiss;
+ QByteArray diskCacheKey;
+
+ if (isProgramBinaryDiskCacheEnabled()) {
+ QOpenGLProgramBinaryCache::ProgramDesc binaryProgram;
+ for (int i = 0; i < stageCount; ++i) {
+ const QRhiShaderStage &stage(stages[i]);
+ const QByteArray source = shaderSource(stage, nullptr);
+ if (source.isEmpty())
+ return QRhiGles2::DiskCacheError;
+ binaryProgram.shaders.append(QOpenGLProgramBinaryCache::ShaderDesc(toShaderStage(stage.type()), source));
+ }
+
+ diskCacheKey = binaryProgram.cacheKey();
+ if (qrhi_programBinaryCache.load(diskCacheKey, program)) {
+ qCDebug(lcOpenGLProgramDiskCache, "Program binary received from cache, program %u, key %s",
+ program, diskCacheKey.constData());
+ result = QRhiGles2::DiskCacheHit;
+ }
+ }
+
+ if (cacheKey)
+ *cacheKey = diskCacheKey;
+
+ return result;
+}
+
+void QRhiGles2::trySaveToDiskCache(GLuint program, const QByteArray &cacheKey)
+{
+ if (isProgramBinaryDiskCacheEnabled()) {
+ qCDebug(lcOpenGLProgramDiskCache, "Saving program binary, program %u, key %s",
+ program, cacheKey.constData());
+ qrhi_programBinaryCache.save(cacheKey, program);
+ }
+}
+
QGles2Buffer::QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, int size)
: QRhiBuffer(rhi, type, usage, size)
{
@@ -2855,7 +3048,7 @@ bool QGles2Buffer::build()
return false;
}
ubuf.resize(nonZeroSize);
- QRHI_PROF_F(newBuffer(this, nonZeroSize, 0, 1));
+ QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 0, 1));
return true;
}
@@ -2874,7 +3067,7 @@ bool QGles2Buffer::build()
usageState.access = AccessNone;
- QRHI_PROF_F(newBuffer(this, nonZeroSize, 1, 0));
+ QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 1, 0));
rhiD->registerResource(this);
return true;
}
@@ -3145,13 +3338,13 @@ bool QGles2Texture::build()
for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
for (int level = 0; level != mipLevelCount; ++level) {
const QSize mipSize = rhiD->q->sizeForMipLevel(level, size);
- rhiD->f->glTexImage2D(faceTargetBase + layer, level, glintformat,
+ rhiD->f->glTexImage2D(faceTargetBase + uint(layer), level, GLint(glintformat),
mipSize.width(), mipSize.height(), 0,
glformat, gltype, nullptr);
}
}
} else {
- rhiD->f->glTexImage2D(target, 0, glintformat, size.width(), size.height(),
+ rhiD->f->glTexImage2D(target, 0, GLint(glintformat), size.width(), size.height(),
0, glformat, gltype, nullptr);
}
} else {
@@ -3327,14 +3520,18 @@ bool QGles2TextureRenderTarget::build()
if (framebuffer)
release();
- const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
- Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture());
+ const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments();
+ Q_ASSERT(hasColorAttachments || m_desc.depthTexture());
Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture());
const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();
- if (colorAttachments.count() > rhiD->caps.maxDrawBuffers)
- qWarning("QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)",
- colorAttachments.count(), rhiD->caps.maxDrawBuffers);
+ if (hasColorAttachments) {
+ const int count = m_desc.cendColorAttachments() - m_desc.cbeginColorAttachments();
+ if (count > rhiD->caps.maxDrawBuffers) {
+ qWarning("QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)",
+ count, rhiD->caps.maxDrawBuffers);
+ }
+ }
if (m_desc.depthTexture() && !rhiD->caps.depthTexture)
qWarning("QGles2TextureRenderTarget: Depth texture is not supported and will be ignored");
@@ -3344,9 +3541,11 @@ bool QGles2TextureRenderTarget::build()
rhiD->f->glGenFramebuffers(1, &framebuffer);
rhiD->f->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
- d.colorAttCount = colorAttachments.count();
- for (int i = 0; i < d.colorAttCount; ++i) {
- const QRhiColorAttachment &colorAtt(colorAttachments[i]);
+ d.colorAttCount = 0;
+ int attIndex = 0;
+ for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
+ d.colorAttCount += 1;
+ const QRhiColorAttachment &colorAtt(*it);
QRhiTexture *texture = colorAtt.texture();
QRhiRenderBuffer *renderBuffer = colorAtt.renderBuffer();
Q_ASSERT(texture || renderBuffer);
@@ -3354,15 +3553,16 @@ bool QGles2TextureRenderTarget::build()
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
Q_ASSERT(texD->texture && texD->specified);
const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
- rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, faceTargetBase + colorAtt.layer(), texD->texture, colorAtt.level());
- if (i == 0) {
+ rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(attIndex), faceTargetBase + uint(colorAtt.layer()),
+ texD->texture, colorAtt.level());
+ if (attIndex == 0) {
d.pixelSize = texD->pixelSize();
d.sampleCount = 1;
}
} else if (renderBuffer) {
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
- rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, rbD->renderbuffer);
- if (i == 0) {
+ rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(attIndex), GL_RENDERBUFFER, rbD->renderbuffer);
+ if (attIndex == 0) {
d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples;
}
@@ -3491,32 +3691,50 @@ bool QGles2GraphicsPipeline::build()
if (!rhiD->ensureContext())
return false;
+ if (!rhiD->sanityCheckGraphicsPipeline(this))
+ return false;
+
drawMode = toGlTopology(m_topology);
program = rhiD->f->glCreateProgram();
+ QByteArray diskCacheKey;
+ QRhiGles2::DiskCacheResult diskCacheResult = rhiD->tryLoadFromDiskCache(m_shaderStages.constData(),
+ m_shaderStages.count(),
+ program,
+ &diskCacheKey);
+ if (diskCacheResult == QRhiGles2::DiskCacheError)
+ return false;
+
+ const bool needsCompile = diskCacheResult == QRhiGles2::DiskCacheMiss;
+
QShaderDescription vsDesc;
QShaderDescription fsDesc;
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
const bool isVertex = shaderStage.type() == QRhiShaderStage::Vertex;
const bool isFragment = shaderStage.type() == QRhiShaderStage::Fragment;
if (isVertex) {
- if (!rhiD->compileShader(program, shaderStage, &vsDesc, nullptr))
+ if (needsCompile && !rhiD->compileShader(program, shaderStage, nullptr))
return false;
+ vsDesc = shaderStage.shader().description();
} else if (isFragment) {
- if (!rhiD->compileShader(program, shaderStage, &fsDesc, nullptr))
+ if (needsCompile && !rhiD->compileShader(program, shaderStage, nullptr))
return false;
+ fsDesc = shaderStage.shader().description();
}
}
for (auto inVar : vsDesc.inputVariables()) {
const QByteArray name = inVar.name.toUtf8();
- rhiD->f->glBindAttribLocation(program, inVar.location, name.constData());
+ rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), name.constData());
}
- if (!rhiD->linkProgram(program))
+ if (needsCompile && !rhiD->linkProgram(program))
return false;
+ if (needsCompile)
+ rhiD->trySaveToDiskCache(program, diskCacheKey);
+
for (const QShaderDescription::UniformBlock &ub : vsDesc.uniformBlocks())
rhiD->gatherUniforms(program, ub, &uniforms);
@@ -3577,11 +3795,24 @@ bool QGles2ComputePipeline::build()
program = rhiD->f->glCreateProgram();
QShaderDescription csDesc;
- if (!rhiD->compileShader(program, m_shaderStage, &csDesc, nullptr))
+ QByteArray diskCacheKey;
+ QRhiGles2::DiskCacheResult diskCacheResult = rhiD->tryLoadFromDiskCache(&m_shaderStage, 1, program, &diskCacheKey);
+ if (diskCacheResult == QRhiGles2::DiskCacheError)
return false;
- if (!rhiD->linkProgram(program))
+
+ const bool needsCompile = diskCacheResult == QRhiGles2::DiskCacheMiss;
+
+ if (needsCompile && !rhiD->compileShader(program, m_shaderStage, nullptr))
return false;
+ csDesc = m_shaderStage.shader().description();
+
+ if (needsCompile && !rhiD->linkProgram(program))
+ return false;
+
+ if (needsCompile)
+ rhiD->trySaveToDiskCache(program, diskCacheKey);
+
for (const QShaderDescription::UniformBlock &ub : csDesc.uniformBlocks())
rhiD->gatherUniforms(program, ub, &uniforms);
for (const QShaderDescription::InOutVariable &v : csDesc.combinedImageSamplers())
@@ -3655,9 +3886,16 @@ bool QGles2SwapChain::buildOrResize()
m_currentPixelSize = surfacePixelSize();
pixelSize = m_currentPixelSize;
+ if (m_depthStencil && m_depthStencil->flags().testFlag(QRhiRenderBuffer::UsedWithSwapChainOnly)
+ && m_depthStencil->pixelSize() != pixelSize)
+ {
+ m_depthStencil->setPixelSize(pixelSize);
+ m_depthStencil->build();
+ }
+
rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
rt.d.pixelSize = pixelSize;
- rt.d.dpr = m_window->devicePixelRatio();
+ rt.d.dpr = float(m_window->devicePixelRatio());
rt.d.sampleCount = qBound(1, m_sampleCount, 64);
rt.d.colorAttCount = 1;
rt.d.dsAttCount = m_depthStencil ? 1 : 0;
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 6da529be92..8814d9c19d 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -312,8 +312,8 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
BindShaderResources,
BindFramebuffer,
Clear,
- BufferData,
BufferSubData,
+ GetBufferSubData,
CopyTex,
ReadPixels,
SubImage,
@@ -402,6 +402,13 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
const void *data; // must come from retainData()
} bufferSubData;
struct {
+ QRhiBufferReadbackResult *result;
+ GLenum target;
+ GLuint buffer;
+ int offset;
+ int size;
+ } getBufferSubData;
+ struct {
GLenum srcFaceTarget;
GLuint srcTexture;
int srcLevel;
@@ -664,7 +671,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
bool ensureContext(QSurface *surface = nullptr) const;
void executeDeferredReleases();
@@ -690,13 +699,23 @@ public:
bool *wantsColorClear = nullptr, bool *wantsDsClear = nullptr);
void enqueueBarriersForPass(QGles2CommandBuffer *cbD);
int effectiveSampleCount(int sampleCount) const;
- bool compileShader(GLuint program, const QRhiShaderStage &shaderStage,
- QShaderDescription *desc, int *glslVersionUsed);
+ QByteArray shaderSource(const QRhiShaderStage &shaderStage, int *glslVersion);
+ bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, int *glslVersion);
bool linkProgram(GLuint program);
void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub,
QVector<QGles2UniformDescription> *dst);
void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v,
QVector<QGles2SamplerDescription> *dst);
+ bool isProgramBinaryDiskCacheEnabled() const;
+
+ enum DiskCacheResult {
+ DiskCacheHit,
+ DiskCacheMiss,
+ DiskCacheError
+ };
+ DiskCacheResult tryLoadFromDiskCache(const QRhiShaderStage *stages, int stageCount,
+ GLuint program, QByteArray *cacheKey);
+ void trySaveToDiskCache(GLuint program, const QByteArray &cacheKey);
QOpenGLContext *ctx = nullptr;
bool importedContext = false;
@@ -732,7 +751,10 @@ public:
rgba8Format(false),
instancing(false),
baseVertex(false),
- compute(false)
+ compute(false),
+ textureCompareMode(false),
+ properMapBuffer(false),
+ nonBaseLevelFramebufferTexture(false)
{ }
int ctxMajor;
int ctxMinor;
@@ -763,11 +785,14 @@ public:
uint baseVertex : 1;
uint compute : 1;
uint textureCompareMode : 1;
+ uint properMapBuffer : 1;
+ uint nonBaseLevelFramebufferTexture : 1;
} caps;
QGles2SwapChain *currentSwapChain = nullptr;
QVector<GLint> supportedCompressedFormats;
mutable QVector<int> supportedSampleCountList;
QRhiGles2NativeHandles nativeHandlesStruct;
+ mutable bool contextLost = false;
struct DeferredReleaseEntry {
enum Type {
@@ -804,6 +829,8 @@ public:
bool active = false;
QGles2CommandBuffer cbWrapper;
} ofr;
+
+ QHash<QRhiShaderStage, uint> m_shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 07753c985c..5f14d917b8 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -138,6 +138,20 @@ QT_BEGIN_NAMESPACE
\l{QRhiCommandBuffer::endPass()}.
*/
+struct QMetalShader
+{
+ id<MTLLibrary> lib = nil;
+ id<MTLFunction> func = nil;
+ std::array<uint, 3> localSize;
+
+ void release() {
+ [lib release];
+ lib = nil;
+ [func release];
+ func = nil;
+ }
+};
+
struct QRhiMetalData
{
QRhiMetalData(QRhiImplementation *rhi) : ofr(rhi) { }
@@ -191,7 +205,7 @@ struct QRhiMetalData
QMetalCommandBuffer cbWrapper;
} ofr;
- struct ActiveReadback {
+ struct TextureReadback {
int activeFrameSlot = -1;
QRhiReadbackDescription desc;
QRhiReadbackResult *result;
@@ -200,23 +214,25 @@ struct QRhiMetalData
QSize pixelSize;
QRhiTexture::Format format;
};
- QVector<ActiveReadback> activeReadbacks;
+ QVector<TextureReadback> activeTextureReadbacks;
API_AVAILABLE(macos(10.13), ios(11.0)) MTLCaptureManager *captureMgr;
API_AVAILABLE(macos(10.13), ios(11.0)) id<MTLCaptureScope> captureScope = nil;
static const int TEXBUF_ALIGN = 256; // probably not accurate
+
+ QHash<QRhiShaderStage, QMetalShader> shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiMetalData::DeferredReleaseEntry, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QRhiMetalData::ActiveReadback, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QRhiMetalData::TextureReadback, Q_MOVABLE_TYPE);
struct QMetalBufferData
{
bool managed;
bool slotted;
id<MTLBuffer> buf[QMTL_FRAMES_IN_FLIGHT];
- QVector<QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate> pendingUpdates[QMTL_FRAMES_IN_FLIGHT];
+ QVarLengthArray<QRhiResourceUpdateBatchPrivate::BufferOp, 16> pendingUpdates[QMTL_FRAMES_IN_FLIGHT];
};
struct QMetalRenderBufferData
@@ -289,17 +305,14 @@ struct QMetalGraphicsPipelineData
MTLPrimitiveType primitiveType;
MTLWinding winding;
MTLCullMode cullMode;
- id<MTLLibrary> vsLib = nil;
- id<MTLFunction> vsFunc = nil;
- id<MTLLibrary> fsLib = nil;
- id<MTLFunction> fsFunc = nil;
+ QMetalShader vs;
+ QMetalShader fs;
};
struct QMetalComputePipelineData
{
id<MTLComputePipelineState> ps = nil;
- id<MTLLibrary> csLib = nil;
- id<MTLFunction> csFunc = nil;
+ QMetalShader cs;
MTLSize localSize;
};
@@ -339,7 +352,8 @@ QRhiMetal::~QRhiMetal()
delete d;
}
-static inline uint aligned(uint v, uint byteAlign)
+template <class Int>
+inline Int aligned(Int v, Int byteAlign)
{
return (v + byteAlign - 1) & ~(byteAlign - 1);
}
@@ -353,6 +367,11 @@ bool QRhiMetal::create(QRhi::Flags flags)
else
d->dev = MTLCreateSystemDefaultDevice();
+ if (!d->dev) {
+ qWarning("No MTLDevice");
+ return false;
+ }
+
qCDebug(QRHI_LOG_INFO, "Metal device: %s", qPrintable(QString::fromNSString([d->dev name])));
if (importedCmdQueue)
@@ -404,6 +423,10 @@ void QRhiMetal::destroy()
executeDeferredReleases(true);
finishActiveReadbacks(true);
+ for (QMetalShader &s : d->shaderCache)
+ s.release();
+ d->shaderCache.clear();
+
if (@available(macOS 10.13, iOS 11.0, *)) {
[d->captureScope release];
d->captureScope = nil;
@@ -532,6 +555,12 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::BaseInstance:
return true;
+ case QRhi::TriangleFanTopology:
+ return false;
+ case QRhi::ReadBackNonUniformBuffer:
+ return true;
+ case QRhi::ReadBackNonBaseMipLevel:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -565,9 +594,23 @@ void QRhiMetal::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiMetal::makeThreadLocalNativeContextCurrent()
+bool QRhiMetal::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
+}
+
+void QRhiMetal::releaseCachedResources()
+{
+ for (QMetalShader &s : d->shaderCache)
+ s.release();
+
+ d->shaderCache.clear();
+}
+
+bool QRhiMetal::isDeviceLost() const
+{
+ return false;
}
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -624,13 +667,13 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
} res[KNOWN_STAGES];
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
+ const QRhiShaderResourceBinding::Data *b = binding.data();
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
{
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf);
id<MTLBuffer> mtlbuf = bufD->d->buf[bufD->d->slotted ? currentFrameSlot : 0];
- uint offset = b->u.ubuf.offset;
+ uint offset = uint(b->u.ubuf.offset);
for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
if (dynOfs.first == b->binding) {
@@ -694,7 +737,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
{
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf);
id<MTLBuffer> mtlbuf = bufD->d->buf[0];
- uint offset = b->u.sbuf.offset;
+ uint offset = uint(b->u.sbuf.offset);
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
res[0].buffers.feed(b->binding, mtlbuf);
res[0].bufferOffsets.feed(b->binding, offset);
@@ -726,17 +769,17 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
case 0:
[cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break;
case 1:
[cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break;
case 2:
[cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break;
default:
Q_UNREACHABLE();
@@ -755,15 +798,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
switch (idx) {
case 0:
[cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 1:
[cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 2:
[cbD->d->currentComputePassEncoder setTextures: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
default:
Q_UNREACHABLE();
@@ -775,15 +818,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
switch (idx) {
case 0:
[cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 1:
[cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 2:
[cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
default:
Q_UNREACHABLE();
@@ -806,8 +849,15 @@ void QRhiMetal::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
[cbD->d->currentRenderPassEncoder setRenderPipelineState: psD->d->ps];
[cbD->d->currentRenderPassEncoder setDepthStencilState: psD->d->ds];
- [cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode];
- [cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding];
+
+ if (cbD->currentCullMode == -1 || psD->d->cullMode != uint(cbD->currentCullMode)) {
+ [cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode];
+ cbD->currentCullMode = int(psD->d->cullMode);
+ }
+ if (cbD->currentFrontFaceWinding == -1 || psD->d->winding != uint(cbD->currentFrontFaceWinding)) {
+ [cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding];
+ cbD->currentFrontFaceWinding = int(psD->d->winding);
+ }
}
psD->lastActiveFrameSlot = currentFrameSlot;
@@ -836,7 +886,7 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
// do buffer writes, figure out if we need to rebind, and mark as in-use
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
QMetalShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
@@ -981,7 +1031,7 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
[cbD->d->currentRenderPassEncoder setVertexBuffers:
bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(firstVertexBinding + bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(uint(firstVertexBinding) + bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
}
}
@@ -1009,21 +1059,21 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
return;
MTLViewport vp;
- vp.originX = x;
- vp.originY = y;
- vp.width = w;
- vp.height = h;
- vp.znear = viewport.minDepth();
- vp.zfar = viewport.maxDepth();
+ vp.originX = double(x);
+ vp.originY = double(y);
+ vp.width = double(w);
+ vp.height = double(h);
+ vp.znear = double(viewport.minDepth());
+ vp.zfar = double(viewport.maxDepth());
[cbD->d->currentRenderPassEncoder setViewport: vp];
if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
MTLScissorRect s;
- s.x = x;
- s.y = y;
- s.width = w;
- s.height = h;
+ s.x = NSUInteger(x);
+ s.y = NSUInteger(y);
+ s.width = NSUInteger(w);
+ s.height = NSUInteger(h);
[cbD->d->currentRenderPassEncoder setScissorRect: s];
}
}
@@ -1041,10 +1091,10 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
return;
MTLScissorRect s;
- s.x = x;
- s.y = y;
- s.width = w;
- s.height = h;
+ s.x = NSUInteger(x);
+ s.y = NSUInteger(y);
+ s.width = NSUInteger(w);
+ s.height = NSUInteger(h);
[cbD->d->currentRenderPassEncoder setScissorRect: s];
}
@@ -1054,7 +1104,8 @@ void QRhiMetal::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
- [cbD->d->currentRenderPassEncoder setBlendColorRed: c.redF() green: c.greenF() blue: c.blueF() alpha: c.alphaF()];
+ [cbD->d->currentRenderPassEncoder setBlendColorRed: float(c.redF())
+ green: float(c.greenF()) blue: float(c.blueF()) alpha: float(c.alphaF())];
}
void QRhiMetal::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
@@ -1086,7 +1137,7 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
return;
const quint32 indexOffset = cbD->currentIndexOffset + firstIndex * (cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? 2 : 4);
- Q_ASSERT(indexOffset == aligned(indexOffset, 4));
+ Q_ASSERT(indexOffset == aligned<quint32>(indexOffset, 4));
QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer);
id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0];
@@ -1344,7 +1395,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
MTLClearColor c = MTLClearColorMake(colorClearValue.redF(), colorClearValue.greenF(), colorClearValue.blueF(),
colorClearValue.alphaF());
- for (int i = 0; i < colorAttCount; ++i) {
+ for (uint i = 0; i < uint(colorAttCount); ++i) {
rp.colorAttachments[i].loadAction = MTLLoadActionClear;
rp.colorAttachments[i].storeAction = MTLStoreActionStore;
rp.colorAttachments[i].clearColor = c;
@@ -1355,7 +1406,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
rp.depthAttachment.storeAction = MTLStoreActionDontCare;
rp.stencilAttachment.loadAction = MTLLoadActionClear;
rp.stencilAttachment.storeAction = MTLStoreActionDontCare;
- rp.depthAttachment.clearDepth = depthStencilClearValue.depthClearValue();
+ rp.depthAttachment.clearDepth = double(depthStencilClearValue.depthClearValue());
rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue();
}
@@ -1368,7 +1419,7 @@ qsizetype QRhiMetal::subresUploadByteSize(const QRhiTextureSubresourceUploadDesc
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
subresDesc.data().size() : subresDesc.image().sizeInBytes();
if (imageSizeBytes > 0)
- size += aligned(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
+ size += aligned<qsizetype>(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
return size;
}
@@ -1396,31 +1447,31 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
h = subresDesc.sourceSize().height();
}
if (img.depth() == 32) {
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes);
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
srcOffset = sy * bpl + sx * 4;
// bpl remains set to the original image's row stride
} else {
img = img.copy(sx, sy, w, h);
bpl = img.bytesPerLine();
Q_ASSERT(img.sizeInBytes() <= fullImageSizeBytes);
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), img.sizeInBytes());
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(img.sizeInBytes()));
}
} else {
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes);
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
}
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
- sourceOffset: *curOfs + srcOffset
- sourceBytesPerRow: bpl
+ sourceOffset: NSUInteger(*curOfs + srcOffset)
+ sourceBytesPerRow: NSUInteger(bpl)
sourceBytesPerImage: 0
- sourceSize: MTLSizeMake(w, h, 1)
+ sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex
- destinationSlice: layer
- destinationLevel: level
- destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
+ destinationSlice: NSUInteger(layer)
+ destinationLevel: NSUInteger(level)
+ destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
options: MTLBlitOptionNone];
- *curOfs += aligned(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
+ *curOfs += aligned<qsizetype>(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize);
const int subresw = subresSize.width();
@@ -1445,17 +1496,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
if (dy + h != subresh)
h = aligned(h, blockDim.height());
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size());
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
- sourceOffset: *curOfs
+ sourceOffset: NSUInteger(*curOfs)
sourceBytesPerRow: bpl
sourceBytesPerImage: 0
- sourceSize: MTLSizeMake(w, h, 1)
+ sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex
- destinationSlice: layer
- destinationLevel: level
- destinationOrigin: MTLOriginMake(dx, dy, 0)
+ destinationSlice: NSUInteger(layer)
+ destinationLevel: NSUInteger(level)
+ destinationOrigin: MTLOriginMake(NSUInteger(dx), NSUInteger(dy), 0)
options: MTLBlitOptionNone];
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
@@ -1474,17 +1525,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
quint32 bpl = 0;
textureFormatInfo(texD->m_format, QSize(w, h), &bpl, nullptr);
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size());
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
- sourceOffset: *curOfs
+ sourceOffset: NSUInteger(*curOfs)
sourceBytesPerRow: bpl
sourceBytesPerImage: 0
- sourceSize: MTLSizeMake(w, h, 1)
+ sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex
- destinationSlice: layer
- destinationLevel: level
- destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
+ destinationSlice: NSUInteger(layer)
+ destinationLevel: NSUInteger(level)
+ destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
options: MTLBlitOptionNone];
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
@@ -1499,21 +1550,33 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
- QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, u.buf);
- Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
- for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i)
- bufD->d->pendingUpdates[i].append(u);
- }
-
- // Due to the Metal API the handling of static and dynamic buffers is
- // basically the same. So go through the same pendingUpdates machinery.
- for (const QRhiResourceUpdateBatchPrivate::StaticBufferUpload &u : ud->staticBufferUploads) {
- QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, u.buf);
- Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
- Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
- for (int i = 0, ie = bufD->d->slotted ? QMTL_FRAMES_IN_FLIGHT : 1; i != ie; ++i)
- bufD->d->pendingUpdates[i].append({ u.buf, u.offset, u.data.size(), u.data.constData() });
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
+ QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, u.buf);
+ Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
+ for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i)
+ bufD->d->pendingUpdates[i].append(u);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload) {
+ // Due to the Metal API the handling of static and dynamic buffers is
+ // basically the same. So go through the same pendingUpdates machinery.
+ QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, u.buf);
+ Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
+ Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
+ for (int i = 0, ie = bufD->d->slotted ? QMTL_FRAMES_IN_FLIGHT : 1; i != ie; ++i)
+ bufD->d->pendingUpdates[i].append(
+ QRhiResourceUpdateBatchPrivate::BufferOp::dynamicUpdate(u.buf, u.offset, u.data.size(), u.data.constData()));
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
+ QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, u.buf);
+ executeBufferHostWritesForCurrentFrame(bufD);
+ const int idx = bufD->d->slotted ? currentFrameSlot : 0;
+ char *p = reinterpret_cast<char *>([bufD->d->buf[idx] contents]);
+ if (p) {
+ u.result->data.resize(u.readSize);
+ memcpy(u.result->data.data(), p + u.offset, size_t(u.readSize));
+ }
+ if (u.result->completed)
+ u.result->completed();
+ }
}
id<MTLBlitCommandEncoder> blitEnc = nil;
@@ -1527,26 +1590,26 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
- QMetalTexture *utexD = QRHI_RES(QMetalTexture, u.upload.tex);
+ QMetalTexture *utexD = QRHI_RES(QMetalTexture, u.dst);
qsizetype stagingSize = 0;
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
- for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.upload.subresDesc[layer][level]))
+ for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
stagingSize += subresUploadByteSize(subresDesc);
}
}
ensureBlit();
Q_ASSERT(!utexD->d->stagingBuf[currentFrameSlot]);
- utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: stagingSize
+ utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: NSUInteger(stagingSize)
options: MTLResourceStorageModeShared];
- QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize));
+ QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents];
qsizetype curOfs = 0;
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
- for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.upload.subresDesc[layer][level]))
+ for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
enqueueSubresUpload(utexD, mp, blitEnc, layer, level, subresDesc, &curOfs);
}
}
@@ -1561,32 +1624,33 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
d->releaseQueue.append(e);
QRHI_PROF_F(releaseTextureStagingArea(utexD, currentFrameSlot));
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Copy) {
- Q_ASSERT(u.copy.src && u.copy.dst);
- QMetalTexture *srcD = QRHI_RES(QMetalTexture, u.copy.src);
- QMetalTexture *dstD = QRHI_RES(QMetalTexture, u.copy.dst);
- const QPoint dp = u.copy.desc.destinationTopLeft();
- const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
- const QPoint sp = u.copy.desc.sourceTopLeft();
+ Q_ASSERT(u.src && u.dst);
+ QMetalTexture *srcD = QRHI_RES(QMetalTexture, u.src);
+ QMetalTexture *dstD = QRHI_RES(QMetalTexture, u.dst);
+ const QPoint dp = u.desc.destinationTopLeft();
+ const QSize mipSize = q->sizeForMipLevel(u.desc.sourceLevel(), srcD->m_pixelSize);
+ const QSize copySize = u.desc.pixelSize().isEmpty() ? mipSize : u.desc.pixelSize();
+ const QPoint sp = u.desc.sourceTopLeft();
ensureBlit();
[blitEnc copyFromTexture: srcD->d->tex
- sourceSlice: u.copy.desc.sourceLayer()
- sourceLevel: u.copy.desc.sourceLevel()
- sourceOrigin: MTLOriginMake(sp.x(), sp.y(), 0)
- sourceSize: MTLSizeMake(size.width(), size.height(), 1)
+ sourceSlice: NSUInteger(u.desc.sourceLayer())
+ sourceLevel: NSUInteger(u.desc.sourceLevel())
+ sourceOrigin: MTLOriginMake(NSUInteger(sp.x()), NSUInteger(sp.y()), 0)
+ sourceSize: MTLSizeMake(NSUInteger(copySize.width()), NSUInteger(copySize.height()), 1)
toTexture: dstD->d->tex
- destinationSlice: u.copy.desc.destinationLayer()
- destinationLevel: u.copy.desc.destinationLevel()
- destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)];
+ destinationSlice: NSUInteger(u.desc.destinationLayer())
+ destinationLevel: NSUInteger(u.desc.destinationLevel())
+ destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)];
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
- QRhiMetalData::ActiveReadback aRb;
- aRb.activeFrameSlot = currentFrameSlot;
- aRb.desc = u.read.rb;
- aRb.result = u.read.result;
+ QRhiMetalData::TextureReadback readback;
+ readback.activeFrameSlot = currentFrameSlot;
+ readback.desc = u.rb;
+ readback.result = u.result;
- QMetalTexture *texD = QRHI_RES(QMetalTexture, u.read.rb.texture());
+ QMetalTexture *texD = QRHI_RES(QMetalTexture, u.rb.texture());
QMetalSwapChain *swapChainD = nullptr;
id<MTLTexture> src;
QSize srcSize;
@@ -1595,17 +1659,16 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
qWarning("Multisample texture cannot be read back");
continue;
}
- aRb.pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize)
- : texD->m_pixelSize;
- aRb.format = texD->m_format;
+ readback.pixelSize = q->sizeForMipLevel(u.rb.level(), texD->m_pixelSize);
+ readback.format = texD->m_format;
src = texD->d->tex;
- srcSize = texD->m_pixelSize;
+ srcSize = readback.pixelSize;
texD->lastActiveFrameSlot = currentFrameSlot;
} else {
Q_ASSERT(currentSwapChain);
swapChainD = QRHI_RES(QMetalSwapChain, currentSwapChain);
- aRb.pixelSize = swapChainD->pixelSize;
- aRb.format = swapChainD->d->rhiColorFormat;
+ readback.pixelSize = swapChainD->pixelSize;
+ readback.format = swapChainD->d->rhiColorFormat;
// Multisample swapchains need nothing special since resolving
// happens when ending a renderpass.
const QMetalRenderTargetData::ColorAtt &colorAtt(swapChainD->rtWrapper.d->fb.colorAtt[0]);
@@ -1614,28 +1677,28 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
quint32 bpl = 0;
- textureFormatInfo(aRb.format, aRb.pixelSize, &bpl, &aRb.bufSize);
- aRb.buf = [d->dev newBufferWithLength: aRb.bufSize options: MTLResourceStorageModeShared];
+ textureFormatInfo(readback.format, readback.pixelSize, &bpl, &readback.bufSize);
+ readback.buf = [d->dev newBufferWithLength: readback.bufSize options: MTLResourceStorageModeShared];
- QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(aRb.buf)),
+ QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(readback.buf)),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
- aRb.bufSize));
+ readback.bufSize));
ensureBlit();
[blitEnc copyFromTexture: src
- sourceSlice: u.read.rb.layer()
- sourceLevel: u.read.rb.level()
+ sourceSlice: NSUInteger(u.rb.layer())
+ sourceLevel: NSUInteger(u.rb.level())
sourceOrigin: MTLOriginMake(0, 0, 0)
- sourceSize: MTLSizeMake(srcSize.width(), srcSize.height(), 1)
- toBuffer: aRb.buf
+ sourceSize: MTLSizeMake(NSUInteger(srcSize.width()), NSUInteger(srcSize.height()), 1)
+ toBuffer: readback.buf
destinationOffset: 0
destinationBytesPerRow: bpl
destinationBytesPerImage: 0
options: MTLBlitOptionNone];
- d->activeReadbacks.append(aRb);
- } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::MipGen) {
- QMetalTexture *utexD = QRHI_RES(QMetalTexture, u.mipgen.tex);
+ d->activeTextureReadbacks.append(readback);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
+ QMetalTexture *utexD = QRHI_RES(QMetalTexture, u.dst);
ensureBlit();
[blitEnc generateMipmapsForTexture: utexD->d->tex];
utexD->lastActiveFrameSlot = currentFrameSlot;
@@ -1655,25 +1718,24 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
{
const int idx = bufD->d->slotted ? currentFrameSlot : 0;
- QVector<QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate> &updates(bufD->d->pendingUpdates[idx]);
- if (updates.isEmpty())
+ if (bufD->d->pendingUpdates[idx].isEmpty())
return;
void *p = [bufD->d->buf[idx] contents];
int changeBegin = -1;
int changeEnd = -1;
- for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->d->pendingUpdates[idx])) {
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
- memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), u.data.size());
+ memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
if (changeBegin == -1 || u.offset < changeBegin)
changeBegin = u.offset;
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
changeEnd = u.offset + u.data.size();
}
if (changeBegin >= 0 && bufD->d->managed)
- [bufD->d->buf[idx] didModifyRange: NSMakeRange(changeBegin, changeEnd - changeBegin)];
+ [bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
- updates.clear();
+ bufD->d->pendingUpdates[idx].clear();
}
void QRhiMetal::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
@@ -1728,21 +1790,22 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
rtD = rtTex->d;
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) {
- for (int i = 0; i < rtD->colorAttCount; ++i)
+ for (uint i = 0; i < uint(rtD->colorAttCount); ++i)
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
}
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
cbD->d->currentPassRpDesc.depthAttachment.loadAction = MTLLoadActionLoad;
cbD->d->currentPassRpDesc.stencilAttachment.loadAction = MTLLoadActionLoad;
}
- const QVector<QRhiColorAttachment> colorAttachments = rtTex->m_desc.colorAttachments();
- for (const QRhiColorAttachment &colorAttachment : colorAttachments) {
- if (colorAttachment.texture())
- QRHI_RES(QMetalTexture, colorAttachment.texture())->lastActiveFrameSlot = currentFrameSlot;
- else if (colorAttachment.renderBuffer())
- QRHI_RES(QMetalRenderBuffer, colorAttachment.renderBuffer())->lastActiveFrameSlot = currentFrameSlot;
- if (colorAttachment.resolveTexture())
- QRHI_RES(QMetalTexture, colorAttachment.resolveTexture())->lastActiveFrameSlot = currentFrameSlot;
+ for (auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments();
+ it != itEnd; ++it)
+ {
+ if (it->texture())
+ QRHI_RES(QMetalTexture, it->texture())->lastActiveFrameSlot = currentFrameSlot;
+ else if (it->renderBuffer())
+ QRHI_RES(QMetalRenderBuffer, it->renderBuffer())->lastActiveFrameSlot = currentFrameSlot;
+ if (it->resolveTexture())
+ QRHI_RES(QMetalTexture, it->resolveTexture())->lastActiveFrameSlot = currentFrameSlot;
}
if (rtTex->m_desc.depthStencilBuffer())
QRHI_RES(QMetalRenderBuffer, rtTex->m_desc.depthStencilBuffer())->lastActiveFrameSlot = currentFrameSlot;
@@ -1755,15 +1818,15 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
break;
}
- for (int i = 0; i < rtD->colorAttCount; ++i) {
+ for (uint i = 0; i < uint(rtD->colorAttCount); ++i) {
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
- cbD->d->currentPassRpDesc.colorAttachments[i].slice = rtD->fb.colorAtt[i].layer;
- cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level;
+ cbD->d->currentPassRpDesc.colorAttachments[i].slice = NSUInteger(rtD->fb.colorAtt[i].layer);
+ cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
if (rtD->fb.colorAtt[i].resolveTex) {
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
- cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = rtD->fb.colorAtt[i].resolveLayer;
- cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = rtD->fb.colorAtt[i].resolveLevel;
+ cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
+ cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = NSUInteger(rtD->fb.colorAtt[i].resolveLevel);
}
}
@@ -1845,7 +1908,7 @@ void QRhiMetal::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::ComputePass);
QMetalComputePipeline *psD = QRHI_RES(QMetalComputePipeline, cbD->currentComputePipeline);
- [cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(x, y, z)
+ [cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(NSUInteger(x), NSUInteger(y), NSUInteger(z))
threadsPerThreadgroup: psD->d->localSize];
}
@@ -1908,22 +1971,22 @@ void QRhiMetal::finishActiveReadbacks(bool forced)
QVarLengthArray<std::function<void()>, 4> completedCallbacks;
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (int i = d->activeReadbacks.count() - 1; i >= 0; --i) {
- const QRhiMetalData::ActiveReadback &aRb(d->activeReadbacks[i]);
- if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
- aRb.result->format = aRb.format;
- aRb.result->pixelSize = aRb.pixelSize;
- aRb.result->data.resize(aRb.bufSize);
- void *p = [aRb.buf contents];
- memcpy(aRb.result->data.data(), p, aRb.bufSize);
- [aRb.buf release];
+ for (int i = d->activeTextureReadbacks.count() - 1; i >= 0; --i) {
+ const QRhiMetalData::TextureReadback &readback(d->activeTextureReadbacks[i]);
+ if (forced || currentFrameSlot == readback.activeFrameSlot || readback.activeFrameSlot < 0) {
+ readback.result->format = readback.format;
+ readback.result->pixelSize = readback.pixelSize;
+ readback.result->data.resize(int(readback.bufSize));
+ void *p = [readback.buf contents];
+ memcpy(readback.result->data.data(), p, readback.bufSize);
+ [readback.buf release];
- QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.buf))));
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(readback.buf))));
- if (aRb.result->completed)
- completedCallbacks.append(aRb.result->completed);
+ if (readback.result->completed)
+ completedCallbacks.append(readback.result->completed);
- d->activeReadbacks.removeAt(i);
+ d->activeTextureReadbacks.removeAt(i);
}
}
@@ -1977,8 +2040,8 @@ bool QMetalBuffer::build()
return false;
}
- const int nonZeroSize = m_size <= 0 ? 256 : m_size;
- const int roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned(nonZeroSize, 256) : nonZeroSize;
+ const uint nonZeroSize = m_size <= 0 ? 256 : uint(m_size);
+ const uint roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned<uint>(nonZeroSize, 256) : nonZeroSize;
d->managed = false;
MTLResourceOptions opts = MTLResourceStorageModeShared;
@@ -1999,7 +2062,6 @@ bool QMetalBuffer::build()
for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) {
if (i == 0 || d->slotted) {
d->buf[i] = [rhiD->d->dev newBufferWithLength: roundedSize options: opts];
- d->pendingUpdates[i].reserve(16);
if (!m_objectName.isEmpty()) {
if (!d->slotted) {
d->buf[i].label = [NSString stringWithUTF8String: m_objectName.constData()];
@@ -2065,10 +2127,10 @@ bool QMetalRenderBuffer::build()
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
- desc.width = m_pixelSize.width();
- desc.height = m_pixelSize.height();
+ desc.width = NSUInteger(m_pixelSize.width());
+ desc.height = NSUInteger(m_pixelSize.height());
if (samples > 1)
- desc.sampleCount = samples;
+ desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget;
@@ -2335,11 +2397,11 @@ bool QMetalTexture::build()
else
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
desc.pixelFormat = d->format;
- desc.width = size.width();
- desc.height = size.height();
- desc.mipmapLevelCount = mipLevelCount;
+ desc.width = NSUInteger(size.width());
+ desc.height = NSUInteger(size.height());
+ desc.mipmapLevelCount = NSUInteger(mipLevelCount);
if (samples > 1)
- desc.sampleCount = samples;
+ desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate;
desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageShaderRead;
@@ -2405,7 +2467,7 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level)
const MTLTextureType type = [tex textureType];
const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap);
id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type
- levels: NSMakeRange(level, 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
+ levels: NSMakeRange(NSUInteger(level), 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
perLevelViews[level] = view;
return view;
@@ -2607,60 +2669,63 @@ void QMetalTextureRenderTarget::release()
QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDescriptor()
{
- const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
+ const int colorAttachmentCount = m_desc.cendColorAttachments() - m_desc.cbeginColorAttachments();
QMetalRenderPassDescriptor *rpD = new QMetalRenderPassDescriptor(m_rhi);
- rpD->colorAttachmentCount = colorAttachments.count();
+ rpD->colorAttachmentCount = colorAttachmentCount;
rpD->hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();
- for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) {
- QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
- QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer());
- rpD->colorFormat[i] = texD ? texD->d->format : rbD->d->format;
+ for (int i = 0; i < colorAttachmentCount; ++i) {
+ const QRhiColorAttachment *colorAtt = m_desc.colorAttachmentAt(i);
+ QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAtt->texture());
+ QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAtt->renderBuffer());
+ rpD->colorFormat[i] = int(texD ? texD->d->format : rbD->d->format);
}
if (m_desc.depthTexture())
- rpD->dsFormat = QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format;
+ rpD->dsFormat = int(QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format);
else if (m_desc.depthStencilBuffer())
- rpD->dsFormat = QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format;
+ rpD->dsFormat = int(QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format);
return rpD;
}
bool QMetalTextureRenderTarget::build()
{
- const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
- Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture());
+ const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments();
+ Q_ASSERT(hasColorAttachments || m_desc.depthTexture());
Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture());
const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();
- d->colorAttCount = colorAttachments.count();
- for (int i = 0; i < d->colorAttCount; ++i) {
- QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
- QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer());
+ d->colorAttCount = 0;
+ int attIndex = 0;
+ for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
+ d->colorAttCount += 1;
+ QMetalTexture *texD = QRHI_RES(QMetalTexture, it->texture());
+ QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, it->renderBuffer());
Q_ASSERT(texD || rbD);
id<MTLTexture> dst = nil;
if (texD) {
dst = texD->d->tex;
- if (i == 0) {
+ if (attIndex == 0) {
d->pixelSize = texD->pixelSize();
d->sampleCount = texD->samples;
}
} else if (rbD) {
dst = rbD->d->tex;
- if (i == 0) {
+ if (attIndex == 0) {
d->pixelSize = rbD->pixelSize();
d->sampleCount = rbD->samples;
}
}
QMetalRenderTargetData::ColorAtt colorAtt;
colorAtt.tex = dst;
- colorAtt.layer = colorAttachments[i].layer();
- colorAtt.level = colorAttachments[i].level();
- QMetalTexture *resTexD = QRHI_RES(QMetalTexture, colorAttachments[i].resolveTexture());
+ colorAtt.layer = it->layer();
+ colorAtt.level = it->level();
+ QMetalTexture *resTexD = QRHI_RES(QMetalTexture, it->resolveTexture());
colorAtt.resolveTex = resTexD ? resTexD->d->tex : nil;
- colorAtt.resolveLayer = colorAttachments[i].resolveLayer();
- colorAtt.resolveLevel = colorAttachments[i].resolveLevel();
- d->fb.colorAtt[i] = colorAtt;
+ colorAtt.resolveLayer = it->resolveLayer();
+ colorAtt.resolveLevel = it->resolveLevel();
+ d->fb.colorAtt[attIndex] = colorAtt;
}
d->dpr = 1;
@@ -2728,21 +2793,21 @@ bool QMetalShaderResourceBindings::build()
if (!sortedBindings.isEmpty())
release();
- sortedBindings = m_bindings;
+ std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
std::sort(sortedBindings.begin(), sortedBindings.end(),
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
{
- return QRhiShaderResourceBindingPrivate::get(&a)->binding < QRhiShaderResourceBindingPrivate::get(&b)->binding;
+ return a.data()->binding < b.data()->binding;
});
if (!sortedBindings.isEmpty())
- maxBinding = QRhiShaderResourceBindingPrivate::get(&sortedBindings.last())->binding;
+ maxBinding = sortedBindings.last().data()->binding;
else
maxBinding = -1;
boundResourceData.resize(sortedBindings.count());
for (int i = 0, ie = sortedBindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&sortedBindings[i]);
+ const QRhiShaderResourceBinding::Data *b = sortedBindings.at(i).data();
QMetalShaderResourceBindings::BoundResourceData &bd(boundResourceData[i]);
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
@@ -2810,36 +2875,17 @@ void QMetalGraphicsPipeline::release()
{
QRHI_RES_RHI(QRhiMetal);
- if (!d->ps)
- return;
-
- if (d->ps) {
- [d->ps release];
- d->ps = nil;
- }
+ d->vs.release();
+ d->fs.release();
- if (d->ds) {
- [d->ds release];
- d->ds = nil;
- }
+ [d->ds release];
+ d->ds = nil;
- if (d->vsFunc) {
- [d->vsFunc release];
- d->vsFunc = nil;
- }
- if (d->vsLib) {
- [d->vsLib release];
- d->vsLib = nil;
- }
+ if (!d->ps)
+ return;
- if (d->fsFunc) {
- [d->fsFunc release];
- d->fsFunc = nil;
- }
- if (d->fsLib) {
- [d->fsLib release];
- d->fsLib = nil;
- }
+ [d->ps release];
+ d->ps = nil;
rhiD->unregisterResource(this);
}
@@ -3040,7 +3086,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
if (!mtllib.shader().isEmpty()) {
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
- mtllib.shader().size(),
+ size_t(mtllib.shader().size()),
dispatch_get_global_queue(0, 0),
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
NSError *err = nil;
@@ -3093,27 +3139,31 @@ bool QMetalGraphicsPipeline::build()
release();
QRHI_RES_RHI(QRhiMetal);
+ if (!rhiD->sanityCheckGraphicsPipeline(this))
+ return false;
// same binding space for vertex and constant buffers - work it around
const int firstVertexBinding = QRHI_RES(QMetalShaderResourceBindings, m_shaderResourceBindings)->maxBinding + 1;
MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
- const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
- for (const QRhiVertexInputAttribute &attribute : attributes) {
- const int loc = attribute.location();
- inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format());
- inputLayout.attributes[loc].offset = attribute.offset();
- inputLayout.attributes[loc].bufferIndex = firstVertexBinding + attribute.binding();
- }
- const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
- for (int i = 0, ie = bindings.count(); i != ie; ++i) {
- const QRhiVertexInputBinding &binding(bindings[i]);
- const int layoutIdx = firstVertexBinding + i;
+ for (auto it = m_vertexInputLayout.cbeginAttributes(), itEnd = m_vertexInputLayout.cendAttributes();
+ it != itEnd; ++it)
+ {
+ const uint loc = uint(it->location());
+ inputLayout.attributes[loc].format = toMetalAttributeFormat(it->format());
+ inputLayout.attributes[loc].offset = NSUInteger(it->offset());
+ inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + it->binding());
+ }
+ int bindingIndex = 0;
+ for (auto it = m_vertexInputLayout.cbeginBindings(), itEnd = m_vertexInputLayout.cendBindings();
+ it != itEnd; ++it, ++bindingIndex)
+ {
+ const uint layoutIdx = uint(firstVertexBinding + bindingIndex);
inputLayout.layouts[layoutIdx].stepFunction =
- binding.classification() == QRhiVertexInputBinding::PerInstance
+ it->classification() == QRhiVertexInputBinding::PerInstance
? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
- inputLayout.layouts[layoutIdx].stepRate = binding.instanceStepRate();
- inputLayout.layouts[layoutIdx].stride = binding.stride();
+ inputLayout.layouts[layoutIdx].stepRate = NSUInteger(it->instanceStepRate());
+ inputLayout.layouts[layoutIdx].stride = it->stride();
}
MTLRenderPipelineDescriptor *rpDesc = [[MTLRenderPipelineDescriptor alloc] init];
@@ -3126,34 +3176,66 @@ bool QMetalGraphicsPipeline::build()
// buffers not just the resource binding layout) so leave it at the default
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
- QString error;
- QByteArray entryPoint;
- id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
- if (!lib) {
- qWarning("MSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
- if (!func) {
- qWarning("MSL function for entry point %s not found", entryPoint.constData());
- [lib release];
- return false;
- }
- switch (shaderStage.type()) {
- case QRhiShaderStage::Vertex:
- rpDesc.vertexFunction = func;
- d->vsLib = lib;
- d->vsFunc = func;
- break;
- case QRhiShaderStage::Fragment:
- rpDesc.fragmentFunction = func;
- d->fsLib = lib;
- d->fsFunc = func;
- break;
- default:
- [func release];
- [lib release];
- break;
+ auto cacheIt = rhiD->d->shaderCache.constFind(shaderStage);
+ if (cacheIt != rhiD->d->shaderCache.constEnd()) {
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ d->vs = *cacheIt;
+ [d->vs.lib retain];
+ [d->vs.func retain];
+ rpDesc.vertexFunction = d->vs.func;
+ break;
+ case QRhiShaderStage::Fragment:
+ d->fs = *cacheIt;
+ [d->fs.lib retain];
+ [d->fs.func retain];
+ rpDesc.fragmentFunction = d->fs.func;
+ break;
+ default:
+ break;
+ }
+ } else {
+ QString error;
+ QByteArray entryPoint;
+ id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
+ if (!lib) {
+ qWarning("MSL shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
+ id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
+ if (!func) {
+ qWarning("MSL function for entry point %s not found", entryPoint.constData());
+ [lib release];
+ return false;
+ }
+ if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ for (QMetalShader &s : rhiD->d->shaderCache)
+ s.release();
+ rhiD->d->shaderCache.clear();
+ }
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ d->vs.lib = lib;
+ d->vs.func = func;
+ rhiD->d->shaderCache.insert(shaderStage, d->vs);
+ [d->vs.lib retain];
+ [d->vs.func retain];
+ rpDesc.vertexFunction = func;
+ break;
+ case QRhiShaderStage::Fragment:
+ d->fs.lib = lib;
+ d->fs.func = func;
+ rhiD->d->shaderCache.insert(shaderStage, d->fs);
+ [d->fs.lib retain];
+ [d->fs.func retain];
+ rpDesc.fragmentFunction = func;
+ break;
+ default:
+ [func release];
+ [lib release];
+ break;
+ }
}
}
@@ -3168,8 +3250,8 @@ bool QMetalGraphicsPipeline::build()
Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount
|| (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1));
- for (int i = 0, ie = m_targetBlends.count(); i != ie; ++i) {
- const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[i]);
+ for (uint i = 0, ie = uint(m_targetBlends.count()); i != ie; ++i) {
+ const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[int(i)]);
rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]);
rpDesc.colorAttachments[i].blendingEnabled = b.enable;
rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor);
@@ -3191,7 +3273,7 @@ bool QMetalGraphicsPipeline::build()
rpDesc.stencilAttachmentPixelFormat = fmt;
}
- rpDesc.sampleCount = rhiD->effectiveSampleCount(m_sampleCount);
+ rpDesc.sampleCount = NSUInteger(rhiD->effectiveSampleCount(m_sampleCount));
NSError *err = nil;
d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
@@ -3253,22 +3335,13 @@ void QMetalComputePipeline::release()
{
QRHI_RES_RHI(QRhiMetal);
- if (d->csFunc) {
- [d->csFunc release];
- d->csFunc = nil;
- }
- if (d->csLib) {
- [d->csLib release];
- d->csLib = nil;
- }
+ d->cs.release();
if (!d->ps)
return;
- if (d->ps) {
- [d->ps release];
- d->ps = nil;
- }
+ [d->ps release];
+ d->ps = nil;
rhiD->unregisterResource(this);
}
@@ -3280,28 +3353,44 @@ bool QMetalComputePipeline::build()
QRHI_RES_RHI(QRhiMetal);
- const QShader shader = m_shaderStage.shader();
- QString error;
- QByteArray entryPoint;
- id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
- &error, &entryPoint);
- if (!lib) {
- qWarning("MSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
- if (!func) {
- qWarning("MSL function for entry point %s not found", entryPoint.constData());
- [lib release];
- return false;
+ auto cacheIt = rhiD->d->shaderCache.constFind(m_shaderStage);
+ if (cacheIt != rhiD->d->shaderCache.constEnd()) {
+ d->cs = *cacheIt;
+ } else {
+ const QShader shader = m_shaderStage.shader();
+ QString error;
+ QByteArray entryPoint;
+ id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
+ &error, &entryPoint);
+ if (!lib) {
+ qWarning("MSL shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
+ id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
+ if (!func) {
+ qWarning("MSL function for entry point %s not found", entryPoint.constData());
+ [lib release];
+ return false;
+ }
+ d->cs.lib = lib;
+ d->cs.func = func;
+ d->cs.localSize = shader.description().computeShaderLocalSize();
+
+ if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
+ for (QMetalShader &s : rhiD->d->shaderCache)
+ s.release();
+ rhiD->d->shaderCache.clear();
+ }
+ rhiD->d->shaderCache.insert(m_shaderStage, d->cs);
}
- d->csLib = lib;
- d->csFunc = func;
- std::array<uint, 3> localSize = shader.description().computeShaderLocalSize();
- d->localSize = MTLSizeMake(localSize[0], localSize[1], localSize[2]);
+
+ [d->cs.lib retain];
+ [d->cs.func retain];
+
+ d->localSize = MTLSizeMake(d->cs.localSize[0], d->cs.localSize[1], d->cs.localSize[2]);
NSError *err = nil;
- d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->csFunc error: &err];
+ d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->cs.func error: &err];
if (!d->ps) {
const QString msg = QString::fromNSString(err.localizedDescription);
qWarning("Failed to create render pipeline state: %s", qPrintable(msg));
@@ -3364,6 +3453,10 @@ void QMetalCommandBuffer::resetPerPassCachedState()
currentSrbGeneration = 0;
currentResSlot = -1;
currentIndexBuffer = nullptr;
+ currentIndexOffset = 0;
+ currentIndexFormat = QRhiCommandBuffer::IndexUInt16;
+ currentCullMode = -1;
+ currentFrontFaceWinding = -1;
d->currentFirstVertexBinding = -1;
d->currentVertexInputsBuffers.clear();
@@ -3432,17 +3525,8 @@ QRhiRenderTarget *QMetalSwapChain::currentFrameRenderTarget()
QSize QMetalSwapChain::surfacePixelSize()
{
- // may be called before build, must not access other than m_*
-
- NSView *v = (NSView *) m_window->winId();
- if (v) {
- CAMetalLayer *layer = (CAMetalLayer *) [v layer];
- if (layer) {
- CGSize size = [layer drawableSize];
- return QSize(size.width, size.height);
- }
- }
- return QSize();
+ Q_ASSERT(m_window);
+ return m_window->size() * m_window->devicePixelRatio();
}
QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
@@ -3454,7 +3538,7 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
rpD->colorAttachmentCount = 1;
rpD->hasDepthStencil = m_depthStencil != nullptr;
- rpD->colorFormat[0] = d->colorFormat;
+ rpD->colorFormat[0] = int(d->colorFormat);
// m_depthStencil may not be built yet so cannot rely on computed fields in it
rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported
@@ -3493,8 +3577,9 @@ bool QMetalSwapChain::buildOrResize()
return false;
}
- NSView *v = (NSView *) window->winId();
- d->layer = (CAMetalLayer *) [v layer];
+ NSView *view = reinterpret_cast<NSView *>(window->winId());
+ Q_ASSERT(view);
+ d->layer = static_cast<CAMetalLayer *>(view.layer);
Q_ASSERT(d->layer);
chooseFormats();
@@ -3511,7 +3596,27 @@ bool QMetalSwapChain::buildOrResize()
}
#endif
- m_currentPixelSize = surfacePixelSize();
+ if (m_flags.testFlag(SurfaceHasPreMulAlpha)) {
+ d->layer.opaque = NO;
+ } else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
+ // The CoreAnimation compositor is said to expect premultiplied alpha,
+ // so this is then wrong when it comes to the blending operations but
+ // there's nothing we can do. Fortunately Qt Quick always outputs
+ // premultiplied alpha so it is not a problem there.
+ d->layer.opaque = NO;
+ } else {
+ d->layer.opaque = YES;
+ }
+
+ // Now set the layer's drawableSize which will stay set to the same value
+ // until the next buildOrResize(), thus ensuring atomicity with regards to
+ // the drawable size in frames.
+ CGSize layerSize = d->layer.bounds.size;
+ layerSize.width *= d->layer.contentsScale;
+ layerSize.height *= d->layer.contentsScale;
+ d->layer.drawableSize = layerSize;
+
+ m_currentPixelSize = QSizeF::fromCGSize(layerSize).toSize();
pixelSize = m_currentPixelSize;
[d->layer setDevice: rhiD->d->dev];
@@ -3532,13 +3637,20 @@ bool QMetalSwapChain::buildOrResize()
m_depthStencil->sampleCount(), m_sampleCount);
}
if (m_depthStencil && m_depthStencil->pixelSize() != pixelSize) {
- qWarning("Depth-stencil buffer's size (%dx%d) does not match the layer size (%dx%d). Expect problems.",
- m_depthStencil->pixelSize().width(), m_depthStencil->pixelSize().height(),
- pixelSize.width(), pixelSize.height());
+ if (m_depthStencil->flags().testFlag(QRhiRenderBuffer::UsedWithSwapChainOnly)) {
+ m_depthStencil->setPixelSize(pixelSize);
+ if (!m_depthStencil->build())
+ qWarning("Failed to rebuild swapchain's associated depth-stencil buffer for size %dx%d",
+ pixelSize.width(), pixelSize.height());
+ } else {
+ qWarning("Depth-stencil buffer's size (%dx%d) does not match the layer size (%dx%d). Expect problems.",
+ m_depthStencil->pixelSize().width(), m_depthStencil->pixelSize().height(),
+ pixelSize.width(), pixelSize.height());
+ }
}
rtWrapper.d->pixelSize = pixelSize;
- rtWrapper.d->dpr = window->devicePixelRatio();
+ rtWrapper.d->dpr = float(window->devicePixelRatio());
rtWrapper.d->sampleCount = samples;
rtWrapper.d->colorAttCount = 1;
rtWrapper.d->dsAttCount = ds ? 1 : 0;
@@ -3549,9 +3661,9 @@ bool QMetalSwapChain::buildOrResize()
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.textureType = MTLTextureType2DMultisample;
desc.pixelFormat = d->colorFormat;
- desc.width = pixelSize.width();
- desc.height = pixelSize.height();
- desc.sampleCount = samples;
+ desc.width = NSUInteger(pixelSize.width());
+ desc.height = NSUInteger(pixelSize.height());
+ desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate;
desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget;
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index c448865f4d..688fec8147 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -188,7 +188,7 @@ struct QMetalShaderResourceBindings : public QRhiShaderResourceBindings
void release() override;
bool build() override;
- QVector<QRhiShaderResourceBinding> sortedBindings;
+ QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
int maxBinding = -1;
struct BoundUniformBufferData {
@@ -217,7 +217,7 @@ struct QMetalShaderResourceBindings : public QRhiShaderResourceBindings
BoundStorageBufferData sbuf;
};
};
- QVector<BoundResourceData> boundResourceData;
+ QVarLengthArray<BoundResourceData, 8> boundResourceData;
uint generation = 0;
friend class QRhiMetal;
@@ -271,8 +271,11 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
ComputePass
};
+ // per-pass (render or compute command encoder) persistent state
PassType recordingPass;
QRhiRenderTarget *currentTarget;
+
+ // per-pass (render or compute command encoder) volatile (cached) state
QRhiGraphicsPipeline *currentGraphicsPipeline;
QRhiComputePipeline *currentComputePipeline;
uint currentPipelineGeneration;
@@ -283,6 +286,8 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
QRhiBuffer *currentIndexBuffer;
quint32 currentIndexOffset;
QRhiCommandBuffer::IndexFormat currentIndexFormat;
+ int currentCullMode;
+ int currentFrontFaceWinding;
const QRhiNativeHandles *nativeHandles();
void resetState();
@@ -416,7 +421,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
void executeDeferredReleases(bool forced = false);
void finishActiveReadbacks(bool forced = false);
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index dff6e05268..fe606f971f 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -36,6 +36,7 @@
#include "qrhinull_p_p.h"
#include <qmath.h>
+#include <QPainter>
QT_BEGIN_NAMESPACE
@@ -169,11 +170,22 @@ void QRhiNull::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiNull::makeThreadLocalNativeContextCurrent()
+bool QRhiNull::makeThreadLocalNativeContextCurrent()
+{
+ // not applicable
+ return false;
+}
+
+void QRhiNull::releaseCachedResources()
{
// nothing to do here
}
+bool QRhiNull::isDeviceLost() const
+{
+ return false;
+}
+
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
@@ -374,27 +386,125 @@ QRhi::FrameOpResult QRhiNull::finish()
return QRhi::FrameOpSuccess;
}
+void QRhiNull::simulateTextureUpload(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
+{
+ QNullTexture *texD = QRHI_RES(QNullTexture, u.dst);
+ for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
+ for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
+ for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) {
+ if (!subresDesc.image().isNull()) {
+ const QImage src = subresDesc.image();
+ QPainter painter(&texD->image[layer][level]);
+ const QSize srcSize = subresDesc.sourceSize().isEmpty()
+ ? src.size() : subresDesc.sourceSize();
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.drawImage(subresDesc.destinationTopLeft(), src,
+ QRect(subresDesc.sourceTopLeft(), srcSize));
+ } else if (!subresDesc.data().isEmpty()) {
+ const QSize subresSize = q->sizeForMipLevel(level, texD->pixelSize());
+ int w = subresSize.width();
+ int h = subresSize.height();
+ if (!subresDesc.sourceSize().isEmpty()) {
+ w = subresDesc.sourceSize().width();
+ h = subresDesc.sourceSize().height();
+ }
+ // sourceTopLeft is not supported on this path as per QRhi docs
+ const char *src = subresDesc.data().constData();
+ const int srcBpl = w * 4;
+ const QPoint dstOffset = subresDesc.destinationTopLeft();
+ uchar *dst = texD->image[layer][level].bits();
+ const int dstBpl = texD->image[layer][level].bytesPerLine();
+ for (int y = 0; y < h; ++y) {
+ memcpy(dst + dstOffset.x() * 4 + (y + dstOffset.y()) * dstBpl,
+ src + y * srcBpl,
+ size_t(srcBpl));
+ }
+ }
+ }
+ }
+ }
+}
+
+void QRhiNull::simulateTextureCopy(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
+{
+ QNullTexture *srcD = QRHI_RES(QNullTexture, u.src);
+ QNullTexture *dstD = QRHI_RES(QNullTexture, u.dst);
+ const QImage &srcImage(srcD->image[u.desc.sourceLayer()][u.desc.sourceLevel()]);
+ QImage &dstImage(dstD->image[u.desc.destinationLayer()][u.desc.destinationLevel()]);
+ const QPoint dstPos = u.desc.destinationTopLeft();
+ const QSize size = u.desc.pixelSize().isEmpty() ? srcD->pixelSize() : u.desc.pixelSize();
+ const QPoint srcPos = u.desc.sourceTopLeft();
+
+ QPainter painter(&dstImage);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.drawImage(QRect(dstPos, size), srcImage, QRect(srcPos, size));
+}
+
+void QRhiNull::simulateTextureGenMips(const QRhiResourceUpdateBatchPrivate::TextureOp &u)
+{
+ QNullTexture *texD = QRHI_RES(QNullTexture, u.dst);
+ const QSize baseSize = texD->pixelSize();
+ const int levelCount = q->mipLevelsForSize(baseSize);
+ for (int level = 1; level < levelCount; ++level)
+ texD->image[0][level] = texD->image[0][0].scaled(q->sizeForMipLevel(level, baseSize));
+}
+
void QRhiNull::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
{
Q_UNUSED(cb);
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate
+ || u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload)
+ {
+ QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
+ memcpy(bufD->data.data() + u.offset, u.data.constData(), size_t(u.data.size()));
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
+ QRhiBufferReadbackResult *result = u.result;
+ result->data.resize(u.readSize);
+ QNullBuffer *bufD = QRHI_RES(QNullBuffer, u.buf);
+ memcpy(result->data.data(), bufD->data.constData() + u.offset, size_t(u.readSize));
+ if (result->completed)
+ result->completed();
+ }
+ }
for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
- if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
- QRhiReadbackResult *result = u.read.result;
- QRhiTexture *tex = u.read.rb.texture();
- if (tex) {
- result->format = tex->format();
- result->pixelSize = q->sizeForMipLevel(u.read.rb.level(), tex->pixelSize());
+ if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
+ if (u.dst->format() == QRhiTexture::RGBA8)
+ simulateTextureUpload(u);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Copy) {
+ if (u.src->format() == QRhiTexture::RGBA8 && u.dst->format() == QRhiTexture::RGBA8)
+ simulateTextureCopy(u);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
+ QRhiReadbackResult *result = u.result;
+ QNullTexture *texD = QRHI_RES(QNullTexture, u.rb.texture());
+ if (texD) {
+ result->format = texD->format();
+ result->pixelSize = q->sizeForMipLevel(u.rb.level(), texD->pixelSize());
} else {
Q_ASSERT(currentSwapChain);
result->format = QRhiTexture::RGBA8;
result->pixelSize = currentSwapChain->currentPixelSize();
}
+ quint32 bytesPerLine = 0;
quint32 byteSize = 0;
- textureFormatInfo(result->format, result->pixelSize, nullptr, &byteSize);
- result->data.fill(0, byteSize);
+ textureFormatInfo(result->format, result->pixelSize, &bytesPerLine, &byteSize);
+ if (texD && texD->format() == QRhiTexture::RGBA8) {
+ result->data.resize(int(byteSize));
+ const QImage &src(texD->image[u.rb.layer()][u.rb.level()]);
+ char *dst = result->data.data();
+ for (int y = 0, h = src.height(); y < h; ++y) {
+ memcpy(dst, src.constScanLine(y), bytesPerLine);
+ dst += bytesPerLine;
+ }
+ } else {
+ result->data.fill(0, int(byteSize));
+ }
if (result->completed)
result->completed();
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
+ if (u.dst->format() == QRhiTexture::RGBA8)
+ simulateTextureGenMips(u);
}
}
ud->free();
@@ -443,14 +553,18 @@ QNullBuffer::~QNullBuffer()
void QNullBuffer::release()
{
+ data.clear();
+
QRHI_PROF;
QRHI_PROF_F(releaseBuffer(this));
}
bool QNullBuffer::build()
{
+ data.fill('\0', m_size);
+
QRHI_PROF;
- QRHI_PROF_F(newBuffer(this, m_size, 1, 0));
+ QRHI_PROF_F(newBuffer(this, uint(m_size), 1, 0));
return true;
}
@@ -502,22 +616,36 @@ void QNullTexture::release()
bool QNullTexture::build()
{
+ QRHI_RES_RHI(QRhiNull);
const bool isCube = m_flags.testFlag(CubeMap);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize;
- const int mipLevelCount = hasMipMaps ? qCeil(log2(qMax(size.width(), size.height()))) + 1 : 1;
+ const int mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
+ const int layerCount = isCube ? 6 : 1;
+
+ if (m_format == RGBA8) {
+ for (int layer = 0; layer < layerCount; ++layer) {
+ for (int level = 0; level < mipLevelCount; ++level) {
+ image[layer][level] = QImage(rhiD->q->sizeForMipLevel(level, size),
+ QImage::Format_RGBA8888_Premultiplied);
+ image[layer][level].fill(Qt::yellow);
+ }
+ }
+ }
+
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, 1));
+ QRHI_PROF_F(newTexture(this, true, mipLevelCount, layerCount, 1));
return true;
}
bool QNullTexture::buildFrom(const QRhiNativeHandles *src)
{
Q_UNUSED(src);
+ QRHI_RES_RHI(QRhiNull);
const bool isCube = m_flags.testFlag(CubeMap);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize;
- const int mipLevelCount = hasMipMaps ? qCeil(log2(qMax(size.width(), size.height()))) + 1 : 1;
+ const int mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
QRHI_PROF;
QRHI_PROF_F(newTexture(this, false, mipLevelCount, isCube ? 6 : 1, 1));
return true;
@@ -617,10 +745,9 @@ QRhiRenderPassDescriptor *QNullTextureRenderTarget::newCompatibleRenderPassDescr
bool QNullTextureRenderTarget::build()
{
d.rp = QRHI_RES(QNullRenderPassDescriptor, m_renderPassDesc);
- const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
- if (!colorAttachments.isEmpty()) {
- QRhiTexture *tex = colorAttachments.first().texture();
- QRhiRenderBuffer *rb = colorAttachments.first().renderBuffer();
+ if (m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments()) {
+ QRhiTexture *tex = m_desc.cbeginColorAttachments()->texture();
+ QRhiRenderBuffer *rb = m_desc.cbeginColorAttachments()->renderBuffer();
d.pixelSize = tex ? tex->pixelSize() : rb->pixelSize();
} else if (m_desc.depthStencilBuffer()) {
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
@@ -680,6 +807,10 @@ void QNullGraphicsPipeline::release()
bool QNullGraphicsPipeline::build()
{
+ QRHI_RES_RHI(QRhiNull);
+ if (!rhiD->sanityCheckGraphicsPipeline(this))
+ return false;
+
return true;
}
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index bdf0d59724..ce517bfa63 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -59,6 +59,8 @@ struct QNullBuffer : public QRhiBuffer
~QNullBuffer();
void release() override;
bool build() override;
+
+ QByteArray data;
};
struct QNullRenderBuffer : public QRhiRenderBuffer
@@ -82,6 +84,7 @@ struct QNullTexture : public QRhiTexture
const QRhiNativeHandles *nativeHandles() override;
QRhiNullTextureNativeHandles nativeHandlesStruct;
+ QImage image[QRhi::MAX_LAYERS][QRhi::MAX_LEVELS];
};
struct QNullSampler : public QRhiSampler
@@ -282,7 +285,13 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
+
+ void simulateTextureUpload(const QRhiResourceUpdateBatchPrivate::TextureOp &u);
+ void simulateTextureCopy(const QRhiResourceUpdateBatchPrivate::TextureOp &u);
+ void simulateTextureGenMips(const QRhiResourceUpdateBatchPrivate::TextureOp &u);
QRhiNullNativeHandles nativeHandlesStruct;
QRhiSwapChain *currentSwapChain = nullptr;
diff --git a/src/gui/rhi/qrhiprofiler.cpp b/src/gui/rhi/qrhiprofiler.cpp
index e74e446a1c..1521c0f36e 100644
--- a/src/gui/rhi/qrhiprofiler.cpp
+++ b/src/gui/rhi/qrhiprofiler.cpp
@@ -319,7 +319,7 @@ void QRhiProfilerPrivate::writeFloat(const char *key, float f)
Q_ASSERT(key[0] == 'F');
buf.append(key);
buf.append(',');
- buf.append(QByteArray::number(f));
+ buf.append(QByteArray::number(double(f)));
buf.append(',');
}
@@ -385,7 +385,7 @@ void QRhiProfilerPrivate::newRenderBuffer(QRhiRenderBuffer *rb, bool transientBa
const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8;
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1);
if (sampleCount > 1)
- byteSize *= sampleCount;
+ byteSize *= uint(sampleCount);
startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb);
writeInt("type", type);
@@ -416,7 +416,7 @@ void QRhiProfilerPrivate::newTexture(QRhiTexture *tex, bool owns, int mipCount,
const QSize sz = tex->pixelSize();
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount);
if (sampleCount > 1)
- byteSize *= sampleCount;
+ byteSize *= uint(sampleCount);
startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex);
writeInt("width", sz.width());
@@ -467,7 +467,7 @@ void QRhiProfilerPrivate::resizeSwapChain(QRhiSwapChain *sc, int bufferCount, in
const QSize sz = sc->currentPixelSize();
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(QRhiTexture::BGRA8, sz, 1, 1);
- byteSize = byteSize * bufferCount + byteSize * msaaBufferCount * sampleCount;
+ byteSize = byteSize * uint(bufferCount) + byteSize * uint(msaaBufferCount) * uint(sampleCount);
startEntry(QRhiProfiler::ResizeSwapChain, ts.elapsed(), sc);
writeInt("width", sz.width());
@@ -569,7 +569,7 @@ void QRhiProfilerPrivate::swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTime
}
}
-void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size)
+void QRhiProfilerPrivate::newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size)
{
if (!outputDevice)
return;
@@ -580,7 +580,7 @@ void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint
endEntry();
}
-void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
+void QRhiProfilerPrivate::releaseReadbackBuffer(qint64 id)
{
if (!outputDevice)
return;
@@ -590,7 +590,7 @@ void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
endEntry();
}
-void QRhiProfilerPrivate::vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize)
+void QRhiProfilerPrivate::vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize)
{
if (!outputDevice)
return;
diff --git a/src/gui/rhi/qrhiprofiler_p_p.h b/src/gui/rhi/qrhiprofiler_p_p.h
index 49c6bd78ed..7d0f183fb1 100644
--- a/src/gui/rhi/qrhiprofiler_p_p.h
+++ b/src/gui/rhi/qrhiprofiler_p_p.h
@@ -79,10 +79,10 @@ public:
void endSwapChainFrame(QRhiSwapChain *sc, int frameCount);
void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs);
- void newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size);
- void releaseReadbackBuffer(quint64 id);
+ void newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size);
+ void releaseReadbackBuffer(qint64 id);
- void vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize);
+ void vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize);
void startEntry(QRhiProfiler::StreamOp op, qint64 timestamp, QRhiResource *res);
void writeInt(const char *key, qint64 v);
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index dfc85fb853..2d69abb36b 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -211,7 +211,8 @@ QT_BEGIN_NAMESPACE
\brief Holds the Vulkan render pass object backing a QRhiRenderPassDescriptor.
*/
-static inline VkDeviceSize aligned(VkDeviceSize v, VkDeviceSize byteAlign)
+template <class Int>
+inline Int aligned(Int v, Int byteAlign)
{
return (v + byteAlign - 1) & ~(byteAlign - 1);
}
@@ -362,6 +363,11 @@ bool QRhiVulkan::create(QRhi::Flags flags)
Q_UNUSED(flags);
Q_ASSERT(inst);
+ if (!inst->isValid()) {
+ qWarning("Vulkan instance is not valid");
+ return false;
+ }
+
globalVulkanInstance = inst; // assume this will not change during the lifetime of the entire application
f = inst->functions();
@@ -370,7 +376,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
auto queryQueueFamilyProps = [this, &queueFamilyProps] {
uint32_t queueCount = 0;
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
- queueFamilyProps.resize(queueCount);
+ queueFamilyProps.resize(int(queueCount));
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueFamilyProps.data());
};
@@ -387,22 +393,42 @@ bool QRhiVulkan::create(QRhi::Flags flags)
qWarning("Failed to enumerate physical devices: %d", err);
return false;
}
+
int physDevIndex = -1;
int requestedPhysDevIndex = -1;
if (qEnvironmentVariableIsSet("QT_VK_PHYSICAL_DEVICE_INDEX"))
requestedPhysDevIndex = qEnvironmentVariableIntValue("QT_VK_PHYSICAL_DEVICE_INDEX");
- for (uint32_t i = 0; i < physDevCount; ++i) {
+
+ if (requestedPhysDevIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) {
+ for (int i = 0; i < int(physDevCount); ++i) {
+ f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties);
+ if (physDevProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+ requestedPhysDevIndex = i;
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < int(physDevCount); ++i) {
f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties);
- qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d", i,
+ qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d (api %d.%d.%d vendor 0x%X device 0x%X type %d)",
+ i,
physDevProperties.deviceName,
VK_VERSION_MAJOR(physDevProperties.driverVersion),
VK_VERSION_MINOR(physDevProperties.driverVersion),
- VK_VERSION_PATCH(physDevProperties.driverVersion));
+ VK_VERSION_PATCH(physDevProperties.driverVersion),
+ VK_VERSION_MAJOR(physDevProperties.apiVersion),
+ VK_VERSION_MINOR(physDevProperties.apiVersion),
+ VK_VERSION_PATCH(physDevProperties.apiVersion),
+ physDevProperties.vendorID,
+ physDevProperties.deviceID,
+ physDevProperties.deviceType);
if (physDevIndex < 0 && (requestedPhysDevIndex < 0 || requestedPhysDevIndex == int(i))) {
physDevIndex = i;
qCDebug(QRHI_LOG_INFO, " using this physical device");
}
}
+
if (physDevIndex < 0) {
qWarning("No matching physical device");
return false;
@@ -423,7 +449,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
i, queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount);
if (gfxQueueFamilyIdx == -1
&& (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
- && (!maybeWindow || inst->supportsPresent(physDev, i, maybeWindow)))
+ && (!maybeWindow || inst->supportsPresent(physDev, uint32_t(i), maybeWindow)))
{
if (queueFamilyProps[i].queueFlags & VK_QUEUE_COMPUTE_BIT)
gfxQueueFamilyIdx = i;
@@ -444,7 +470,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
const float prio[] = { 0 };
memset(queueInfo, 0, sizeof(queueInfo));
queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queueInfo[0].queueFamilyIndex = gfxQueueFamilyIdx;
+ queueInfo[0].queueFamilyIndex = uint32_t(gfxQueueFamilyIdx);
queueInfo[0].queueCount = 1;
queueInfo[0].pQueuePriorities = prio;
@@ -480,9 +506,9 @@ bool QRhiVulkan::create(QRhi::Flags flags)
devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
devInfo.queueCreateInfoCount = 1;
devInfo.pQueueCreateInfos = queueInfo;
- devInfo.enabledLayerCount = devLayers.count();
+ devInfo.enabledLayerCount = uint32_t(devLayers.count());
devInfo.ppEnabledLayerNames = devLayers.constData();
- devInfo.enabledExtensionCount = requestedDevExts.count();
+ devInfo.enabledExtensionCount = uint32_t(requestedDevExts.count());
devInfo.ppEnabledExtensionNames = requestedDevExts.constData();
err = f->vkCreateDevice(physDev, &devInfo, nullptr, &dev);
@@ -498,7 +524,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
VkCommandPoolCreateInfo poolInfo;
memset(&poolInfo, 0, sizeof(poolInfo));
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- poolInfo.queueFamilyIndex = gfxQueueFamilyIdx;
+ poolInfo.queueFamilyIndex = uint32_t(gfxQueueFamilyIdx);
VkResult err = df->vkCreateCommandPool(dev, &poolInfo, nullptr, &cmdPool);
if (err != VK_SUCCESS) {
qWarning("Failed to create command pool: %d", err);
@@ -508,7 +534,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
if (gfxQueueFamilyIdx != -1) {
if (!gfxQueue)
- df->vkGetDeviceQueue(dev, gfxQueueFamilyIdx, 0, &gfxQueue);
+ df->vkGetDeviceQueue(dev, uint32_t(gfxQueueFamilyIdx), 0, &gfxQueue);
if (queueFamilyProps.isEmpty())
queryQueueFamilyProps();
@@ -547,6 +573,9 @@ bool QRhiVulkan::create(QRhi::Flags flags)
VmaAllocatorCreateInfo allocatorInfo;
memset(&allocatorInfo, 0, sizeof(allocatorInfo));
+ // A QRhi is supposed to be used from one single thread only. Disable
+ // the allocator's own mutexes. This gives a performance boost.
+ allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
allocatorInfo.physicalDevice = physDev;
allocatorInfo.device = dev;
allocatorInfo.pVulkanFunctions = &afuncs;
@@ -588,6 +617,8 @@ bool QRhiVulkan::create(QRhi::Flags flags)
vkDebugMarkerSetObjectName = reinterpret_cast<PFN_vkDebugMarkerSetObjectNameEXT>(f->vkGetDeviceProcAddr(dev, "vkDebugMarkerSetObjectNameEXT"));
}
+ deviceLost = false;
+
nativeHandlesStruct.physDev = physDev;
nativeHandlesStruct.dev = dev;
nativeHandlesStruct.gfxQueueFamilyIdx = gfxQueueFamilyIdx;
@@ -603,7 +634,8 @@ void QRhiVulkan::destroy()
if (!df)
return;
- df->vkDeviceWaitIdle(dev);
+ if (!deviceLost)
+ df->vkDeviceWaitIdle(dev);
executeDeferredReleases(true);
finishActiveReadbacks(true);
@@ -691,7 +723,7 @@ bool QRhiVulkan::allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, V
df->vkResetDescriptorPool(dev, descriptorPools[i].pool, 0);
descriptorPools[i].allocedDescSets = 0;
}
- if (descriptorPools[i].allocedDescSets + allocInfo->descriptorSetCount <= QVK_DESC_SETS_PER_POOL) {
+ if (descriptorPools[i].allocedDescSets + int(allocInfo->descriptorSetCount) <= QVK_DESC_SETS_PER_POOL) {
VkResult err = tryAllocate(i);
if (err == VK_SUCCESS) {
descriptorPools[i].allocedDescSets += allocInfo->descriptorSetCount;
@@ -901,8 +933,8 @@ bool QRhiVulkan::createTransientImage(VkFormat format,
imgInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imgInfo.imageType = VK_IMAGE_TYPE_2D;
imgInfo.format = format;
- imgInfo.extent.width = pixelSize.width();
- imgInfo.extent.height = pixelSize.height();
+ imgInfo.extent.width = uint32_t(pixelSize.width());
+ imgInfo.extent.height = uint32_t(pixelSize.height());
imgInfo.extent.depth = 1;
imgInfo.mipLevels = imgInfo.arrayLayers = 1;
imgInfo.samples = samples;
@@ -925,7 +957,7 @@ bool QRhiVulkan::createTransientImage(VkFormat format,
VkMemoryAllocateInfo memInfo;
memset(&memInfo, 0, sizeof(memInfo));
memInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- memInfo.allocationSize = aligned(memReq.size, memReq.alignment) * count;
+ memInfo.allocationSize = aligned(memReq.size, memReq.alignment) * VkDeviceSize(count);
uint32_t startIndex = 0;
do {
@@ -1087,7 +1119,8 @@ bool QRhiVulkan::createDefaultRenderPass(VkRenderPass *rp, bool hasDepthStencil,
}
bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
- const QVector<QRhiColorAttachment> &colorAttachments,
+ const QRhiColorAttachment *firstColorAttachment,
+ const QRhiColorAttachment *lastColorAttachment,
bool preserveColor,
bool preserveDs,
QRhiRenderBuffer *depthStencilBuffer,
@@ -1096,13 +1129,12 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
QVarLengthArray<VkAttachmentDescription, 8> attDescs;
QVarLengthArray<VkAttachmentReference, 8> colorRefs;
QVarLengthArray<VkAttachmentReference, 8> resolveRefs;
- const int colorAttCount = colorAttachments.count();
// attachment list layout is color (0-8), ds (0-1), resolve (0-8)
- for (int i = 0; i < colorAttCount; ++i) {
- QVkTexture *texD = QRHI_RES(QVkTexture, colorAttachments[i].texture());
- QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, colorAttachments[i].renderBuffer());
+ for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) {
+ QVkTexture *texD = QRHI_RES(QVkTexture, it->texture());
+ QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer());
Q_ASSERT(texD || rbD);
const VkFormat vkformat = texD ? texD->vkformat : rbD->vkformat;
const VkSampleCountFlagBits samples = texD ? texD->samples : rbD->samples;
@@ -1112,7 +1144,7 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
attDesc.format = vkformat;
attDesc.samples = samples;
attDesc.loadOp = preserveColor ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
- attDesc.storeOp = colorAttachments[i].resolveTexture() ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
+ attDesc.storeOp = it->resolveTexture() ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
// this has to interact correctly with activateTextureRenderTarget(), hence leaving in COLOR_ATT
@@ -1146,9 +1178,9 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
}
VkAttachmentReference dsRef = { uint32_t(attDescs.count() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
- for (int i = 0; i < colorAttCount; ++i) {
- if (colorAttachments[i].resolveTexture()) {
- QVkTexture *rtexD = QRHI_RES(QVkTexture, colorAttachments[i].resolveTexture());
+ for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) {
+ if (it->resolveTexture()) {
+ QVkTexture *rtexD = QRHI_RES(QVkTexture, it->resolveTexture());
if (rtexD->samples > VK_SAMPLE_COUNT_1_BIT)
qWarning("Resolving into a multisample texture is not supported");
@@ -1175,7 +1207,7 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
VkSubpassDescription subpassDesc;
memset(&subpassDesc, 0, sizeof(subpassDesc));
subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpassDesc.colorAttachmentCount = colorRefs.count();
+ subpassDesc.colorAttachmentCount = uint32_t(colorRefs.count());
Q_ASSERT(colorRefs.count() == resolveRefs.count());
subpassDesc.pColorAttachments = !colorRefs.isEmpty() ? colorRefs.constData() : nullptr;
subpassDesc.pDepthStencilAttachment = hasDepthStencil ? &dsRef : nullptr;
@@ -1184,7 +1216,7 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
VkRenderPassCreateInfo rpInfo;
memset(&rpInfo, 0, sizeof(rpInfo));
rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- rpInfo.attachmentCount = attDescs.count();
+ rpInfo.attachmentCount = uint32_t(attDescs.count());
rpInfo.pAttachments = attDescs.constData();
rpInfo.subpassCount = 1;
rpInfo.pSubpasses = &subpassDesc;
@@ -1325,7 +1357,7 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
}
if (actualSwapChainBufferCount != reqBufferCount)
qCDebug(QRHI_LOG_INFO, "Actual swapchain buffer count is %u", actualSwapChainBufferCount);
- swapChainD->bufferCount = actualSwapChainBufferCount;
+ swapChainD->bufferCount = int(actualSwapChainBufferCount);
VkImage swapChainImages[QVkSwapChain::MAX_BUFFER_COUNT];
err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, swapChainImages);
@@ -1424,7 +1456,8 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain)
if (swapChainD->sc == VK_NULL_HANDLE)
return;
- df->vkDeviceWaitIdle(dev);
+ if (!deviceLost)
+ df->vkDeviceWaitIdle(dev);
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) {
QVkSwapChain::FrameResources &frame(swapChainD->frameRes[i]);
@@ -1487,15 +1520,6 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain)
// NB! surface and similar must remain intact
}
-static inline bool checkDeviceLost(VkResult err)
-{
- if (err == VK_ERROR_DEVICE_LOST) {
- qWarning("Device lost");
- return true;
- }
- return false;
-}
-
QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags)
{
QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain);
@@ -1522,10 +1546,12 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
} else if (err == VK_ERROR_OUT_OF_DATE_KHR) {
return QRhi::FrameOpSwapChainOutOfDate;
} else {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkAcquireNextImageKHR()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to acquire next swapchain image: %d", err);
+ }
+ qWarning("Failed to acquire next swapchain image: %d", err);
return QRhi::FrameOpError;
}
}
@@ -1540,12 +1566,12 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
// will make B wait for A's frame 0 commands, so if a resource is written
// in B's frame or when B checks for pending resource releases, that won't
// mess up A's in-flight commands (as they are not in flight anymore).
- waitCommandCompletion(swapChainD->currentFrameSlot);
+ waitCommandCompletion(int(swapChainD->currentFrameSlot));
// Now is the time to read the timestamps for the previous frame for this slot.
if (frame.timestampQueryIndex >= 0) {
quint64 timestamp[2] = { 0, 0 };
- VkResult err = df->vkGetQueryPoolResults(dev, timestampQueryPool, frame.timestampQueryIndex, 2,
+ VkResult err = df->vkGetQueryPoolResults(dev, timestampQueryPool, uint32_t(frame.timestampQueryIndex), 2,
2 * sizeof(quint64), timestamp, sizeof(quint64),
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
timestampQueryPoolMap.clearBit(frame.timestampQueryIndex / 2);
@@ -1585,10 +1611,10 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
}
}
if (timestampQueryIdx >= 0) {
- df->vkCmdResetQueryPool(frame.cmdBuf, timestampQueryPool, timestampQueryIdx, 2);
+ df->vkCmdResetQueryPool(frame.cmdBuf, timestampQueryPool, uint32_t(timestampQueryIdx), 2);
// record timestamp at the start of the command buffer
df->vkCmdWriteTimestamp(frame.cmdBuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
- timestampQueryPool, timestampQueryIdx);
+ timestampQueryPool, uint32_t(timestampQueryIdx));
frame.timestampQueryIndex = timestampQueryIdx;
}
@@ -1598,7 +1624,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
QVkSwapChain::ImageResources &image(swapChainD->imageRes[swapChainD->currentImageIndex]);
swapChainD->rtWrapper.d.fb = image.fb;
- currentFrameSlot = swapChainD->currentFrameSlot;
+ currentFrameSlot = int(swapChainD->currentFrameSlot);
currentSwapChain = swapChainD;
if (swapChainD->ds)
swapChainD->ds->lastActiveFrameSlot = currentFrameSlot;
@@ -1653,7 +1679,7 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram
// record another timestamp, when enabled
if (frame.timestampQueryIndex >= 0) {
df->vkCmdWriteTimestamp(frame.cmdBuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
- timestampQueryPool, frame.timestampQueryIndex + 1);
+ timestampQueryPool, uint32_t(frame.timestampQueryIndex + 1));
}
// stop recording and submit to the queue
@@ -1684,15 +1710,21 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram
presInfo.waitSemaphoreCount = 1;
presInfo.pWaitSemaphores = &frame.drawSem; // gfxQueueFamilyIdx == presQueueFamilyIdx ? &frame.drawSem : &frame.presTransSem;
+ // Do platform-specific WM notification. F.ex. essential on Wayland in
+ // order to circumvent driver frame callbacks
+ inst->presentAboutToBeQueued(swapChainD->window);
+
VkResult err = vkQueuePresentKHR(gfxQueue, &presInfo);
if (err != VK_SUCCESS) {
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
return QRhi::FrameOpSwapChainOutOfDate;
} else if (err != VK_SUBOPTIMAL_KHR) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkQueuePresentKHR()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to present: %d", err);
+ }
+ qWarning("Failed to present: %d", err);
return QRhi::FrameOpError;
}
}
@@ -1749,10 +1781,12 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb)
VkResult err = df->vkAllocateCommandBuffers(dev, &cmdBufInfo, cb);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkAllocateCommandBuffers()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to allocate frame command buffer: %d", err);
+ }
+ qWarning("Failed to allocate frame command buffer: %d", err);
return QRhi::FrameOpError;
}
@@ -1762,10 +1796,12 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb)
err = df->vkBeginCommandBuffer(*cb, &cmdBufBeginInfo);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkBeginCommandBuffer()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to begin frame command buffer: %d", err);
+ }
+ qWarning("Failed to begin frame command buffer: %d", err);
return QRhi::FrameOpError;
}
@@ -1777,10 +1813,12 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer
{
VkResult err = df->vkEndCommandBuffer(cb);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkEndCommandBuffer()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to end frame command buffer: %d", err);
+ }
+ qWarning("Failed to end frame command buffer: %d", err);
return QRhi::FrameOpError;
}
@@ -1802,10 +1840,12 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer
err = df->vkQueueSubmit(gfxQueue, 1, &submitInfo, cmdFence);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkQueueSubmit()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to submit to graphics queue: %d", err);
+ }
+ qWarning("Failed to submit to graphics queue: %d", err);
return QRhi::FrameOpError;
}
@@ -1932,8 +1972,8 @@ static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const
{
QRhiPassResourceTracker::UsageState u;
u.layout = 0; // unused with buffers
- u.access = bufUsage.access;
- u.stage = bufUsage.stage;
+ u.access = int(bufUsage.access);
+ u.stage = int(bufUsage.stage);
return u;
}
@@ -1941,8 +1981,8 @@ static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const
{
QRhiPassResourceTracker::UsageState u;
u.layout = texUsage.layout;
- u.access = texUsage.access;
- u.stage = texUsage.stage;
+ u.access = int(texUsage.access);
+ u.stage = int(texUsage.stage);
return u;
}
@@ -1951,11 +1991,10 @@ void QRhiVulkan::activateTextureRenderTarget(QVkCommandBuffer *cbD, QVkTextureRe
rtD->lastActiveFrameSlot = currentFrameSlot;
rtD->d.rp->lastActiveFrameSlot = currentFrameSlot;
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
- const QVector<QRhiColorAttachment> colorAttachments = rtD->m_desc.colorAttachments();
- for (const QRhiColorAttachment &colorAttachment : colorAttachments) {
- QVkTexture *texD = QRHI_RES(QVkTexture, colorAttachment.texture());
- QVkTexture *resolveTexD = QRHI_RES(QVkTexture, colorAttachment.resolveTexture());
- QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, colorAttachment.renderBuffer());
+ for (auto it = rtD->m_desc.cbeginColorAttachments(), itEnd = rtD->m_desc.cendColorAttachments(); it != itEnd; ++it) {
+ QVkTexture *texD = QRHI_RES(QVkTexture, it->texture());
+ QVkTexture *resolveTexD = QRHI_RES(QVkTexture, it->resolveTexture());
+ QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer());
if (texD) {
trackedRegisterTexture(&passResTracker, texD,
QRhiPassResourceTracker::TexColorOutput,
@@ -2106,8 +2145,8 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb,
rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rpBeginInfo.renderPass = rtD->rp->rp;
rpBeginInfo.framebuffer = rtD->fb;
- rpBeginInfo.renderArea.extent.width = rtD->pixelSize.width();
- rpBeginInfo.renderArea.extent.height = rtD->pixelSize.height();
+ rpBeginInfo.renderArea.extent.width = uint32_t(rtD->pixelSize.width());
+ rpBeginInfo.renderArea.extent.height = uint32_t(rtD->pixelSize.height());
QVarLengthArray<VkClearValue, 4> cvs;
for (int i = 0; i < rtD->colorAttCount; ++i) {
@@ -2127,7 +2166,7 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb,
float(colorClearValue.alphaF()) } };
cvs.append(cv);
}
- rpBeginInfo.clearValueCount = cvs.count();
+ rpBeginInfo.clearValueCount = uint32_t(cvs.count());
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::BeginRenderPass;
@@ -2229,7 +2268,7 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::ComputePass);
if (cbD->useSecondaryCb) {
- df->vkCmdDispatch(cbD->secondaryCbs.last(), x, y, z);
+ df->vkCmdDispatch(cbD->secondaryCbs.last(), uint32_t(x), uint32_t(y), uint32_t(z));
} else {
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::Dispatch;
@@ -2245,7 +2284,7 @@ VkShaderModule QRhiVulkan::createShader(const QByteArray &spirv)
VkShaderModuleCreateInfo shaderInfo;
memset(&shaderInfo, 0, sizeof(shaderInfo));
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
- shaderInfo.codeSize = spirv.size();
+ shaderInfo.codeSize = size_t(spirv.size());
shaderInfo.pCode = reinterpret_cast<const quint32 *>(spirv.constData());
VkShaderModule shaderModule;
VkResult err = df->vkCreateShaderModule(dev, &shaderInfo, nullptr, &shaderModule);
@@ -2285,14 +2324,14 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
while (frameSlot < (updateAll ? QVK_FRAMES_IN_FLIGHT : descSetIdx + 1)) {
srbD->boundResourceData[frameSlot].resize(srbD->sortedBindings.count());
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[frameSlot][i]);
VkWriteDescriptorSet writeInfo;
memset(&writeInfo, 0, sizeof(writeInfo));
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfo.dstSet = srbD->descSets[frameSlot];
- writeInfo.dstBinding = b->binding;
+ writeInfo.dstBinding = uint32_t(b->binding);
writeInfo.descriptorCount = 1;
switch (b->type) {
@@ -2306,8 +2345,8 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
bd.ubuf.generation = bufD->generation;
VkDescriptorBufferInfo bufInfo;
bufInfo.buffer = bufD->m_type == QRhiBuffer::Dynamic ? bufD->buffers[frameSlot] : bufD->buffers[0];
- bufInfo.offset = b->u.ubuf.offset;
- bufInfo.range = b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size;
+ bufInfo.offset = VkDeviceSize(b->u.ubuf.offset);
+ bufInfo.range = VkDeviceSize(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size);
// be nice and assert when we know the vulkan device would die a horrible death due to non-aligned reads
Q_ASSERT(aligned(bufInfo.offset, ubufAlign) == bufInfo.offset);
bufferInfos.append(bufInfo);
@@ -2364,8 +2403,8 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
bd.sbuf.generation = bufD->generation;
VkDescriptorBufferInfo bufInfo;
bufInfo.buffer = bufD->m_type == QRhiBuffer::Dynamic ? bufD->buffers[frameSlot] : bufD->buffers[0];
- bufInfo.offset = b->u.ubuf.offset;
- bufInfo.range = b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size;
+ bufInfo.offset = VkDeviceSize(b->u.ubuf.offset);
+ bufInfo.range = VkDeviceSize(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size);
bufferInfos.append(bufInfo);
writeInfo.pBufferInfo = &bufferInfos.last();
}
@@ -2379,7 +2418,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
++frameSlot;
}
- df->vkUpdateDescriptorSets(dev, writeInfos.count(), writeInfos.constData(), 0, nullptr);
+ df->vkUpdateDescriptorSets(dev, uint32_t(writeInfos.count()), writeInfos.constData(), 0, nullptr);
}
static inline bool accessIsWrite(VkAccessFlags access)
@@ -2487,10 +2526,10 @@ void QRhiVulkan::subresourceBarrier(QVkCommandBuffer *cbD, VkImage image,
memset(&barrier, 0, sizeof(barrier));
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- barrier.subresourceRange.baseMipLevel = startLevel;
- barrier.subresourceRange.levelCount = levelCount;
- barrier.subresourceRange.baseArrayLayer = startLayer;
- barrier.subresourceRange.layerCount = layerCount;
+ barrier.subresourceRange.baseMipLevel = uint32_t(startLevel);
+ barrier.subresourceRange.levelCount = uint32_t(levelCount);
+ barrier.subresourceRange.baseArrayLayer = uint32_t(startLayer);
+ barrier.subresourceRange.layerCount = uint32_t(layerCount);
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.srcAccessMask = srcAccess;
@@ -2511,7 +2550,7 @@ VkDeviceSize QRhiVulkan::subresUploadByteSize(const QRhiTextureSubresourceUpload
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
subresDesc.data().size() : subresDesc.image().sizeInBytes();
if (imageSizeBytes > 0)
- size += aligned(imageSizeBytes, texbufAlign);
+ size += aligned(VkDeviceSize(imageSizeBytes), texbufAlign);
return size;
}
@@ -2528,8 +2567,8 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
memset(&copyInfo, 0, sizeof(copyInfo));
copyInfo.bufferOffset = *curOfs;
copyInfo.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- copyInfo.imageSubresource.mipLevel = level;
- copyInfo.imageSubresource.baseArrayLayer = layer;
+ copyInfo.imageSubresource.mipLevel = uint32_t(level);
+ copyInfo.imageSubresource.baseArrayLayer = uint32_t(layer);
copyInfo.imageSubresource.layerCount = 1;
copyInfo.imageExtent.depth = 1;
@@ -2544,7 +2583,7 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
// be taken into account for bufferRowLength.
int bpc = qMax(1, image.depth() / 8);
// this is in pixels, not bytes, to make it more complicated...
- copyInfo.bufferRowLength = image.bytesPerLine() / bpc;
+ copyInfo.bufferRowLength = uint32_t(image.bytesPerLine() / bpc);
if (!subresDesc.sourceSize().isEmpty() || !subresDesc.sourceTopLeft().isNull()) {
const int sx = subresDesc.sourceTopLeft().x();
const int sy = subresDesc.sourceTopLeft().y();
@@ -2554,7 +2593,7 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
// The staging buffer will get the full image
// regardless, just adjust the vk
// buffer-to-image copy start offset.
- copyInfo.bufferOffset += sy * image.bytesPerLine() + sx * 4;
+ copyInfo.bufferOffset += VkDeviceSize(sy * image.bytesPerLine() + sx * 4);
// bufferRowLength remains set to the original image's width
} else {
image = image.copy(sx, sy, size.width(), size.height());
@@ -2563,13 +2602,13 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
// space reserved for this mip will be unused.
copySizeBytes = image.sizeInBytes();
bpc = qMax(1, image.depth() / 8);
- copyInfo.bufferRowLength = image.bytesPerLine() / bpc;
+ copyInfo.bufferRowLength = uint32_t(image.bytesPerLine() / bpc);
}
}
copyInfo.imageOffset.x = dp.x();
copyInfo.imageOffset.y = dp.y();
- copyInfo.imageExtent.width = size.width();
- copyInfo.imageExtent.height = size.height();
+ copyInfo.imageExtent.width = uint32_t(size.width());
+ copyInfo.imageExtent.height = uint32_t(size.height());
copyInfos->append(copyInfo);
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
copySizeBytes = imageSizeBytes = rawData.size();
@@ -2588,8 +2627,8 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
copyInfo.imageOffset.y = aligned(dp.y(), blockDim.height());
// width and height must be multiples of the block width and height
// or x + width and y + height must equal the subresource width and height
- copyInfo.imageExtent.width = dp.x() + w == subresw ? w : aligned(w, blockDim.width());
- copyInfo.imageExtent.height = dp.y() + h == subresh ? h : aligned(h, blockDim.height());
+ copyInfo.imageExtent.width = uint32_t(dp.x() + w == subresw ? w : aligned(w, blockDim.width()));
+ copyInfo.imageExtent.height = uint32_t(dp.y() + h == subresh ? h : aligned(h, blockDim.height()));
copyInfos->append(copyInfo);
} else if (!rawData.isEmpty()) {
copySizeBytes = imageSizeBytes = rawData.size();
@@ -2599,15 +2638,15 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
size = subresDesc.sourceSize();
copyInfo.imageOffset.x = dp.x();
copyInfo.imageOffset.y = dp.y();
- copyInfo.imageExtent.width = size.width();
- copyInfo.imageExtent.height = size.height();
+ copyInfo.imageExtent.width = uint32_t(size.width());
+ copyInfo.imageExtent.height = uint32_t(size.height());
copyInfos->append(copyInfo);
} else {
qWarning("Invalid texture upload for %p layer=%d mip=%d", texD, layer, level);
}
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, src, copySizeBytes);
- *curOfs += aligned(imageSizeBytes, texbufAlign);
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, src, size_t(copySizeBytes));
+ *curOfs += aligned(VkDeviceSize(imageSizeBytes), texbufAlign);
}
void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates)
@@ -2615,100 +2654,164 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
- QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
- Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
- for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
- bufD->pendingDynamicUpdates[i].append(u);
- }
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
+ QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
+ Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
+ for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
+ bufD->pendingDynamicUpdates[i].append(u);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload) {
+ QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
+ Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
+ Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
+
+ if (!bufD->stagingBuffers[currentFrameSlot]) {
+ VkBufferCreateInfo bufferInfo;
+ memset(&bufferInfo, 0, sizeof(bufferInfo));
+ bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ // must cover the entire buffer - this way multiple, partial updates per frame
+ // are supported even when the staging buffer is reused (Static)
+ bufferInfo.size = VkDeviceSize(bufD->m_size);
+ bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+
+ VmaAllocationCreateInfo allocInfo;
+ memset(&allocInfo, 0, sizeof(allocInfo));
+ allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
+
+ VmaAllocation allocation;
+ VkResult err = vmaCreateBuffer(toVmaAllocator(allocator), &bufferInfo, &allocInfo,
+ &bufD->stagingBuffers[currentFrameSlot], &allocation, nullptr);
+ if (err == VK_SUCCESS) {
+ bufD->stagingAllocations[currentFrameSlot] = allocation;
+ QRHI_PROF_F(newBufferStagingArea(bufD, currentFrameSlot, quint32(bufD->m_size)));
+ } else {
+ qWarning("Failed to create staging buffer of size %d: %d", bufD->m_size, err);
+ continue;
+ }
+ }
- for (const QRhiResourceUpdateBatchPrivate::StaticBufferUpload &u : ud->staticBufferUploads) {
- QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
- Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
- Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
+ void *p = nullptr;
+ VmaAllocation a = toVmaAllocation(bufD->stagingAllocations[currentFrameSlot]);
+ VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
+ if (err != VK_SUCCESS) {
+ qWarning("Failed to map buffer: %d", err);
+ continue;
+ }
+ memcpy(static_cast<uchar *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
+ vmaUnmapMemory(toVmaAllocator(allocator), a);
+ vmaFlushAllocation(toVmaAllocator(allocator), a, VkDeviceSize(u.offset), VkDeviceSize(u.data.size()));
- if (!bufD->stagingBuffers[currentFrameSlot]) {
- VkBufferCreateInfo bufferInfo;
- memset(&bufferInfo, 0, sizeof(bufferInfo));
- bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- // must cover the entire buffer - this way multiple, partial updates per frame
- // are supported even when the staging buffer is reused (Static)
- bufferInfo.size = bufD->m_size;
- bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ trackedBufferBarrier(cbD, bufD, 0,
+ VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
- VmaAllocationCreateInfo allocInfo;
- memset(&allocInfo, 0, sizeof(allocInfo));
- allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
+ VkBufferCopy copyInfo;
+ memset(&copyInfo, 0, sizeof(copyInfo));
+ copyInfo.srcOffset = VkDeviceSize(u.offset);
+ copyInfo.dstOffset = VkDeviceSize(u.offset);
+ copyInfo.size = VkDeviceSize(u.data.size());
- VmaAllocation allocation;
- VkResult err = vmaCreateBuffer(toVmaAllocator(allocator), &bufferInfo, &allocInfo,
- &bufD->stagingBuffers[currentFrameSlot], &allocation, nullptr);
- if (err == VK_SUCCESS) {
- bufD->stagingAllocations[currentFrameSlot] = allocation;
- QRHI_PROF_F(newBufferStagingArea(bufD, currentFrameSlot, bufD->m_size));
- } else {
- qWarning("Failed to create staging buffer of size %d: %d", bufD->m_size, err);
- continue;
- }
- }
+ QVkCommandBuffer::Command cmd;
+ cmd.cmd = QVkCommandBuffer::Command::CopyBuffer;
+ cmd.args.copyBuffer.src = bufD->stagingBuffers[currentFrameSlot];
+ cmd.args.copyBuffer.dst = bufD->buffers[0];
+ cmd.args.copyBuffer.desc = copyInfo;
+ cbD->commands.append(cmd);
- void *p = nullptr;
- VmaAllocation a = toVmaAllocation(bufD->stagingAllocations[currentFrameSlot]);
- VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
- if (err != VK_SUCCESS) {
- qWarning("Failed to map buffer: %d", err);
- continue;
- }
- memcpy(static_cast<uchar *>(p) + u.offset, u.data.constData(), u.data.size());
- vmaUnmapMemory(toVmaAllocator(allocator), a);
- vmaFlushAllocation(toVmaAllocator(allocator), a, u.offset, u.data.size());
+ // Where's the barrier for read-after-write? (assuming the common case
+ // of binding this buffer as vertex/index, or, less likely, as uniform
+ // buffer, in a renderpass later on) That is handled by the pass
+ // resource tracking: the appropriate pipeline barrier will be
+ // generated and recorded right before the renderpass, that binds this
+ // buffer in one of its commands, gets its BeginRenderPass recorded.
- trackedBufferBarrier(cbD, bufD, 0,
- VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+ bufD->lastActiveFrameSlot = currentFrameSlot;
- VkBufferCopy copyInfo;
- memset(&copyInfo, 0, sizeof(copyInfo));
- copyInfo.srcOffset = u.offset;
- copyInfo.dstOffset = u.offset;
- copyInfo.size = u.data.size();
+ if (bufD->m_type == QRhiBuffer::Immutable) {
+ QRhiVulkan::DeferredReleaseEntry e;
+ e.type = QRhiVulkan::DeferredReleaseEntry::StagingBuffer;
+ e.lastActiveFrameSlot = currentFrameSlot;
+ e.stagingBuffer.stagingBuffer = bufD->stagingBuffers[currentFrameSlot];
+ e.stagingBuffer.stagingAllocation = bufD->stagingAllocations[currentFrameSlot];
+ bufD->stagingBuffers[currentFrameSlot] = VK_NULL_HANDLE;
+ bufD->stagingAllocations[currentFrameSlot] = nullptr;
+ releaseQueue.append(e);
+ QRHI_PROF_F(releaseBufferStagingArea(bufD, currentFrameSlot));
+ }
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
+ QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
+ if (bufD->m_type == QRhiBuffer::Dynamic) {
+ executeBufferHostWritesForCurrentFrame(bufD);
+ void *p = nullptr;
+ VmaAllocation a = toVmaAllocation(bufD->allocations[currentFrameSlot]);
+ VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
+ if (err == VK_SUCCESS) {
+ u.result->data.resize(u.readSize);
+ memcpy(u.result->data.data(), reinterpret_cast<char *>(p) + u.offset, size_t(u.readSize));
+ vmaUnmapMemory(toVmaAllocator(allocator), a);
+ }
+ if (u.result->completed)
+ u.result->completed();
+ } else {
+ // Non-Dynamic buffers may not be host visible, so have to
+ // create a readback buffer, enqueue a copy from
+ // bufD->buffers[0] to this buffer, and then once the command
+ // buffer completes, copy the data out of the host visible
+ // readback buffer. Quite similar to what we do for texture
+ // readbacks.
+ BufferReadback readback;
+ readback.activeFrameSlot = currentFrameSlot;
+ readback.result = u.result;
+ readback.byteSize = u.readSize;
+
+ VkBufferCreateInfo bufferInfo;
+ memset(&bufferInfo, 0, sizeof(bufferInfo));
+ bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ bufferInfo.size = VkDeviceSize(readback.byteSize);
+ bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+
+ VmaAllocationCreateInfo allocInfo;
+ memset(&allocInfo, 0, sizeof(allocInfo));
+ allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
+
+ VmaAllocation allocation;
+ VkResult err = vmaCreateBuffer(toVmaAllocator(allocator), &bufferInfo, &allocInfo, &readback.stagingBuf, &allocation, nullptr);
+ if (err == VK_SUCCESS) {
+ readback.stagingAlloc = allocation;
+ QRHI_PROF_F(newReadbackBuffer(qint64(readback.stagingBuf), bufD, uint(readback.byteSize)));
+ } else {
+ qWarning("Failed to create readback buffer of size %u: %d", readback.byteSize, err);
+ continue;
+ }
- QVkCommandBuffer::Command cmd;
- cmd.cmd = QVkCommandBuffer::Command::CopyBuffer;
- cmd.args.copyBuffer.src = bufD->stagingBuffers[currentFrameSlot];
- cmd.args.copyBuffer.dst = bufD->buffers[0];
- cmd.args.copyBuffer.desc = copyInfo;
- cbD->commands.append(cmd);
+ trackedBufferBarrier(cbD, bufD, 0, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
- // Where's the barrier for read-after-write? (assuming the common case
- // of binding this buffer as vertex/index, or, less likely, as uniform
- // buffer, in a renderpass later on) That is handled by the pass
- // resource tracking: the appropriate pipeline barrier will be
- // generated and recorded right before the renderpass, that binds this
- // buffer in one of its commands, gets its BeginRenderPass recorded.
+ VkBufferCopy copyInfo;
+ memset(&copyInfo, 0, sizeof(copyInfo));
+ copyInfo.srcOffset = VkDeviceSize(u.offset);
+ copyInfo.size = VkDeviceSize(u.readSize);
- bufD->lastActiveFrameSlot = currentFrameSlot;
+ QVkCommandBuffer::Command cmd;
+ cmd.cmd = QVkCommandBuffer::Command::CopyBuffer;
+ cmd.args.copyBuffer.src = bufD->buffers[0];
+ cmd.args.copyBuffer.dst = readback.stagingBuf;
+ cmd.args.copyBuffer.desc = copyInfo;
+ cbD->commands.append(cmd);
- if (bufD->m_type == QRhiBuffer::Immutable) {
- QRhiVulkan::DeferredReleaseEntry e;
- e.type = QRhiVulkan::DeferredReleaseEntry::StagingBuffer;
- e.lastActiveFrameSlot = currentFrameSlot;
- e.stagingBuffer.stagingBuffer = bufD->stagingBuffers[currentFrameSlot];
- e.stagingBuffer.stagingAllocation = bufD->stagingAllocations[currentFrameSlot];
- bufD->stagingBuffers[currentFrameSlot] = VK_NULL_HANDLE;
- bufD->stagingAllocations[currentFrameSlot] = nullptr;
- releaseQueue.append(e);
- QRHI_PROF_F(releaseBufferStagingArea(bufD, currentFrameSlot));
+ bufD->lastActiveFrameSlot = currentFrameSlot;
+
+ activeBufferReadbacks.append(readback);
+ }
}
}
for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
- QVkTexture *utexD = QRHI_RES(QVkTexture, u.upload.tex);
+ QVkTexture *utexD = QRHI_RES(QVkTexture, u.dst);
// batch into a single staging buffer and a single CopyBufferToImage with multiple copyInfos
VkDeviceSize stagingSize = 0;
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
- for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.upload.subresDesc[layer][level]))
+ for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
stagingSize += subresUploadByteSize(subresDesc);
}
}
@@ -2732,7 +2835,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
continue;
}
utexD->stagingAllocations[currentFrameSlot] = allocation;
- QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize));
+ QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
BufferImageCopyList copyInfos;
size_t curOfs = 0;
@@ -2746,7 +2849,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
- const QVector<QRhiTextureSubresourceUploadDescription> &srd(u.upload.subresDesc[layer][level]);
+ const QVector<QRhiTextureSubresourceUploadDescription> &srd(u.subresDesc[layer][level]);
if (srd.isEmpty())
continue;
for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(srd)) {
@@ -2787,36 +2890,37 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
utexD->lastActiveFrameSlot = currentFrameSlot;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Copy) {
- Q_ASSERT(u.copy.src && u.copy.dst);
- if (u.copy.src == u.copy.dst) {
+ Q_ASSERT(u.src && u.dst);
+ if (u.src == u.dst) {
qWarning("Texture copy with matching source and destination is not supported");
continue;
}
- QVkTexture *srcD = QRHI_RES(QVkTexture, u.copy.src);
- QVkTexture *dstD = QRHI_RES(QVkTexture, u.copy.dst);
+ QVkTexture *srcD = QRHI_RES(QVkTexture, u.src);
+ QVkTexture *dstD = QRHI_RES(QVkTexture, u.dst);
VkImageCopy region;
memset(&region, 0, sizeof(region));
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.srcSubresource.mipLevel = u.copy.desc.sourceLevel();
- region.srcSubresource.baseArrayLayer = u.copy.desc.sourceLayer();
+ region.srcSubresource.mipLevel = uint32_t(u.desc.sourceLevel());
+ region.srcSubresource.baseArrayLayer = uint32_t(u.desc.sourceLayer());
region.srcSubresource.layerCount = 1;
- region.srcOffset.x = u.copy.desc.sourceTopLeft().x();
- region.srcOffset.y = u.copy.desc.sourceTopLeft().y();
+ region.srcOffset.x = u.desc.sourceTopLeft().x();
+ region.srcOffset.y = u.desc.sourceTopLeft().y();
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.dstSubresource.mipLevel = u.copy.desc.destinationLevel();
- region.dstSubresource.baseArrayLayer = u.copy.desc.destinationLayer();
+ region.dstSubresource.mipLevel = uint32_t(u.desc.destinationLevel());
+ region.dstSubresource.baseArrayLayer = uint32_t(u.desc.destinationLayer());
region.dstSubresource.layerCount = 1;
- region.dstOffset.x = u.copy.desc.destinationTopLeft().x();
- region.dstOffset.y = u.copy.desc.destinationTopLeft().y();
+ region.dstOffset.x = u.desc.destinationTopLeft().x();
+ region.dstOffset.y = u.desc.destinationTopLeft().y();
- const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
- region.extent.width = size.width();
- region.extent.height = size.height();
+ const QSize mipSize = q->sizeForMipLevel(u.desc.sourceLevel(), srcD->m_pixelSize);
+ const QSize copySize = u.desc.pixelSize().isEmpty() ? mipSize : u.desc.pixelSize();
+ region.extent.width = uint32_t(copySize.width());
+ region.extent.height = uint32_t(copySize.height());
region.extent.depth = 1;
trackedImageBarrier(cbD, srcD, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
@@ -2835,21 +2939,20 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
- ActiveReadback aRb;
- aRb.activeFrameSlot = currentFrameSlot;
- aRb.desc = u.read.rb;
- aRb.result = u.read.result;
+ TextureReadback readback;
+ readback.activeFrameSlot = currentFrameSlot;
+ readback.desc = u.rb;
+ readback.result = u.result;
- QVkTexture *texD = QRHI_RES(QVkTexture, u.read.rb.texture());
+ QVkTexture *texD = QRHI_RES(QVkTexture, u.rb.texture());
QVkSwapChain *swapChainD = nullptr;
if (texD) {
if (texD->samples > VK_SAMPLE_COUNT_1_BIT) {
qWarning("Multisample texture cannot be read back");
continue;
}
- aRb.pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize)
- : texD->m_pixelSize;
- aRb.format = texD->m_format;
+ readback.pixelSize = q->sizeForMipLevel(u.rb.level(), texD->m_pixelSize);
+ readback.format = texD->m_format;
texD->lastActiveFrameSlot = currentFrameSlot;
} else {
Q_ASSERT(currentSwapChain);
@@ -2858,21 +2961,21 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
qWarning("Swapchain does not support readback");
continue;
}
- aRb.pixelSize = swapChainD->pixelSize;
- aRb.format = colorTextureFormatFromVkFormat(swapChainD->colorFormat, nullptr);
- if (aRb.format == QRhiTexture::UnknownFormat)
+ readback.pixelSize = swapChainD->pixelSize;
+ readback.format = colorTextureFormatFromVkFormat(swapChainD->colorFormat, nullptr);
+ if (readback.format == QRhiTexture::UnknownFormat)
continue;
// Multisample swapchains need nothing special since resolving
// happens when ending a renderpass.
}
- textureFormatInfo(aRb.format, aRb.pixelSize, nullptr, &aRb.bufSize);
+ textureFormatInfo(readback.format, readback.pixelSize, nullptr, &readback.byteSize);
- // Create a host visible buffer.
+ // Create a host visible readback buffer.
VkBufferCreateInfo bufferInfo;
memset(&bufferInfo, 0, sizeof(bufferInfo));
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- bufferInfo.size = aRb.bufSize;
+ bufferInfo.size = readback.byteSize;
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
VmaAllocationCreateInfo allocInfo;
@@ -2880,14 +2983,14 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
VmaAllocation allocation;
- VkResult err = vmaCreateBuffer(toVmaAllocator(allocator), &bufferInfo, &allocInfo, &aRb.buf, &allocation, nullptr);
+ VkResult err = vmaCreateBuffer(toVmaAllocator(allocator), &bufferInfo, &allocInfo, &readback.stagingBuf, &allocation, nullptr);
if (err == VK_SUCCESS) {
- aRb.bufAlloc = allocation;
- QRHI_PROF_F(newReadbackBuffer(quint64(aRb.buf),
+ readback.stagingAlloc = allocation;
+ QRHI_PROF_F(newReadbackBuffer(qint64(readback.stagingBuf),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
- aRb.bufSize));
+ readback.byteSize));
} else {
- qWarning("Failed to create readback buffer of size %u: %d", aRb.bufSize, err);
+ qWarning("Failed to create readback buffer of size %u: %d", readback.byteSize, err);
continue;
}
@@ -2896,11 +2999,11 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
memset(&copyDesc, 0, sizeof(copyDesc));
copyDesc.bufferOffset = 0;
copyDesc.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- copyDesc.imageSubresource.mipLevel = u.read.rb.level();
- copyDesc.imageSubresource.baseArrayLayer = u.read.rb.layer();
+ copyDesc.imageSubresource.mipLevel = uint32_t(u.rb.level());
+ copyDesc.imageSubresource.baseArrayLayer = uint32_t(u.rb.layer());
copyDesc.imageSubresource.layerCount = 1;
- copyDesc.imageExtent.width = aRb.pixelSize.width();
- copyDesc.imageExtent.height = aRb.pixelSize.height();
+ copyDesc.imageExtent.width = uint32_t(readback.pixelSize.width());
+ copyDesc.imageExtent.height = uint32_t(readback.pixelSize.height());
copyDesc.imageExtent.depth = 1;
if (texD) {
@@ -2910,7 +3013,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
cmd.cmd = QVkCommandBuffer::Command::CopyImageToBuffer;
cmd.args.copyImageToBuffer.src = texD->image;
cmd.args.copyImageToBuffer.srcLayout = texD->usageState.layout;
- cmd.args.copyImageToBuffer.dst = aRb.buf;
+ cmd.args.copyImageToBuffer.dst = readback.stagingBuf;
cmd.args.copyImageToBuffer.desc = copyDesc;
cbD->commands.append(cmd);
} else {
@@ -2935,14 +3038,14 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
cmd.cmd = QVkCommandBuffer::Command::CopyImageToBuffer;
cmd.args.copyImageToBuffer.src = image;
cmd.args.copyImageToBuffer.srcLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- cmd.args.copyImageToBuffer.dst = aRb.buf;
+ cmd.args.copyImageToBuffer.dst = readback.stagingBuf;
cmd.args.copyImageToBuffer.desc = copyDesc;
cbD->commands.append(cmd);
}
- activeReadbacks.append(aRb);
- } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::MipGen) {
- QVkTexture *utexD = QRHI_RES(QVkTexture, u.mipgen.tex);
+ activeTextureReadbacks.append(readback);
+ } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
+ QVkTexture *utexD = QRHI_RES(QVkTexture, u.dst);
Q_ASSERT(utexD->m_flags.testFlag(QRhiTexture::UsedWithGenerateMips));
int w = utexD->m_pixelSize.width();
int h = utexD->m_pixelSize.height();
@@ -2953,20 +3056,20 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
if (!origStage)
origStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- for (uint level = 1; level < utexD->mipLevelCount; ++level) {
+ for (int level = 1; level < int(utexD->mipLevelCount); ++level) {
if (level == 1) {
subresourceBarrier(cbD, utexD->image,
origLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
origAccess, VK_ACCESS_TRANSFER_READ_BIT,
origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
- u.mipgen.layer, 1,
+ u.layer, 1,
level - 1, 1);
} else {
subresourceBarrier(cbD, utexD->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- u.mipgen.layer, 1,
+ u.layer, 1,
level - 1, 1);
}
@@ -2974,15 +3077,15 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
origLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
origAccess, VK_ACCESS_TRANSFER_WRITE_BIT,
origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
- u.mipgen.layer, 1,
+ u.layer, 1,
level, 1);
VkImageBlit region;
memset(&region, 0, sizeof(region));
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.srcSubresource.mipLevel = level - 1;
- region.srcSubresource.baseArrayLayer = u.mipgen.layer;
+ region.srcSubresource.mipLevel = uint32_t(level) - 1;
+ region.srcSubresource.baseArrayLayer = uint32_t(u.layer);
region.srcSubresource.layerCount = 1;
region.srcOffsets[1].x = qMax(1, w);
@@ -2990,8 +3093,8 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
region.srcOffsets[1].z = 1;
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.dstSubresource.mipLevel = level;
- region.dstSubresource.baseArrayLayer = u.mipgen.layer;
+ region.dstSubresource.mipLevel = uint32_t(level);
+ region.dstSubresource.baseArrayLayer = uint32_t(u.layer);
region.dstSubresource.layerCount = 1;
region.dstOffsets[1].x = qMax(1, w >> 1);
@@ -3017,14 +3120,14 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, origLayout,
VK_ACCESS_TRANSFER_READ_BIT, origAccess,
VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
- u.mipgen.layer, 1,
- 0, utexD->mipLevelCount - 1);
+ u.layer, 1,
+ 0, int(utexD->mipLevelCount) - 1);
subresourceBarrier(cbD, utexD->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, origLayout,
VK_ACCESS_TRANSFER_WRITE_BIT, origAccess,
VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
- u.mipgen.layer, 1,
- utexD->mipLevelCount - 1, 1);
+ u.layer, 1,
+ int(utexD->mipLevelCount) - 1, 1);
}
utexD->lastActiveFrameSlot = currentFrameSlot;
@@ -3036,8 +3139,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
{
- QVector<QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate> &updates(bufD->pendingDynamicUpdates[currentFrameSlot]);
- if (updates.isEmpty())
+ if (bufD->pendingDynamicUpdates[currentFrameSlot].isEmpty())
return;
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
@@ -3053,9 +3155,9 @@ void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
}
int changeBegin = -1;
int changeEnd = -1;
- for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->pendingDynamicUpdates[currentFrameSlot])) {
Q_ASSERT(bufD == QRHI_RES(QVkBuffer, u.buf));
- memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), u.data.size());
+ memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
if (changeBegin == -1 || u.offset < changeBegin)
changeBegin = u.offset;
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
@@ -3063,9 +3165,9 @@ void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
}
vmaUnmapMemory(toVmaAllocator(allocator), a);
if (changeBegin >= 0)
- vmaFlushAllocation(toVmaAllocator(allocator), a, changeBegin, changeEnd - changeBegin);
+ vmaFlushAllocation(toVmaAllocator(allocator), a, VkDeviceSize(changeBegin), VkDeviceSize(changeEnd - changeBegin));
- updates.clear();
+ bufD->pendingDynamicUpdates[currentFrameSlot].clear();
}
static void qrhivk_releaseBuffer(const QRhiVulkan::DeferredReleaseEntry &e, void *allocator)
@@ -3159,29 +3261,53 @@ void QRhiVulkan::finishActiveReadbacks(bool forced)
QVarLengthArray<std::function<void()>, 4> completedCallbacks;
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (int i = activeReadbacks.count() - 1; i >= 0; --i) {
- const QRhiVulkan::ActiveReadback &aRb(activeReadbacks[i]);
- if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
- aRb.result->format = aRb.format;
- aRb.result->pixelSize = aRb.pixelSize;
- aRb.result->data.resize(aRb.bufSize);
+ for (int i = activeTextureReadbacks.count() - 1; i >= 0; --i) {
+ const QRhiVulkan::TextureReadback &readback(activeTextureReadbacks[i]);
+ if (forced || currentFrameSlot == readback.activeFrameSlot || readback.activeFrameSlot < 0) {
+ readback.result->format = readback.format;
+ readback.result->pixelSize = readback.pixelSize;
+ VmaAllocation a = toVmaAllocation(readback.stagingAlloc);
void *p = nullptr;
- VmaAllocation a = toVmaAllocation(aRb.bufAlloc);
VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
- if (err != VK_SUCCESS) {
- qWarning("Failed to map readback buffer: %d", err);
- continue;
+ if (err == VK_SUCCESS && p) {
+ readback.result->data.resize(int(readback.byteSize));
+ memcpy(readback.result->data.data(), p, readback.byteSize);
+ vmaUnmapMemory(toVmaAllocator(allocator), a);
+ } else {
+ qWarning("Failed to map texture readback buffer of size %u: %d", readback.byteSize, err);
}
- memcpy(aRb.result->data.data(), p, aRb.bufSize);
- vmaUnmapMemory(toVmaAllocator(allocator), a);
- vmaDestroyBuffer(toVmaAllocator(allocator), aRb.buf, a);
- QRHI_PROF_F(releaseReadbackBuffer(quint64(aRb.buf)));
+ vmaDestroyBuffer(toVmaAllocator(allocator), readback.stagingBuf, a);
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(readback.stagingBuf)));
+
+ if (readback.result->completed)
+ completedCallbacks.append(readback.result->completed);
+
+ activeTextureReadbacks.removeAt(i);
+ }
+ }
+
+ for (int i = activeBufferReadbacks.count() - 1; i >= 0; --i) {
+ const QRhiVulkan::BufferReadback &readback(activeBufferReadbacks[i]);
+ if (forced || currentFrameSlot == readback.activeFrameSlot || readback.activeFrameSlot < 0) {
+ VmaAllocation a = toVmaAllocation(readback.stagingAlloc);
+ void *p = nullptr;
+ VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
+ if (err == VK_SUCCESS && p) {
+ readback.result->data.resize(readback.byteSize);
+ memcpy(readback.result->data.data(), p, size_t(readback.byteSize));
+ vmaUnmapMemory(toVmaAllocator(allocator), a);
+ } else {
+ qWarning("Failed to map buffer readback buffer of size %d: %d", readback.byteSize, err);
+ }
- if (aRb.result->completed)
- completedCallbacks.append(aRb.result->completed);
+ vmaDestroyBuffer(toVmaAllocator(allocator), readback.stagingBuf, a);
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(readback.stagingBuf)));
- activeReadbacks.removeAt(i);
+ if (readback.result->completed)
+ completedCallbacks.append(readback.result->completed);
+
+ activeBufferReadbacks.removeAt(i);
}
}
@@ -3211,12 +3337,12 @@ QVector<int> QRhiVulkan::supportedSampleCounts() const
VkSampleCountFlags stencil = limits->framebufferStencilSampleCounts;
QVector<int> result;
- for (size_t i = 0; i < sizeof(qvk_sampleCounts) / sizeof(qvk_sampleCounts[0]); ++i) {
- if ((color & qvk_sampleCounts[i].mask)
- && (depth & qvk_sampleCounts[i].mask)
- && (stencil & qvk_sampleCounts[i].mask))
+ for (const auto &qvk_sampleCount : qvk_sampleCounts) {
+ if ((color & qvk_sampleCount.mask)
+ && (depth & qvk_sampleCount.mask)
+ && (stencil & qvk_sampleCount.mask))
{
- result.append(qvk_sampleCounts[i].count);
+ result.append(qvk_sampleCount.count);
}
}
@@ -3233,9 +3359,9 @@ VkSampleCountFlagBits QRhiVulkan::effectiveSampleCount(int sampleCount)
return VK_SAMPLE_COUNT_1_BIT;
}
- for (size_t i = 0; i < sizeof(qvk_sampleCounts) / sizeof(qvk_sampleCounts[0]); ++i) {
- if (qvk_sampleCounts[i].count == sampleCount)
- return qvk_sampleCounts[i].mask;
+ for (const auto &qvk_sampleCount : qvk_sampleCounts) {
+ if (qvk_sampleCount.count == sampleCount)
+ return qvk_sampleCount.mask;
}
Q_UNREACHABLE();
@@ -3266,7 +3392,7 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
case QVkCommandBuffer::Command::CopyBufferToImage:
df->vkCmdCopyBufferToImage(cbD->cb, cmd.args.copyBufferToImage.src, cmd.args.copyBufferToImage.dst,
cmd.args.copyBufferToImage.dstLayout,
- cmd.args.copyBufferToImage.count,
+ uint32_t(cmd.args.copyBufferToImage.count),
cbD->pools.bufferImageCopy.constData() + cmd.args.copyBufferToImage.bufferImageCopyIndex);
break;
case QVkCommandBuffer::Command::CopyImage:
@@ -3315,13 +3441,13 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
df->vkCmdBindDescriptorSets(cbD->cb, cmd.args.bindDescriptorSet.bindPoint,
cmd.args.bindDescriptorSet.pipelineLayout,
0, 1, &cmd.args.bindDescriptorSet.descSet,
- cmd.args.bindDescriptorSet.dynamicOffsetCount,
+ uint32_t(cmd.args.bindDescriptorSet.dynamicOffsetCount),
offsets);
}
break;
case QVkCommandBuffer::Command::BindVertexBuffer:
- df->vkCmdBindVertexBuffers(cbD->cb, cmd.args.bindVertexBuffer.startBinding,
- cmd.args.bindVertexBuffer.count,
+ df->vkCmdBindVertexBuffers(cbD->cb, uint32_t(cmd.args.bindVertexBuffer.startBinding),
+ uint32_t(cmd.args.bindVertexBuffer.count),
cbD->pools.vertexBuffer.constData() + cmd.args.bindVertexBuffer.vertexBufferIndex,
cbD->pools.vertexBufferOffset.constData() + cmd.args.bindVertexBuffer.vertexBufferOffsetIndex);
break;
@@ -3367,7 +3493,7 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
recordTransitionPassResources(cbD, cbD->passResTrackers[cmd.args.transitionResources.trackerIndex]);
break;
case QVkCommandBuffer::Command::Dispatch:
- df->vkCmdDispatch(cbD->cb, cmd.args.dispatch.x, cmd.args.dispatch.y, cmd.args.dispatch.z);
+ df->vkCmdDispatch(cbD->cb, uint32_t(cmd.args.dispatch.x), uint32_t(cmd.args.dispatch.y), uint32_t(cmd.args.dispatch.z));
break;
case QVkCommandBuffer::Command::ExecuteSecondary:
df->vkCmdExecuteCommands(cbD->cb, 1, &cmd.args.executeSecondary.cb);
@@ -3421,8 +3547,8 @@ static inline VkPipelineStageFlags toVkPipelineStage(QRhiPassResourceTracker::Bu
static inline QVkBuffer::UsageState toVkBufferUsageState(QRhiPassResourceTracker::UsageState usage)
{
QVkBuffer::UsageState u;
- u.access = usage.access;
- u.stage = usage.stage;
+ u.access = VkAccessFlags(usage.access);
+ u.stage = VkPipelineStageFlags(usage.stage);
return u;
}
@@ -3494,8 +3620,8 @@ static inline QVkTexture::UsageState toVkTextureUsageState(QRhiPassResourceTrack
{
QVkTexture::UsageState u;
u.layout = VkImageLayout(usage.layout);
- u.access = usage.access;
- u.stage = usage.stage;
+ u.access = VkAccessFlags(usage.access);
+ u.stage = VkPipelineStageFlags(usage.stage);
return u;
}
@@ -3528,12 +3654,11 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi
if (tracker.isEmpty())
return;
- const QVector<QRhiPassResourceTracker::Buffer> *buffers = tracker.buffers();
- for (const QRhiPassResourceTracker::Buffer &b : *buffers) {
- QVkBuffer *bufD = QRHI_RES(QVkBuffer, b.buf);
- VkAccessFlags access = toVkAccess(b.access);
- VkPipelineStageFlags stage = toVkPipelineStage(b.stage);
- QVkBuffer::UsageState s = toVkBufferUsageState(b.stateAtPassBegin);
+ for (auto it = tracker.cbeginBuffers(), itEnd = tracker.cendBuffers(); it != itEnd; ++it) {
+ QVkBuffer *bufD = QRHI_RES(QVkBuffer, it.key());
+ VkAccessFlags access = toVkAccess(it->access);
+ VkPipelineStageFlags stage = toVkPipelineStage(it->stage);
+ QVkBuffer::UsageState s = toVkBufferUsageState(it->stateAtPassBegin);
if (!s.stage)
continue;
if (s.access == access && s.stage == stage) {
@@ -3547,7 +3672,7 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.srcAccessMask = s.access;
bufMemBarrier.dstAccessMask = access;
- bufMemBarrier.buffer = bufD->buffers[b.slot];
+ bufMemBarrier.buffer = bufD->buffers[it->slot];
bufMemBarrier.size = VK_WHOLE_SIZE;
df->vkCmdPipelineBarrier(cbD->cb, s.stage, stage, 0,
0, nullptr,
@@ -3555,13 +3680,12 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi
0, nullptr);
}
- const QVector<QRhiPassResourceTracker::Texture> *textures = tracker.textures();
- for (const QRhiPassResourceTracker::Texture &t : *textures) {
- QVkTexture *texD = QRHI_RES(QVkTexture, t.tex);
- VkImageLayout layout = toVkLayout(t.access);
- VkAccessFlags access = toVkAccess(t.access);
- VkPipelineStageFlags stage = toVkPipelineStage(t.stage);
- QVkTexture::UsageState s = toVkTextureUsageState(t.stateAtPassBegin);
+ for (auto it = tracker.cbeginTextures(), itEnd = tracker.cendTextures(); it != itEnd; ++it) {
+ QVkTexture *texD = QRHI_RES(QVkTexture, it.key());
+ VkImageLayout layout = toVkLayout(it->access);
+ VkAccessFlags access = toVkAccess(it->access);
+ VkPipelineStageFlags stage = toVkPipelineStage(it->stage);
+ QVkTexture::UsageState s = toVkTextureUsageState(it->stateAtPassBegin);
if (s.access == access && s.stage == stage && s.layout == layout) {
if (!accessIsWrite(access))
continue;
@@ -3603,7 +3727,7 @@ QRhiBuffer *QRhiVulkan::createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFla
int QRhiVulkan::ubufAlignment() const
{
- return ubufAlign; // typically 256 (bytes)
+ return int(ubufAlign); // typically 256 (bytes)
}
bool QRhiVulkan::isYUpInFramebuffer() const
@@ -3699,6 +3823,12 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::BaseInstance:
return true;
+ case QRhi::TriangleFanTopology:
+ return true;
+ case QRhi::ReadBackNonUniformBuffer:
+ return true;
+ case QRhi::ReadBackNonBaseMipLevel:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -3711,9 +3841,9 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const
case QRhi::TextureSizeMin:
return 1;
case QRhi::TextureSizeMax:
- return physDevProperties.limits.maxImageDimension2D;
+ return int(physDevProperties.limits.maxImageDimension2D);
case QRhi::MaxColorAttachments:
- return physDevProperties.limits.maxColorAttachments;
+ return int(physDevProperties.limits.maxColorAttachments);
case QRhi::FramesInFlight:
return QVK_FRAMES_IN_FLIGHT;
default:
@@ -3736,14 +3866,25 @@ void QRhiVulkan::sendVMemStatsToProfiler()
VmaStats stats;
vmaCalculateStats(toVmaAllocator(allocator), &stats);
QRHI_PROF_F(vmemStat(stats.total.blockCount, stats.total.allocationCount,
- stats.total.usedBytes, stats.total.unusedBytes));
+ quint32(stats.total.usedBytes), quint32(stats.total.unusedBytes)));
+}
+
+bool QRhiVulkan::makeThreadLocalNativeContextCurrent()
+{
+ // not applicable
+ return false;
}
-void QRhiVulkan::makeThreadLocalNativeContextCurrent()
+void QRhiVulkan::releaseCachedResources()
{
// nothing to do here
}
+bool QRhiVulkan::isDeviceLost() const
+{
+ return deviceLost;
+}
+
QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
@@ -3831,7 +3972,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
bool hasDynamicOffsetInSrb = false;
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
+ const QRhiShaderResourceBinding::Data *b = binding.data();
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
if (QRHI_RES(QVkBuffer, b->u.ubuf.buf)->m_type == QRhiBuffer::Dynamic)
@@ -3850,7 +3991,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
// Do host writes and mark referenced shader resources as in-use.
// Also prepare to ensure the descriptor set we are going to bind refers to up-to-date Vk objects.
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
+ const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[descSetIdx][i]);
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
switch (b->type) {
@@ -3983,7 +4124,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
// and neither srb nor dynamicOffsets has any such ordering
// requirement.
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
+ const QRhiShaderResourceBinding::Data *b = binding.data();
if (b->type == QRhiShaderResourceBinding::UniformBuffer && b->u.ubuf.hasDynamicOffset) {
uint32_t offset = 0;
for (int i = 0; i < dynamicOffsetCount; ++i) {
@@ -4003,7 +4144,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
gfxPsD ? VK_PIPELINE_BIND_POINT_GRAPHICS : VK_PIPELINE_BIND_POINT_COMPUTE,
gfxPsD ? gfxPsD->layout : compPsD->layout,
0, 1, &srbD->descSets[descSetIdx],
- dynOfs.count(),
+ uint32_t(dynOfs.count()),
dynOfs.count() ? dynOfs.constData() : nullptr);
} else {
QVkCommandBuffer::Command cmd;
@@ -4073,8 +4214,8 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
}
if (cbD->useSecondaryCb) {
- df->vkCmdBindVertexBuffers(cbD->secondaryCbs.last(), startBinding,
- bufs.count(), bufs.constData(), ofs.constData());
+ df->vkCmdBindVertexBuffers(cbD->secondaryCbs.last(), uint32_t(startBinding),
+ uint32_t(bufs.count()), bufs.constData(), ofs.constData());
} else {
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::BindVertexBuffer;
@@ -4155,10 +4296,10 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport
if (!QRHI_RES(QVkGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
VkRect2D *s = &cmd.args.setScissor.scissor;
- s->offset.x = x;
- s->offset.y = y;
- s->extent.width = w;
- s->extent.height = h;
+ s->offset.x = int32_t(x);
+ s->offset.y = int32_t(y);
+ s->extent.width = uint32_t(w);
+ s->extent.height = uint32_t(h);
if (cbD->useSecondaryCb) {
df->vkCmdSetScissor(cbD->secondaryCbs.last(), 0, 1, s);
} else {
@@ -4184,8 +4325,8 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
VkRect2D *s = &cmd.args.setScissor.scissor;
s->offset.x = x;
s->offset.y = y;
- s->extent.width = w;
- s->extent.height = h;
+ s->extent.width = uint32_t(w);
+ s->extent.height = uint32_t(h);
if (cbD->useSecondaryCb) {
df->vkCmdSetScissor(cbD->secondaryCbs.last(), 0, 1, s);
@@ -4206,10 +4347,10 @@ void QRhiVulkan::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
} else {
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::SetBlendConstants;
- cmd.args.setBlendConstants.c[0] = c.redF();
- cmd.args.setBlendConstants.c[1] = c.greenF();
- cmd.args.setBlendConstants.c[2] = c.blueF();
- cmd.args.setBlendConstants.c[3] = c.alphaF();
+ cmd.args.setBlendConstants.c[0] = float(c.redF());
+ cmd.args.setBlendConstants.c[1] = float(c.greenF());
+ cmd.args.setBlendConstants.c[2] = float(c.blueF());
+ cmd.args.setBlendConstants.c[3] = float(c.alphaF());
cbD->commands.append(cmd);
}
}
@@ -4533,6 +4674,8 @@ static inline VkPrimitiveTopology toVkTopology(QRhiGraphicsPipeline::Topology t)
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case QRhiGraphicsPipeline::TriangleStrip:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+ case QRhiGraphicsPipeline::TriangleFan:
+ return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case QRhiGraphicsPipeline::Lines:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case QRhiGraphicsPipeline::LineStrip:
@@ -4711,7 +4854,7 @@ static inline void fillVkStencilOpState(VkStencilOpState *dst, const QRhiGraphic
dst->compareOp = toVkCompareOp(src.compareOp);
}
-static inline VkDescriptorType toVkDescriptorType(const QRhiShaderResourceBindingPrivate *b)
+static inline VkDescriptorType toVkDescriptorType(const QRhiShaderResourceBinding::Data *b)
{
switch (b->type) {
case QRhiShaderResourceBinding::UniformBuffer:
@@ -4838,7 +4981,7 @@ bool QVkBuffer::build()
VkBufferCreateInfo bufferInfo;
memset(&bufferInfo, 0, sizeof(bufferInfo));
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- bufferInfo.size = nonZeroSize;
+ bufferInfo.size = uint32_t(nonZeroSize);
bufferInfo.usage = toVkBufferUsage(m_usage);
VmaAllocationCreateInfo allocInfo;
@@ -4855,7 +4998,7 @@ bool QVkBuffer::build()
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
} else {
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
- bufferInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+ bufferInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
}
QRHI_RES_RHI(QRhiVulkan);
@@ -4869,11 +5012,7 @@ bool QVkBuffer::build()
err = vmaCreateBuffer(toVmaAllocator(rhiD->allocator), &bufferInfo, &allocInfo, &buffers[i], &allocation, nullptr);
if (err != VK_SUCCESS)
break;
-
allocations[i] = allocation;
- if (m_type == Dynamic)
- pendingDynamicUpdates[i].reserve(16);
-
rhiD->setObjectName(uint64_t(buffers[i]), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, m_objectName,
m_type == Dynamic ? i : -1);
}
@@ -4885,7 +5024,7 @@ bool QVkBuffer::build()
}
QRHI_PROF;
- QRHI_PROF_F(newBuffer(this, nonZeroSize, m_type != Dynamic ? 1 : QVK_FRAMES_IN_FLIGHT, 0));
+ QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), m_type != Dynamic ? 1 : QVK_FRAMES_IN_FLIGHT, 0));
lastActiveFrameSlot = -1;
generation += 1;
@@ -5076,7 +5215,7 @@ bool QVkTexture::prepareBuild(QSize *adjustedSize)
const bool isCube = m_flags.testFlag(CubeMap);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
- mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
+ mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
const int maxLevels = QRhi::MAX_LEVELS;
if (mipLevelCount > maxLevels) {
qWarning("Too many mip levels (%d, max is %d), truncating mip chain", mipLevelCount, maxLevels);
@@ -5155,8 +5294,8 @@ bool QVkTexture::build()
imageInfo.flags = isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.format = vkformat;
- imageInfo.extent.width = size.width();
- imageInfo.extent.height = size.height();
+ imageInfo.extent.width = uint32_t(size.width());
+ imageInfo.extent.height = uint32_t(size.height());
imageInfo.extent.depth = 1;
imageInfo.mipLevels = mipLevelCount;
imageInfo.arrayLayers = isCube ? 6 : 1;
@@ -5197,7 +5336,7 @@ bool QVkTexture::build()
rhiD->setObjectName(uint64_t(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, m_objectName);
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, samples));
+ QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, samples));
owns = true;
rhiD->registerResource(this);
@@ -5219,7 +5358,7 @@ bool QVkTexture::buildFrom(const QRhiNativeHandles *src)
return false;
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, samples));
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, samples));
usageState.layout = h->layout;
@@ -5255,7 +5394,7 @@ VkImageView QVkTexture::imageViewForLevel(int level)
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
- viewInfo.subresourceRange.baseMipLevel = level;
+ viewInfo.subresourceRange.baseMipLevel = uint32_t(level);
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
@@ -5450,7 +5589,8 @@ QRhiRenderPassDescriptor *QVkTextureRenderTarget::newCompatibleRenderPassDescrip
QRHI_RES_RHI(QRhiVulkan);
QVkRenderPassDescriptor *rp = new QVkRenderPassDescriptor(m_rhi);
if (!rhiD->createOffscreenRenderPass(&rp->rp,
- m_desc.colorAttachments(),
+ m_desc.cbeginColorAttachments(),
+ m_desc.cendColorAttachments(),
m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents),
m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents),
m_desc.depthStencilBuffer(),
@@ -5470,18 +5610,20 @@ bool QVkTextureRenderTarget::build()
if (d.fb)
release();
- const QVector<QRhiColorAttachment> colorAttachments = m_desc.colorAttachments();
- Q_ASSERT(!colorAttachments.isEmpty() || m_desc.depthTexture());
+ const bool hasColorAttachments = m_desc.cbeginColorAttachments() != m_desc.cendColorAttachments();
+ Q_ASSERT(hasColorAttachments || m_desc.depthTexture());
Q_ASSERT(!m_desc.depthStencilBuffer() || !m_desc.depthTexture());
const bool hasDepthStencil = m_desc.depthStencilBuffer() || m_desc.depthTexture();
QRHI_RES_RHI(QRhiVulkan);
QVarLengthArray<VkImageView, 8> views;
- d.colorAttCount = colorAttachments.count();
- for (int i = 0; i < d.colorAttCount; ++i) {
- QVkTexture *texD = QRHI_RES(QVkTexture, colorAttachments[i].texture());
- QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, colorAttachments[i].renderBuffer());
+ d.colorAttCount = 0;
+ int attIndex = 0;
+ for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
+ d.colorAttCount += 1;
+ QVkTexture *texD = QRHI_RES(QVkTexture, it->texture());
+ QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer());
Q_ASSERT(texD || rbD);
if (texD) {
Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget));
@@ -5496,24 +5638,24 @@ bool QVkTextureRenderTarget::build()
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- viewInfo.subresourceRange.baseMipLevel = colorAttachments[i].level();
+ viewInfo.subresourceRange.baseMipLevel = uint32_t(it->level());
viewInfo.subresourceRange.levelCount = 1;
- viewInfo.subresourceRange.baseArrayLayer = colorAttachments[i].layer();
+ viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->layer());
viewInfo.subresourceRange.layerCount = 1;
- VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[i]);
+ VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[attIndex]);
if (err != VK_SUCCESS) {
qWarning("Failed to create render target image view: %d", err);
return false;
}
- views.append(rtv[i]);
- if (i == 0) {
+ views.append(rtv[attIndex]);
+ if (attIndex == 0) {
d.pixelSize = texD->pixelSize();
d.sampleCount = texD->samples;
}
} else if (rbD) {
Q_ASSERT(rbD->backingTexture);
views.append(rbD->backingTexture->imageView);
- if (i == 0) {
+ if (attIndex == 0) {
d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples;
}
@@ -5543,9 +5685,10 @@ bool QVkTextureRenderTarget::build()
}
d.resolveAttCount = 0;
- for (int i = 0; i < d.colorAttCount; ++i) {
- if (colorAttachments[i].resolveTexture()) {
- QVkTexture *resTexD = QRHI_RES(QVkTexture, colorAttachments[i].resolveTexture());
+ attIndex = 0;
+ for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
+ if (it->resolveTexture()) {
+ QVkTexture *resTexD = QRHI_RES(QVkTexture, it->resolveTexture());
Q_ASSERT(resTexD->flags().testFlag(QRhiTexture::RenderTarget));
d.resolveAttCount += 1;
@@ -5560,16 +5703,16 @@ bool QVkTextureRenderTarget::build()
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- viewInfo.subresourceRange.baseMipLevel = colorAttachments[i].resolveLevel();
+ viewInfo.subresourceRange.baseMipLevel = uint32_t(it->resolveLevel());
viewInfo.subresourceRange.levelCount = 1;
- viewInfo.subresourceRange.baseArrayLayer = colorAttachments[i].resolveLayer();
+ viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->resolveLayer());
viewInfo.subresourceRange.layerCount = 1;
- VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[i]);
+ VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[attIndex]);
if (err != VK_SUCCESS) {
qWarning("Failed to create render target resolve image view: %d", err);
return false;
}
- views.append(resrtv[i]);
+ views.append(resrtv[attIndex]);
}
}
@@ -5583,10 +5726,10 @@ bool QVkTextureRenderTarget::build()
memset(&fbInfo, 0, sizeof(fbInfo));
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbInfo.renderPass = d.rp->rp;
- fbInfo.attachmentCount = d.colorAttCount + d.dsAttCount + d.resolveAttCount;
+ fbInfo.attachmentCount = uint32_t(d.colorAttCount + d.dsAttCount + d.resolveAttCount);
fbInfo.pAttachments = views.constData();
- fbInfo.width = d.pixelSize.width();
- fbInfo.height = d.pixelSize.height();
+ fbInfo.width = uint32_t(d.pixelSize.width());
+ fbInfo.height = uint32_t(d.pixelSize.height());
fbInfo.layers = 1;
VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo, nullptr, &d.fb);
@@ -5658,19 +5801,20 @@ bool QVkShaderResourceBindings::build()
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
descSets[i] = VK_NULL_HANDLE;
- sortedBindings = m_bindings;
+ sortedBindings.clear();
+ std::copy(m_bindings.cbegin(), m_bindings.cend(), std::back_inserter(sortedBindings));
std::sort(sortedBindings.begin(), sortedBindings.end(),
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
{
- return QRhiShaderResourceBindingPrivate::get(&a)->binding < QRhiShaderResourceBindingPrivate::get(&b)->binding;
+ return a.data()->binding < b.data()->binding;
});
QVarLengthArray<VkDescriptorSetLayoutBinding, 4> vkbindings;
for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) {
- const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
+ const QRhiShaderResourceBinding::Data *b = binding.data();
VkDescriptorSetLayoutBinding vkbinding;
memset(&vkbinding, 0, sizeof(vkbinding));
- vkbinding.binding = b->binding;
+ vkbinding.binding = uint32_t(b->binding);
vkbinding.descriptorType = toVkDescriptorType(b);
vkbinding.descriptorCount = 1; // no array support yet
vkbinding.stageFlags = toVkShaderStageFlags(b->stage);
@@ -5746,6 +5890,9 @@ bool QVkGraphicsPipeline::build()
release();
QRHI_RES_RHI(QRhiVulkan);
+ if (!rhiD->sanityCheckGraphicsPipeline(this))
+ return false;
+
if (!rhiD->ensurePipelineCache())
return false;
@@ -5787,25 +5934,24 @@ bool QVkGraphicsPipeline::build()
shaderStageCreateInfos.append(shaderInfo);
}
}
- pipelineInfo.stageCount = shaderStageCreateInfos.count();
+ pipelineInfo.stageCount = uint32_t(shaderStageCreateInfos.count());
pipelineInfo.pStages = shaderStageCreateInfos.constData();
- const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
QVarLengthArray<VkVertexInputBindingDescription, 4> vertexBindings;
QVarLengthArray<VkVertexInputBindingDivisorDescriptionEXT> nonOneStepRates;
- for (int i = 0, ie = bindings.count(); i != ie; ++i) {
- const QRhiVertexInputBinding &binding(bindings[i]);
+ int bindingIndex = 0;
+ for (auto it = m_vertexInputLayout.cbeginBindings(), itEnd = m_vertexInputLayout.cendBindings();
+ it != itEnd; ++it, ++bindingIndex)
+ {
VkVertexInputBindingDescription bindingInfo = {
- uint32_t(i),
- binding.stride(),
- binding.classification() == QRhiVertexInputBinding::PerVertex
+ uint32_t(bindingIndex),
+ it->stride(),
+ it->classification() == QRhiVertexInputBinding::PerVertex
? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE
};
- if (binding.classification() == QRhiVertexInputBinding::PerInstance
- && binding.instanceStepRate() != 1)
- {
+ if (it->classification() == QRhiVertexInputBinding::PerInstance && it->instanceStepRate() != 1) {
if (rhiD->vertexAttribDivisorAvailable) {
- nonOneStepRates.append({ uint32_t(i), uint32_t(binding.instanceStepRate()) });
+ nonOneStepRates.append({ uint32_t(bindingIndex), uint32_t(it->instanceStepRate()) });
} else {
qWarning("QRhiVulkan: Instance step rates other than 1 not supported without "
"VK_EXT_vertex_attribute_divisor on the device and "
@@ -5814,29 +5960,30 @@ bool QVkGraphicsPipeline::build()
}
vertexBindings.append(bindingInfo);
}
- const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
QVarLengthArray<VkVertexInputAttributeDescription, 4> vertexAttributes;
- for (const QRhiVertexInputAttribute &attribute : attributes) {
+ for (auto it = m_vertexInputLayout.cbeginAttributes(), itEnd = m_vertexInputLayout.cendAttributes();
+ it != itEnd; ++it)
+ {
VkVertexInputAttributeDescription attributeInfo = {
- uint32_t(attribute.location()),
- uint32_t(attribute.binding()),
- toVkAttributeFormat(attribute.format()),
- attribute.offset()
+ uint32_t(it->location()),
+ uint32_t(it->binding()),
+ toVkAttributeFormat(it->format()),
+ it->offset()
};
vertexAttributes.append(attributeInfo);
}
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
memset(&vertexInputInfo, 0, sizeof(vertexInputInfo));
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
- vertexInputInfo.vertexBindingDescriptionCount = vertexBindings.count();
+ vertexInputInfo.vertexBindingDescriptionCount = uint32_t(vertexBindings.count());
vertexInputInfo.pVertexBindingDescriptions = vertexBindings.constData();
- vertexInputInfo.vertexAttributeDescriptionCount = vertexAttributes.count();
+ vertexInputInfo.vertexAttributeDescriptionCount = uint32_t(vertexAttributes.count());
vertexInputInfo.pVertexAttributeDescriptions = vertexAttributes.constData();
VkPipelineVertexInputDivisorStateCreateInfoEXT divisorInfo;
if (!nonOneStepRates.isEmpty()) {
memset(&divisorInfo, 0, sizeof(divisorInfo));
divisorInfo.sType = VkStructureType(1000190001); // VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT
- divisorInfo.vertexBindingDivisorCount = nonOneStepRates.count();
+ divisorInfo.vertexBindingDivisorCount = uint32_t(nonOneStepRates.count());
divisorInfo.pVertexBindingDivisors = nonOneStepRates.constData();
vertexInputInfo.pNext = &divisorInfo;
}
@@ -5853,7 +6000,7 @@ bool QVkGraphicsPipeline::build()
VkPipelineDynamicStateCreateInfo dynamicInfo;
memset(&dynamicInfo, 0, sizeof(dynamicInfo));
dynamicInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
- dynamicInfo.dynamicStateCount = dynEnable.count();
+ dynamicInfo.dynamicStateCount = uint32_t(dynEnable.count());
dynamicInfo.pDynamicStates = dynEnable.constData();
pipelineInfo.pDynamicState = &dynamicInfo;
@@ -5925,7 +6072,7 @@ bool QVkGraphicsPipeline::build()
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
vktargetBlends.append(blend);
}
- blendInfo.attachmentCount = vktargetBlends.count();
+ blendInfo.attachmentCount = uint32_t(vktargetBlends.count());
blendInfo.pAttachments = vktargetBlends.constData();
pipelineInfo.pColorBlendState = &blendInfo;
@@ -6126,11 +6273,11 @@ QSize QVkSwapChain::surfacePixelSize()
QRHI_RES_RHI(QRhiVulkan);
rhiD->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(rhiD->physDev, surface, &surfaceCaps);
VkExtent2D bufferSize = surfaceCaps.currentExtent;
- if (bufferSize.width == quint32(-1)) {
- Q_ASSERT(bufferSize.height == quint32(-1));
+ if (bufferSize.width == uint32_t(-1)) {
+ Q_ASSERT(bufferSize.height == uint32_t(-1));
return m_window->size() * m_window->devicePixelRatio();
}
- return QSize(bufferSize.width, bufferSize.height);
+ return QSize(int(bufferSize.width), int(bufferSize.height));
}
QRhiRenderPassDescriptor *QVkSwapChain::newCompatibleRenderPassDescriptor()
@@ -6198,7 +6345,7 @@ bool QVkSwapChain::ensureSurface()
QRHI_RES_RHI(QRhiVulkan);
if (rhiD->gfxQueueFamilyIdx != -1) {
- if (!rhiD->inst->supportsPresent(rhiD->physDev, rhiD->gfxQueueFamilyIdx, m_window)) {
+ if (!rhiD->inst->supportsPresent(rhiD->physDev, uint32_t(rhiD->gfxQueueFamilyIdx), m_window)) {
qWarning("Presenting not supported on this window");
return false;
}
@@ -6227,7 +6374,7 @@ bool QVkSwapChain::ensureSurface()
rhiD->vkGetPhysicalDeviceSurfaceFormatsKHR(rhiD->physDev, surface, &formatCount, formats.data());
const bool srgbRequested = m_flags.testFlag(sRGB);
- for (quint32 i = 0; i < formatCount; ++i) {
+ for (int i = 0; i < int(formatCount); ++i) {
if (formats[i].format != VK_FORMAT_UNDEFINED && srgbRequested == isSrgbFormat(formats[i].format)) {
colorFormat = formats[i].format;
colorSpace = formats[i].colorSpace;
@@ -6276,9 +6423,16 @@ bool QVkSwapChain::buildOrResize()
m_depthStencil->sampleCount(), m_sampleCount);
}
if (m_depthStencil && m_depthStencil->pixelSize() != pixelSize) {
- qWarning("Depth-stencil buffer's size (%dx%d) does not match the surface size (%dx%d). Expect problems.",
- m_depthStencil->pixelSize().width(), m_depthStencil->pixelSize().height(),
- pixelSize.width(), pixelSize.height());
+ if (m_depthStencil->flags().testFlag(QRhiRenderBuffer::UsedWithSwapChainOnly)) {
+ m_depthStencil->setPixelSize(pixelSize);
+ if (!m_depthStencil->build())
+ qWarning("Failed to rebuild swapchain's associated depth-stencil buffer for size %dx%d",
+ pixelSize.width(), pixelSize.height());
+ } else {
+ qWarning("Depth-stencil buffer's size (%dx%d) does not match the surface size (%dx%d). Expect problems.",
+ m_depthStencil->pixelSize().width(), m_depthStencil->pixelSize().height(),
+ pixelSize.width(), pixelSize.height());
+ }
}
if (!m_renderPassDesc)
@@ -6288,7 +6442,7 @@ bool QVkSwapChain::buildOrResize()
Q_ASSERT(rtWrapper.d.rp && rtWrapper.d.rp->rp);
rtWrapper.d.pixelSize = pixelSize;
- rtWrapper.d.dpr = window->devicePixelRatio();
+ rtWrapper.d.dpr = float(window->devicePixelRatio());
rtWrapper.d.sampleCount = samples;
rtWrapper.d.colorAttCount = 1;
if (m_depthStencil) {
@@ -6315,10 +6469,10 @@ bool QVkSwapChain::buildOrResize()
memset(&fbInfo, 0, sizeof(fbInfo));
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbInfo.renderPass = rtWrapper.d.rp->rp;
- fbInfo.attachmentCount = rtWrapper.d.colorAttCount + rtWrapper.d.dsAttCount + rtWrapper.d.resolveAttCount;
+ fbInfo.attachmentCount = uint32_t(rtWrapper.d.colorAttCount + rtWrapper.d.dsAttCount + rtWrapper.d.resolveAttCount);
fbInfo.pAttachments = views;
- fbInfo.width = pixelSize.width();
- fbInfo.height = pixelSize.height();
+ fbInfo.width = uint32_t(pixelSize.width());
+ fbInfo.height = uint32_t(pixelSize.height());
fbInfo.layers = 1;
VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo, nullptr, &image.fb);
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index 962a1b8eb7..d0e1e6758b 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -79,7 +79,7 @@ struct QVkBuffer : public QRhiBuffer
VkBuffer buffers[QVK_FRAMES_IN_FLIGHT];
QVkAlloc allocations[QVK_FRAMES_IN_FLIGHT];
- QVector<QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate> pendingDynamicUpdates[QVK_FRAMES_IN_FLIGHT];
+ QVarLengthArray<QRhiResourceUpdateBatchPrivate::BufferOp, 16> pendingDynamicUpdates[QVK_FRAMES_IN_FLIGHT];
VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT];
QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT];
struct UsageState {
@@ -232,7 +232,7 @@ struct QVkShaderResourceBindings : public QRhiShaderResourceBindings
void release() override;
bool build() override;
- QVector<QRhiShaderResourceBinding> sortedBindings;
+ QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
int poolIndex = -1;
VkDescriptorSetLayout layout = VK_NULL_HANDLE;
VkDescriptorSet descSets[QVK_FRAMES_IN_FLIGHT]; // multiple sets to support dynamic buffers
@@ -268,7 +268,7 @@ struct QVkShaderResourceBindings : public QRhiShaderResourceBindings
BoundStorageBufferData sbuf;
};
};
- QVector<BoundResourceData> boundResourceData[QVK_FRAMES_IN_FLIGHT];
+ QVarLengthArray<BoundResourceData, 8> boundResourceData[QVK_FRAMES_IN_FLIGHT];
friend class QRhiVulkan;
};
@@ -711,7 +711,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
VkResult createDescriptorPool(VkDescriptorPool *pool);
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
@@ -730,7 +732,8 @@ public:
VkSampleCountFlagBits samples,
VkFormat colorFormat);
bool createOffscreenRenderPass(VkRenderPass *rp,
- const QVector<QRhiColorAttachment> &colorAttachments,
+ const QRhiColorAttachment *firstColorAttachment,
+ const QRhiColorAttachment *lastColorAttachment,
bool preserveColor,
bool preserveDs,
QRhiRenderBuffer *depthStencilBuffer,
@@ -803,6 +806,7 @@ public:
VkDeviceSize ubufAlign;
VkDeviceSize texbufAlign;
bool hasWideLines = false;
+ bool deviceLost = false;
bool debugMarkersAvailable = false;
bool vertexAttribDivisorAvailable = false;
@@ -849,17 +853,25 @@ public:
VkFence cmdFence = VK_NULL_HANDLE;
} ofr;
- struct ActiveReadback {
+ struct TextureReadback {
int activeFrameSlot = -1;
QRhiReadbackDescription desc;
QRhiReadbackResult *result;
- VkBuffer buf;
- QVkAlloc bufAlloc;
- quint32 bufSize;
+ VkBuffer stagingBuf;
+ QVkAlloc stagingAlloc;
+ quint32 byteSize;
QSize pixelSize;
QRhiTexture::Format format;
};
- QVector<ActiveReadback> activeReadbacks;
+ QVector<TextureReadback> activeTextureReadbacks;
+ struct BufferReadback {
+ int activeFrameSlot = -1;
+ QRhiBufferReadbackResult *result;
+ int byteSize;
+ VkBuffer stagingBuf;
+ QVkAlloc stagingAlloc;
+ };
+ QVector<BufferReadback> activeBufferReadbacks;
struct DeferredReleaseEntry {
enum Type {
@@ -929,7 +941,8 @@ public:
Q_DECLARE_TYPEINFO(QRhiVulkan::DescriptorPoolData, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiVulkan::DeferredReleaseEntry, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QRhiVulkan::ActiveReadback, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QRhiVulkan::TextureReadback, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QRhiVulkan::BufferReadback, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
diff --git a/src/gui/rhi/qshader.cpp b/src/gui/rhi/qshader.cpp
index 72ce53c87a..6a2c596557 100644
--- a/src/gui/rhi/qshader.cpp
+++ b/src/gui/rhi/qshader.cpp
@@ -450,7 +450,7 @@ QShaderKey::QShaderKey(QShader::Source s,
}
/*!
- Returns \c true if the two QShader objects \a a and \a b are equal,
+ Returns \c true if the two QShader objects \a lhs and \a rhs are equal,
meaning they are for the same stage with matching sets of shader source or
binary code.
@@ -486,7 +486,7 @@ uint qHash(const QShader &s, uint seed) Q_DECL_NOTHROW
}
/*!
- Returns \c true if the two QShaderVersion objects \a a and \a b are
+ Returns \c true if the two QShaderVersion objects \a lhs and \a rhs are
equal.
\relates QShaderVersion
@@ -506,7 +506,7 @@ bool operator==(const QShaderVersion &lhs, const QShaderVersion &rhs) Q_DECL_NOT
*/
/*!
- Returns \c true if the two QShaderKey objects \a a and \a b are equal.
+ Returns \c true if the two QShaderKey objects \a lhs and \a rhs are equal.
\relates QShaderKey
*/
@@ -536,7 +536,7 @@ uint qHash(const QShaderKey &k, uint seed) Q_DECL_NOTHROW
}
/*!
- Returns \c true if the two QShaderCode objects \a a and \a b are equal.
+ Returns \c true if the two QShaderCode objects \a lhs and \a rhs are equal.
\relates QShaderCode
*/
diff --git a/src/gui/rhi/qshaderdescription.cpp b/src/gui/rhi/qshaderdescription.cpp
index c38a83c497..179d5f3a07 100644
--- a/src/gui/rhi/qshaderdescription.cpp
+++ b/src/gui/rhi/qshaderdescription.cpp
@@ -1022,7 +1022,7 @@ void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc)
return;
}
- Q_ASSERT(ref.load() == 1); // must be detached
+ Q_ASSERT(ref.loadRelaxed() == 1); // must be detached
inVars.clear();
outVars.clear();
diff --git a/src/gui/rhi/tdr.hlsl b/src/gui/rhi/tdr.hlsl
new file mode 100644
index 0000000000..f79de91c4a
--- /dev/null
+++ b/src/gui/rhi/tdr.hlsl
@@ -0,0 +1,9 @@
+RWBuffer<uint> uav;
+cbuffer ConstantBuffer { uint zero; }
+
+[numthreads(256, 1, 1)]
+void killDeviceByTimingOut(uint3 id: SV_DispatchThreadID)
+{
+ while (zero == 0)
+ uav[id.x] = zero;
+}
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index 5263ece87c..8b8f3e28ac 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -660,7 +660,7 @@ QTextBlock QAbstractTextDocumentLayout::blockWithMarkerAt(const QPointF &pos) co
{
QTextBlock block = document()->firstBlock();
while (block.isValid()) {
- if (block.blockFormat().marker() != QTextBlockFormat::NoMarker) {
+ if (block.blockFormat().marker() != QTextBlockFormat::MarkerType::NoMarker) {
QRectF blockBr = blockBoundingRect(block);
QTextBlockFormat blockFmt = block.blockFormat();
QFontMetrics fm(block.charFormat().font());
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 3c1a052f37..76fde5388c 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -2096,10 +2096,11 @@ uint qHash(const QFont &font, uint seed) noexcept
*/
bool QFont::fromString(const QString &descrip)
{
- const auto l = descrip.splitRef(QLatin1Char(','));
-
- int count = l.count();
- if (!count || (count > 2 && count < 9) || count > 11) {
+ const QStringRef sr = QStringRef(&descrip).trimmed();
+ const auto l = sr.split(QLatin1Char(','));
+ const int count = l.count();
+ if (!count || (count > 2 && count < 9) || count > 11 ||
+ l.first().isEmpty()) {
qWarning("QFont::fromString: Invalid description '%s'",
descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
return false;
@@ -3175,8 +3176,7 @@ QDebug operator<<(QDebug stream, const QFont &font)
QDebug debug(&fontDescription);
debug.nospace();
- QFontPrivate priv;
- const QFont defaultFont(&priv);
+ const QFont defaultFont(new QFontPrivate);
for (int property = QFont::FamilyResolved; property < QFont::AllPropertiesResolved; property <<= 1) {
const bool resolved = (font.resolve_mask & property) != 0;
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index ce6bb0c347..261e1d831b 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2684,7 +2684,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
QtFontDesc desc;
QList<int> blackListed;
int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
- if (index < 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases()) {
+ if (index < 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases(family_name)) {
// We populated familiy aliases (e.g. localized families), so try again
index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
}
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 80b092f177..63e6b48e4f 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE
class QStringList;
-template <class T> class QList;
struct QFontDef;
class QFontEngine;
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 38ba7f10b2..f79c5db625 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -104,7 +104,7 @@ class Q_GUI_EXPORT QPlatformFontDatabase
public:
virtual ~QPlatformFontDatabase();
virtual void populateFontDatabase();
- virtual bool populateFamilyAliases() { return false; }
+ virtual bool populateFamilyAliases(const QString &missingFamily) { Q_UNUSED(missingFamily); return false; }
virtual void populateFamily(const QString &familyName);
virtual void invalidate();
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index c80617f929..22c249d604 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1970,9 +1970,12 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
QRectF body = QRectF(QPointF(0, 0), d->pageSize);
QPointF pageNumberPos;
+ qreal sourceDpiX = qt_defaultDpiX();
+ qreal sourceDpiY = qt_defaultDpiY();
+ const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX;
+ const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY;
+
if (documentPaginated) {
- qreal sourceDpiX = qt_defaultDpi();
- qreal sourceDpiY = sourceDpiX;
QPaintDevice *dev = doc->documentLayout()->paintDevice();
if (dev) {
@@ -1980,9 +1983,6 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
sourceDpiY = dev->logicalDpiY();
}
- const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX;
- const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY;
-
// scale to dpi
p.scale(dpiScaleX, dpiScaleY);
@@ -2011,15 +2011,21 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
// copy the custom object handlers
layout->d_func()->handlers = documentLayout()->d_func()->handlers;
- int dpiy = p.device()->logicalDpiY();
- int margin = (int) ((2/2.54)*dpiy); // 2 cm margins
+ // 2 cm margins, scaled to device in QTextDocumentLayoutPrivate::layoutFrame
+ const int horizontalMargin = int((2/2.54)*sourceDpiX);
+ const int verticalMargin = int((2/2.54)*sourceDpiY);
QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
- fmt.setMargin(margin);
+ fmt.setLeftMargin(horizontalMargin);
+ fmt.setRightMargin(horizontalMargin);
+ fmt.setTopMargin(verticalMargin);
+ fmt.setBottomMargin(verticalMargin);
doc->rootFrame()->setFrameFormat(fmt);
+ // pageNumberPos must be in device coordinates, so scale to device here
+ const int dpiy = p.device()->logicalDpiY();
body = QRectF(0, 0, printer->width(), printer->height());
- pageNumberPos = QPointF(body.width() - margin,
- body.height() - margin
+ pageNumberPos = QPointF(body.width() - horizontalMargin * dpiScaleX,
+ body.height() - verticalMargin * dpiScaleY
+ QFontMetrics(doc->defaultFont(), p.device()).ascent()
+ 5 * dpiy / 72.0);
clonedDoc->setPageSize(body.size());
@@ -2067,8 +2073,9 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
\enum QTextDocument::ResourceType
This enum describes the types of resources that can be loaded by
- QTextDocument's loadResource() function.
+ QTextDocument's loadResource() function or by QTextBrowser::setSource().
+ \value UnknownResource No resource is loaded, or the resource type is not known.
\value HtmlResource The resource contains HTML.
\value ImageResource The resource contains image data.
Currently supported data types are QVariant::Pixmap and
@@ -2082,7 +2089,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
\value UserResource The first available value for user defined
resource types.
- \sa loadResource()
+ \sa loadResource(), QTextBrowser::sourceType()
*/
/*!
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index 723e5c907c..742c56382d 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -1062,6 +1062,7 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
fmt.setLeftPadding(leftPadding(currentNodeIdx));
if (rightPadding(currentNodeIdx) >= 0)
fmt.setRightPadding(rightPadding(currentNodeIdx));
+#ifndef QT_NO_CSSPARSER
if (tableCellBorder(currentNodeIdx, QCss::TopEdge) > 0)
fmt.setTopBorder(tableCellBorder(currentNodeIdx, QCss::TopEdge));
if (tableCellBorder(currentNodeIdx, QCss::RightEdge) > 0)
@@ -1086,6 +1087,7 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
fmt.setBottomBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::BottomEdge));
if (tableCellBorderBrush(currentNodeIdx, QCss::LeftEdge) != Qt::NoBrush)
fmt.setLeftBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::LeftEdge));
+#endif
cell.setFormat(fmt);
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index b02723c047..7be114adf9 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -265,6 +265,9 @@ public:
inline QFixed topPadding(QTextTable *table, const QTextTableCell &cell) const
{
+#ifdef QT_NO_CSSPARSER
+ Q_UNUSED(table);
+#endif
return paddingProperty(cell.format(), QTextFormat::TableCellTopPadding)
#ifndef QT_NO_CSSPARSER
+ cellBorderWidth(table, cell, QCss::TopEdge)
@@ -274,6 +277,9 @@ public:
inline QFixed bottomPadding(QTextTable *table, const QTextTableCell &cell) const
{
+#ifdef QT_NO_CSSPARSER
+ Q_UNUSED(table);
+#endif
return paddingProperty(cell.format(), QTextFormat::TableCellBottomPadding)
#ifndef QT_NO_CSSPARSER
+ cellBorderWidth(table, cell, QCss::BottomEdge)
@@ -283,6 +289,9 @@ public:
inline QFixed leftPadding(QTextTable *table, const QTextTableCell &cell) const
{
+#ifdef QT_NO_CSSPARSER
+ Q_UNUSED(table);
+#endif
return paddingProperty(cell.format(), QTextFormat::TableCellLeftPadding)
#ifndef QT_NO_CSSPARSER
+ cellBorderWidth(table, cell, QCss::LeftEdge)
@@ -292,6 +301,9 @@ public:
inline QFixed rightPadding(QTextTable *table, const QTextTableCell &cell) const
{
+#ifdef QT_NO_CSSPARSER
+ Q_UNUSED(table);
+#endif
return paddingProperty(cell.format(), QTextFormat::TableCellRightPadding)
#ifndef QT_NO_CSSPARSER
+ cellBorderWidth(table, cell, QCss::RightEdge)
@@ -1034,15 +1046,22 @@ static bool cellClipTest(QTextTable *table, QTextTableData *td,
const QTextTableCell &cell,
QRectF cellRect)
{
+#ifdef QT_NO_CSSPARSER
+ Q_UNUSED(table);
+ Q_UNUSED(cell);
+#endif
+
if (!cell_context.clip.isValid())
return false;
if (td->borderCollapse) {
// we need to account for the cell borders in the clipping test
+#ifndef QT_NO_CSSPARSER
cellRect.adjust(-axisEdgeData(table, td, cell, QCss::LeftEdge).width / 2,
-axisEdgeData(table, td, cell, QCss::TopEdge).width / 2,
axisEdgeData(table, td, cell, QCss::RightEdge).width / 2,
axisEdgeData(table, td, cell, QCss::BottomEdge).width / 2);
+#endif
} else {
qreal border = td->border.toReal();
cellRect.adjust(-border, -border, border, border);
@@ -1798,6 +1817,13 @@ void QTextDocumentLayoutPrivate::drawTableCellBorder(const QRectF &cellRect, QPa
if (turn_off_antialiasing)
painter->setRenderHint(QPainter::Antialiasing, false);
+#else
+ Q_UNUSED(cell);
+ Q_UNUSED(cellRect);
+ Q_UNUSED(painter);
+ Q_UNUSED(table);
+ Q_UNUSED(td);
+ Q_UNUSED(cell);
#endif
}
@@ -2168,11 +2194,11 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
QBrush brush = context.palette.brush(QPalette::Text);
- bool marker = bl.blockFormat().marker() != QTextBlockFormat::NoMarker;
+ bool marker = bl.blockFormat().marker() != QTextBlockFormat::MarkerType::NoMarker;
if (marker) {
int adj = fontMetrics.lineSpacing() / 6;
r.adjust(-adj, 0, -adj, 0);
- if (bl.blockFormat().marker() == QTextBlockFormat::Checked) {
+ if (bl.blockFormat().marker() == QTextBlockFormat::MarkerType::Checked) {
// ### Qt6: render with QStyle / PE_IndicatorCheckBox. We don't currently
// have access to that here, because it would be a widget dependency.
painter->setPen(QPen(painter->pen().color(), 2));
@@ -2285,12 +2311,14 @@ QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QT
+ td->border
+ td->paddingProperty(cell.format(), QTextFormat::TableCellTopPadding); // top cell-border is not repeated
+#ifndef QT_NO_CSSPARSER
const int headerRowCount = t->format().headerRowCount();
if (td->borderCollapse && headerRowCount > 0) {
// consider the header row's bottom edge width
qreal headerRowBottomBorderWidth = axisEdgeData(t, td, t->cellAt(headerRowCount - 1, cell.column()), QCss::BottomEdge).width;
layoutStruct.pageTopMargin += QFixed::fromReal(scaleToDevice(headerRowBottomBorderWidth) / 2);
}
+#endif
layoutStruct.pageBottomMargin = td->effectiveBottomMargin + td->cellSpacing + td->effectiveBottomBorder + td->bottomPadding(t, cell);
layoutStruct.pageBottom = (currentPage + 1) * layoutStruct.pageHeight - layoutStruct.pageBottomMargin;
@@ -2915,24 +2943,24 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
{
QTextFrameFormat fformat = f->frameFormat();
// set sizes of this frame from the format
- QFixed tm = QFixed::fromReal(fformat.topMargin());
+ QFixed tm = QFixed::fromReal(scaleToDevice(fformat.topMargin())).round();
if (tm != fd->topMargin) {
fd->topMargin = tm;
fullLayout = true;
}
- QFixed bm = QFixed::fromReal(fformat.bottomMargin());
+ QFixed bm = QFixed::fromReal(scaleToDevice(fformat.bottomMargin())).round();
if (bm != fd->bottomMargin) {
fd->bottomMargin = bm;
fullLayout = true;
}
- fd->leftMargin = QFixed::fromReal(fformat.leftMargin());
- fd->rightMargin = QFixed::fromReal(fformat.rightMargin());
- QFixed b = QFixed::fromReal(fformat.border());
+ fd->leftMargin = QFixed::fromReal(scaleToDevice(fformat.leftMargin())).round();
+ fd->rightMargin = QFixed::fromReal(scaleToDevice(fformat.rightMargin())).round();
+ QFixed b = QFixed::fromReal(scaleToDevice(fformat.border())).round();
if (b != fd->border) {
fd->border = b;
fullLayout = true;
}
- QFixed p = QFixed::fromReal(fformat.padding());
+ QFixed p = QFixed::fromReal(scaleToDevice(fformat.padding())).round();
if (p != fd->padding) {
fd->padding = p;
fullLayout = true;
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c267ade0c2..b37353bf2c 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -399,6 +399,7 @@ struct QBidiAlgorithm {
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
runHasContent = true;
lastRunWithContent = -1;
+ ++isolatePairPosition;
}
int runBeforeIsolate = runs.size();
ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
@@ -440,21 +441,19 @@ struct QBidiAlgorithm {
doEmbed(true, true, false);
break;
case QChar::DirLRI:
- Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(false, false, true);
- ++isolatePairPosition;
break;
case QChar::DirRLI:
- Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(true, false, true);
- ++isolatePairPosition;
break;
case QChar::DirFSI: {
- const auto &pair = isolatePairs.at(isolatePairPosition);
- Q_ASSERT(pair.start == i);
- bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+ bool isRtl = false;
+ if (isolatePairPosition < isolatePairs.size()) {
+ const auto &pair = isolatePairs.at(isolatePairPosition);
+ Q_ASSERT(pair.start == i);
+ isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+ }
doEmbed(isRtl, false, true);
- ++isolatePairPosition;
break;
}
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 47a38db3ad..e3bd49a15e 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -650,6 +650,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value TableColumns
\value TableColumnWidthConstraints
\value TableHeaderRowCount
+ \value TableBorderCollapse Specifies the \l QTextTableFormat::borderCollapse property.
Table cell properties
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index 12f14a1555..28da0fe344 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -627,7 +627,7 @@ public:
LineDistanceHeight = 4
};
- enum MarkerType {
+ enum class MarkerType {
NoMarker = 0,
Unchecked = 1,
Checked = 2
diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp
index b96263f5fc..fe7e422923 100644
--- a/src/gui/text/qtextmarkdownimporter.cpp
+++ b/src/gui/text/qtextmarkdownimporter.cpp
@@ -190,8 +190,8 @@ int QTextMarkdownImporter::cbEnterBlock(int blockType, void *det)
m_listItem = true;
MD_BLOCK_LI_DETAIL *detail = static_cast<MD_BLOCK_LI_DETAIL *>(det);
m_markerType = detail->is_task ?
- (detail->task_mark == ' ' ? QTextBlockFormat::Unchecked : QTextBlockFormat::Checked) :
- QTextBlockFormat::NoMarker;
+ (detail->task_mark == ' ' ? QTextBlockFormat::MarkerType::Unchecked : QTextBlockFormat::MarkerType::Checked) :
+ QTextBlockFormat::MarkerType::NoMarker;
qCDebug(lcMD) << "LI";
} break;
case MD_BLOCK_UL: {
@@ -549,7 +549,7 @@ void QTextMarkdownImporter::insertBlock()
blockFormat.setTopMargin(m_paragraphMargin);
blockFormat.setBottomMargin(m_paragraphMargin);
}
- if (m_markerType == QTextBlockFormat::NoMarker)
+ if (m_markerType == QTextBlockFormat::MarkerType::NoMarker)
blockFormat.clearProperty(QTextFormat::BlockMarker);
else
blockFormat.setMarker(m_markerType);
diff --git a/src/gui/text/qtextmarkdownimporter_p.h b/src/gui/text/qtextmarkdownimporter_p.h
index 1b8c2ca354..35655aff8a 100644
--- a/src/gui/text/qtextmarkdownimporter_p.h
+++ b/src/gui/text/qtextmarkdownimporter_p.h
@@ -128,7 +128,7 @@ private:
Features m_features;
QTextImageFormat m_imageFormat;
QTextListFormat m_listFormat;
- QTextBlockFormat::MarkerType m_markerType = QTextBlockFormat::NoMarker;
+ QTextBlockFormat::MarkerType m_markerType = QTextBlockFormat::MarkerType::NoMarker;
bool m_needsInsertBlock = false;
bool m_needsInsertList = false;
bool m_listItem = false; // true from the beginning of LI to the end of the first P
diff --git a/src/gui/text/qtextmarkdownwriter.cpp b/src/gui/text/qtextmarkdownwriter.cpp
index cbfb092485..764c64aead 100644
--- a/src/gui/text/qtextmarkdownwriter.cpp
+++ b/src/gui/text/qtextmarkdownwriter.cpp
@@ -327,10 +327,10 @@ int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ign
break;
}
switch (blockFmt.marker()) {
- case QTextBlockFormat::Checked:
+ case QTextBlockFormat::MarkerType::Checked:
bullet += " [x]";
break;
- case QTextBlockFormat::Unchecked:
+ case QTextBlockFormat::MarkerType::Unchecked:
bullet += " [ ]";
break;
default:
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 3561c185a6..0e8666565f 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -358,7 +358,7 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
int precedingSpaces = 0;
int exportedIndex = 0;
for (int i=0; i <= fragmentText.count(); ++i) {
- QChar character = fragmentText[i];
+ QChar character = (i == fragmentText.count() ? QChar() : fragmentText.at(i));
bool isSpace = character.unicode() == ' ';
// find more than one space. -> <text:s text:c="2" />
diff --git a/src/gui/text/qtextoption.h b/src/gui/text/qtextoption.h
index 8b57278633..a90d73dc43 100644
--- a/src/gui/text/qtextoption.h
+++ b/src/gui/text/qtextoption.h
@@ -48,8 +48,6 @@
QT_BEGIN_NAMESPACE
-
-template <typename T> class QList;
struct QTextOptionPrivate;
class Q_GUI_EXPORT QTextOption
diff --git a/src/gui/vulkan/qplatformvulkaninstance.cpp b/src/gui/vulkan/qplatformvulkaninstance.cpp
index 9d044bfd58..1b5d3370f0 100644
--- a/src/gui/vulkan/qplatformvulkaninstance.cpp
+++ b/src/gui/vulkan/qplatformvulkaninstance.cpp
@@ -80,6 +80,11 @@ QPlatformVulkanInstance::~QPlatformVulkanInstance()
{
}
+void QPlatformVulkanInstance::presentAboutToBeQueued(QWindow *window)
+{
+ Q_UNUSED(window);
+}
+
void QPlatformVulkanInstance::presentQueued(QWindow *window)
{
Q_UNUSED(window);
diff --git a/src/gui/vulkan/qplatformvulkaninstance.h b/src/gui/vulkan/qplatformvulkaninstance.h
index d47c59b5db..f96f1720fb 100644
--- a/src/gui/vulkan/qplatformvulkaninstance.h
+++ b/src/gui/vulkan/qplatformvulkaninstance.h
@@ -77,6 +77,7 @@ public:
virtual QByteArrayList enabledExtensions() const = 0;
virtual PFN_vkVoidFunction getInstanceProcAddr(const char *name) = 0;
virtual bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) = 0;
+ virtual void presentAboutToBeQueued(QWindow *window);
virtual void presentQueued(QWindow *window);
virtual void setDebugFilters(const QVector<QVulkanInstance::DebugFilter> &filters);
diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp
index 0605d88cca..daf37e3dc8 100644
--- a/src/gui/vulkan/qvulkaninstance.cpp
+++ b/src/gui/vulkan/qvulkaninstance.cpp
@@ -775,6 +775,20 @@ bool QVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice, uint32_t
}
/*!
+ This function should be called by the application's renderer before queuing
+ a present operation for \a window.
+
+ While on some platforms this will be a no-op, some may perform windowing
+ system dependent synchronization. For example, on Wayland this will
+ add send a wl_surface.frame request in order to prevent the driver from
+ blocking for minimized windows.
+ */
+void QVulkanInstance::presentAboutToBeQueued(QWindow *window)
+{
+ d_ptr->platformInst->presentAboutToBeQueued(window);
+}
+
+/*!
This function should be called by the application's renderer after queuing
a present operation for \a window.
diff --git a/src/gui/vulkan/qvulkaninstance.h b/src/gui/vulkan/qvulkaninstance.h
index 70f2fd5102..5b3db9a4c8 100644
--- a/src/gui/vulkan/qvulkaninstance.h
+++ b/src/gui/vulkan/qvulkaninstance.h
@@ -186,6 +186,7 @@ public:
bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window);
+ void presentAboutToBeQueued(QWindow *window);
void presentQueued(QWindow *window);
typedef bool (*DebugFilter)(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object,
diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp
index 6d12377a60..790bef9e14 100644
--- a/src/gui/vulkan/qvulkanwindow.cpp
+++ b/src/gui/vulkan/qvulkanwindow.cpp
@@ -498,12 +498,12 @@ QVector<int> QVulkanWindow::supportedSampleCounts()
VkSampleCountFlags depth = limits->framebufferDepthSampleCounts;
VkSampleCountFlags stencil = limits->framebufferStencilSampleCounts;
- for (size_t i = 0; i < sizeof(qvk_sampleCounts) / sizeof(qvk_sampleCounts[0]); ++i) {
- if ((color & qvk_sampleCounts[i].mask)
- && (depth & qvk_sampleCounts[i].mask)
- && (stencil & qvk_sampleCounts[i].mask))
+ for (const auto &qvk_sampleCount : qvk_sampleCounts) {
+ if ((color & qvk_sampleCount.mask)
+ && (depth & qvk_sampleCount.mask)
+ && (stencil & qvk_sampleCount.mask))
{
- result.append(qvk_sampleCounts[i].count);
+ result.append(qvk_sampleCount.count);
}
}
@@ -547,9 +547,9 @@ void QVulkanWindow::setSampleCount(int sampleCount)
return;
}
- for (size_t i = 0; i < sizeof(qvk_sampleCounts) / sizeof(qvk_sampleCounts[0]); ++i) {
- if (qvk_sampleCounts[i].count == sampleCount) {
- d->sampleCount = qvk_sampleCounts[i].mask;
+ for (const auto &qvk_sampleCount : qvk_sampleCounts) {
+ if (qvk_sampleCount.count == sampleCount) {
+ d->sampleCount = qvk_sampleCount.mask;
return;
}
}
@@ -647,18 +647,40 @@ void QVulkanWindowPrivate::init()
#endif
qCDebug(lcGuiVk, "Using queue families: graphics = %u present = %u", gfxQueueFamilyIdx, presQueueFamilyIdx);
- VkDeviceQueueCreateInfo queueInfo[2];
+ QVector<VkDeviceQueueCreateInfo> queueInfo;
+ queueInfo.reserve(2);
const float prio[] = { 0 };
- memset(queueInfo, 0, sizeof(queueInfo));
- queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queueInfo[0].queueFamilyIndex = gfxQueueFamilyIdx;
- queueInfo[0].queueCount = 1;
- queueInfo[0].pQueuePriorities = prio;
+ VkDeviceQueueCreateInfo addQueueInfo;
+ memset(&addQueueInfo, 0, sizeof(addQueueInfo));
+ addQueueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ addQueueInfo.queueFamilyIndex = gfxQueueFamilyIdx;
+ addQueueInfo.queueCount = 1;
+ addQueueInfo.pQueuePriorities = prio;
+ queueInfo.append(addQueueInfo);
if (gfxQueueFamilyIdx != presQueueFamilyIdx) {
- queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queueInfo[1].queueFamilyIndex = presQueueFamilyIdx;
- queueInfo[1].queueCount = 1;
- queueInfo[1].pQueuePriorities = prio;
+ addQueueInfo.queueFamilyIndex = presQueueFamilyIdx;
+ addQueueInfo.queueCount = 1;
+ addQueueInfo.pQueuePriorities = prio;
+ queueInfo.append(addQueueInfo);
+ }
+ if (queueCreateInfoModifier) {
+ queueCreateInfoModifier(queueFamilyProps.constData(), queueCount, queueInfo);
+ bool foundGfxQueue = false;
+ bool foundPresQueue = false;
+ for (const VkDeviceQueueCreateInfo& createInfo : qAsConst(queueInfo)) {
+ foundGfxQueue |= createInfo.queueFamilyIndex == gfxQueueFamilyIdx;
+ foundPresQueue |= createInfo.queueFamilyIndex == presQueueFamilyIdx;
+ }
+ if (!foundGfxQueue) {
+ qWarning("QVulkanWindow: Graphics queue missing after call to queueCreateInfoModifier");
+ status = StatusFail;
+ return;
+ }
+ if (!foundPresQueue) {
+ qWarning("QVulkanWindow: Present queue missing after call to queueCreateInfoModifier");
+ status = StatusFail;
+ return;
+ }
}
// Filter out unsupported extensions in order to keep symmetry
@@ -676,8 +698,8 @@ void QVulkanWindowPrivate::init()
VkDeviceCreateInfo devInfo;
memset(&devInfo, 0, sizeof(devInfo));
devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
- devInfo.queueCreateInfoCount = gfxQueueFamilyIdx == presQueueFamilyIdx ? 1 : 2;
- devInfo.pQueueCreateInfos = queueInfo;
+ devInfo.queueCreateInfoCount = queueInfo.size();
+ devInfo.pQueueCreateInfos = queueInfo.constData();
devInfo.enabledExtensionCount = devExts.count();
devInfo.ppEnabledExtensionNames = devExts.constData();
@@ -1546,6 +1568,52 @@ bool QVulkanWindow::event(QEvent *e)
}
/*!
+ \typedef QVulkanWindow::QueueCreateInfoModifier
+
+ A function function that is called during graphics initialization to add
+ additAional queues that should be created.
+
+ Set if the renderer needs additional queues besides the default graphics
+ queue (e.g. a transfer queue).
+ The provided queue family properties can be used to select the indices for
+ the additional queues.
+ The renderer can subsequently request the actual queue in initResources().
+
+ Note when requesting additional graphics queues: Qt itself always requests
+ a graphics queue, you'll need to search queueCreateInfo for the appropriate
+ entry and manipulate it to obtain the additional queue.
+
+ \sa setQueueCreateInfoModifier()
+ */
+
+/*!
+ Return a previously set queue create info modification function.
+
+ \sa setQueueCreateInfoModifier()
+
+ \since 5.15
+ */
+QVulkanWindow::QueueCreateInfoModifier QVulkanWindow::queueCreateInfoModifier() const
+{
+ Q_D(const QVulkanWindow);
+ return d->queueCreateInfoModifier;
+}
+
+/*!
+ Set a queue create info modification function.
+
+ \sa queueCreateInfoModifier()
+
+ \since 5.15
+ */
+void QVulkanWindow::setQueueCreateInfoModifier(QueueCreateInfoModifier modifier)
+{
+ Q_D(QVulkanWindow);
+ d->queueCreateInfoModifier = modifier;
+}
+
+
+/*!
Returns true if this window has successfully initialized all Vulkan
resources, including the swapchain.
@@ -1950,6 +2018,10 @@ void QVulkanWindowPrivate::endFrame()
presInfo.waitSemaphoreCount = 1;
presInfo.pWaitSemaphores = gfxQueueFamilyIdx == presQueueFamilyIdx ? &frame.drawSem : &frame.presTransSem;
+ // Do platform-specific WM notification. F.ex. essential on Wayland in
+ // order to circumvent driver frame callbacks
+ inst->presentAboutToBeQueued(q);
+
err = vkQueuePresentKHR(gfxQueue, &presInfo);
if (err != VK_SUCCESS) {
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
@@ -2211,6 +2283,23 @@ VkQueue QVulkanWindow::graphicsQueue() const
}
/*!
+ Returns the family index of the active graphics queue.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources(). Implementations of
+ QVulkanWindowRenderer::updateQueueCreateInfo() can also call this
+ function.
+
+ \since 5.15
+ */
+uint32_t QVulkanWindow::graphicsQueueFamilyIndex() const
+{
+ Q_D(const QVulkanWindow);
+ return d->gfxQueueFamilyIdx;
+}
+
+/*!
Returns the active graphics command pool.
\note Calling this function is only valid from the invocation of
diff --git a/src/gui/vulkan/qvulkanwindow.h b/src/gui/vulkan/qvulkanwindow.h
index 927c81042f..530b6c0744 100644
--- a/src/gui/vulkan/qvulkanwindow.h
+++ b/src/gui/vulkan/qvulkanwindow.h
@@ -103,6 +103,12 @@ public:
QVector<int> supportedSampleCounts();
void setSampleCount(int sampleCount);
+ typedef std::function<void(const VkQueueFamilyProperties *,
+ uint32_t,
+ QVector<VkDeviceQueueCreateInfo> &)> QueueCreateInfoModifier;
+ QueueCreateInfoModifier queueCreateInfoModifier() const;
+ void setQueueCreateInfoModifier(QueueCreateInfoModifier modifier);
+
bool isValid() const;
virtual QVulkanWindowRenderer *createRenderer();
@@ -112,6 +118,7 @@ public:
const VkPhysicalDeviceProperties *physicalDeviceProperties() const;
VkDevice device() const;
VkQueue graphicsQueue() const;
+ uint32_t graphicsQueueFamilyIndex() const;
VkCommandPool graphicsCommandPool() const;
uint32_t hostVisibleMemoryIndex() const;
uint32_t deviceLocalMemoryIndex() const;
diff --git a/src/gui/vulkan/qvulkanwindow_p.h b/src/gui/vulkan/qvulkanwindow_p.h
index fb374a5564..777be237a8 100644
--- a/src/gui/vulkan/qvulkanwindow_p.h
+++ b/src/gui/vulkan/qvulkanwindow_p.h
@@ -102,6 +102,7 @@ public:
QHash<VkPhysicalDevice, QVulkanInfoVector<QVulkanExtension> > supportedDevExtensions;
QVector<VkFormat> requestedColorFormats;
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
+ QVulkanWindow::QueueCreateInfoModifier queueCreateInfoModifier;
VkDevice dev = VK_NULL_HANDLE;
QVulkanDeviceFunctions *devFuncs;
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index cfb20dcd71..083fbbf5fd 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -114,11 +114,4 @@ qtConfig(http) {
access/qhttpthreaddelegate_p.h \
access/qnetworkreplyhttpimpl_p.h \
access/qhttp2configuration.h
-
- qtConfig(ssl) {
- SOURCES += \
- access/qspdyprotocolhandler.cpp
- HEADERS += \
- access/qspdyprotocolhandler_p.h
- }
}
diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h
index e357dfe58f..a4048c5b8f 100644
--- a/src/network/access/qabstractnetworkcache.h
+++ b/src/network/access/qabstractnetworkcache.h
@@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
class QIODevice;
class QDateTime;
class QUrl;
-template<class T> class QList;
class QNetworkCacheMetaDataPrivate;
class Q_NETWORK_EXPORT QNetworkCacheMetaData
diff --git a/src/network/access/qhsts_p.h b/src/network/access/qhsts_p.h
index c219d9eab5..b5be4ff455 100644
--- a/src/network/access/qhsts_p.h
+++ b/src/network/access/qhsts_p.h
@@ -66,7 +66,6 @@
QT_BEGIN_NAMESPACE
-template<typename T> class QList;
template <typename T> class QVector;
class Q_AUTOTEST_EXPORT QHstsCache
diff --git a/src/network/access/qhttp2configuration.cpp b/src/network/access/qhttp2configuration.cpp
index a32bccfd09..bd4318d4e9 100644
--- a/src/network/access/qhttp2configuration.cpp
+++ b/src/network/access/qhttp2configuration.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QHttp2Configuration
- \brief The QHttp2Configuration class controls HTTP/2 parameters and settings
+ \brief The QHttp2Configuration class controls HTTP/2 parameters and settings.
\since 5.14
\reentrant
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index c1053882af..efbeb17d39 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -58,6 +58,8 @@
#include <QtNetwork/qnetworkproxy.h>
#endif
+#include <qcoreapplication.h>
+
#include <algorithm>
#include <vector>
@@ -195,6 +197,29 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan
}
}
+void QHttp2ProtocolHandler::handleConnectionClosure()
+{
+ // The channel has just received RemoteHostClosedError and since it will
+ // not try (for HTTP/2) to re-connect, it's time to finish all replies
+ // with error.
+
+ // Maybe we still have some data to read and can successfully finish
+ // a stream/request?
+ _q_receiveReply();
+
+ // Finish all still active streams. If we previously had GOAWAY frame,
+ // we probably already closed some (or all) streams with ContentReSend
+ // error, but for those still active, not having any data to finish,
+ // we now report RemoteHostClosedError.
+ const auto errorString = QCoreApplication::translate("QHttp", "Connection closed");
+ for (auto it = activeStreams.begin(), eIt = activeStreams.end(); it != eIt; ++it)
+ finishStreamWithError(it.value(), QNetworkReply::RemoteHostClosedError, errorString);
+
+ // Make sure we'll never try to read anything later:
+ activeStreams.clear();
+ goingAway = true;
+}
+
void QHttp2ProtocolHandler::_q_uploadDataReadyRead()
{
if (!sender()) // QueuedConnection, firing after sender (byte device) was deleted.
@@ -307,13 +332,13 @@ bool QHttp2ProtocolHandler::sendRequest()
// so we cannot create new streams.
m_channel->emitFinishedWithError(QNetworkReply::ProtocolUnknownError,
"GOAWAY received, cannot start a request");
- m_channel->spdyRequestsToSend.clear();
+ m_channel->h2RequestsToSend.clear();
return false;
}
// Process 'fake' (created by QNetworkAccessManager::connectToHostEncrypted())
// requests first:
- auto &requests = m_channel->spdyRequestsToSend;
+ auto &requests = m_channel->h2RequestsToSend;
for (auto it = requests.begin(), endIt = requests.end(); it != endIt;) {
const auto &pair = *it;
const QString scheme(pair.first.url().scheme());
@@ -837,7 +862,7 @@ void QHttp2ProtocolHandler::handleGOAWAY()
m_channel->emitFinishedWithError(QNetworkReply::ProtocolUnknownError,
"GOAWAY received, cannot start a request");
// Also, prevent further calls to sendRequest:
- m_channel->spdyRequestsToSend.clear();
+ m_channel->h2RequestsToSend.clear();
QNetworkReply::NetworkError error = QNetworkReply::NoError;
QString message;
@@ -1256,7 +1281,7 @@ quint32 QHttp2ProtocolHandler::createNewStream(const HttpMessagePair &message, b
const auto replyPrivate = reply->d_func();
replyPrivate->connection = m_connection;
replyPrivate->connectionChannel = m_channel;
- reply->setSpdyWasUsed(true);
+ reply->setHttp2WasUsed(true);
streamIDs.insert(reply, newStreamID);
connect(reply, SIGNAL(destroyed(QObject*)),
this, SLOT(_q_replyDestroyed(QObject*)));
@@ -1314,14 +1339,13 @@ void QHttp2ProtocolHandler::markAsReset(quint32 streamID)
quint32 QHttp2ProtocolHandler::popStreamToResume()
{
quint32 streamID = connectionStreamID;
- const int nQ = sizeof suspendedStreams / sizeof suspendedStreams[0];
using QNR = QHttpNetworkRequest;
- const QNR::Priority ranks[nQ] = {QNR::HighPriority,
- QNR::NormalPriority,
- QNR::LowPriority};
+ const QNR::Priority ranks[] = {QNR::HighPriority,
+ QNR::NormalPriority,
+ QNR::LowPriority};
- for (int i = 0; i < nQ; ++i) {
- auto &queue = suspendedStreams[ranks[i]];
+ for (const QNR::Priority rank : ranks) {
+ auto &queue = suspendedStreams[rank];
auto it = queue.begin();
for (; it != queue.end(); ++it) {
if (!activeStreams.contains(*it))
@@ -1342,9 +1366,7 @@ quint32 QHttp2ProtocolHandler::popStreamToResume()
void QHttp2ProtocolHandler::removeFromSuspended(quint32 streamID)
{
- const int nQ = sizeof suspendedStreams / sizeof suspendedStreams[0];
- for (int i = 0; i < nQ; ++i) {
- auto &q = suspendedStreams[i];
+ for (auto &q : suspendedStreams) {
q.erase(std::remove(q.begin(), q.end(), streamID), q.end());
}
}
@@ -1365,7 +1387,7 @@ void QHttp2ProtocolHandler::deleteActiveStream(quint32 streamID)
}
removeFromSuspended(streamID);
- if (m_channel->spdyRequestsToSend.size())
+ if (m_channel->h2RequestsToSend.size())
QMetaObject::invokeMethod(this, "sendRequest", Qt::QueuedConnection);
}
@@ -1484,7 +1506,7 @@ void QHttp2ProtocolHandler::initReplyFromPushPromise(const HttpMessagePair &mess
Q_ASSERT(promisedData.contains(cacheKey));
auto promise = promisedData.take(cacheKey);
Q_ASSERT(message.second);
- message.second->setSpdyWasUsed(true);
+ message.second->setHttp2WasUsed(true);
qCDebug(QT_HTTP2) << "found cached/promised response on stream" << promise.reservedID;
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index 1943827e23..43fdb136cd 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -92,6 +92,8 @@ public:
QHttp2ProtocolHandler &operator = (const QHttp2ProtocolHandler &rhs) = delete;
QHttp2ProtocolHandler &operator = (QHttp2ProtocolHandler &&rhs) = delete;
+ Q_INVOKABLE void handleConnectionClosure();
+
private slots:
void _q_uploadDataReadyRead();
void _q_replyDestroyed(QObject* reply);
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 13be1aa6b5..795efc91d7 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -82,9 +82,6 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true)
, activeChannelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2
|| type == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
-#ifndef QT_NO_SSL
- || type == QHttpNetworkConnection::ConnectionTypeSPDY
-#endif
? 1 : defaultHttpChannelCount)
, channelCount(defaultHttpChannelCount)
#ifndef QT_NO_NETWORKPROXY
@@ -93,9 +90,9 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
, preConnectRequests(0)
, connectionType(type)
{
- // We allocate all 6 channels even if it's SPDY or HTTP/2 enabled
- // connection: in case the protocol negotiation via NPN/ALPN fails,
- // we will have normally working HTTP/1.1.
+ // We allocate all 6 channels even if it's HTTP/2 enabled connection:
+ // in case the protocol negotiation via NPN/ALPN fails, we will have
+ // normally working HTTP/1.1.
Q_ASSERT(channelCount >= activeChannelCount);
channels = new QHttpNetworkConnectionChannel[channelCount];
}
@@ -641,10 +638,10 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
break;
}
}
- else { // SPDY, HTTP/2 ('h2' mode)
+ else { // HTTP/2 ('h2' mode)
if (!pair.second->d_func()->requestIsPrepared)
prepareRequest(pair);
- channels[0].spdyRequestsToSend.insert(request.priority(), pair);
+ channels[0].h2RequestsToSend.insert(request.priority(), pair);
}
#ifndef Q_OS_WINRT
@@ -680,7 +677,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue()
for (auto &pair : highPriorityQueue) {
if (!pair.second->d_func()->requestIsPrepared)
prepareRequest(pair);
- channels[0].spdyRequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair);
+ channels[0].h2RequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair);
}
highPriorityQueue.clear();
@@ -688,7 +685,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue()
for (auto &pair : lowPriorityQueue) {
if (!pair.second->d_func()->requestIsPrepared)
prepareRequest(pair);
- channels[0].spdyRequestsToSend.insert(pair.first.priority(), pair);
+ channels[0].h2RequestsToSend.insert(pair.first.priority(), pair);
}
lowPriorityQueue.clear();
@@ -984,12 +981,12 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
}
}
#ifndef QT_NO_SSL
- // is the reply inside the SPDY pipeline of this channel already?
- QMultiMap<int, HttpMessagePair>::iterator it = channels[i].spdyRequestsToSend.begin();
- QMultiMap<int, HttpMessagePair>::iterator end = channels[i].spdyRequestsToSend.end();
+ // is the reply inside the H2 pipeline of this channel already?
+ QMultiMap<int, HttpMessagePair>::iterator it = channels[i].h2RequestsToSend.begin();
+ QMultiMap<int, HttpMessagePair>::iterator end = channels[i].h2RequestsToSend.end();
for (; it != end; ++it) {
if (it.value().second == reply) {
- channels[i].spdyRequestsToSend.remove(it.key());
+ channels[i].h2RequestsToSend.remove(it.key());
QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
return;
@@ -1068,9 +1065,8 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
break;
}
case QHttpNetworkConnection::ConnectionTypeHTTP2Direct:
- case QHttpNetworkConnection::ConnectionTypeHTTP2:
- case QHttpNetworkConnection::ConnectionTypeSPDY: {
- if (channels[0].spdyRequestsToSend.isEmpty() && channels[0].switchedToHttp2)
+ case QHttpNetworkConnection::ConnectionTypeHTTP2: {
+ if (channels[0].h2RequestsToSend.isEmpty() && channels[0].switchedToHttp2)
return;
if (networkLayerState == IPv4)
@@ -1079,7 +1075,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
channels[0].networkLayerPreference = QAbstractSocket::IPv6Protocol;
channels[0].ensureConnection();
if (channels[0].socket && channels[0].socket->state() == QAbstractSocket::ConnectedState
- && !channels[0].pendingEncrypt && channels[0].spdyRequestsToSend.size())
+ && !channels[0].pendingEncrypt && channels[0].h2RequestsToSend.size())
channels[0].sendRequest();
break;
}
@@ -1234,18 +1230,18 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
if (dequeueRequest(channels[0].socket)) {
emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
- } else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
- || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2) {
- for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) {
+ } else if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
+ || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
+ for (const HttpMessagePair &h2Pair : qAsConst(channels[0].h2RequestsToSend)) {
// emit error for all replies
- QHttpNetworkReply *currentReply = spdyPair.second;
+ QHttpNetworkReply *currentReply = h2Pair.second;
Q_ASSERT(currentReply);
emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError);
}
} else {
// Should not happen: we start a host lookup before sending a request,
- // so it's natural to have requests either in SPDY/HTTP/2 queue,
- // or in low/high priority queues.
+ // so it's natural to have requests either in HTTP/2 queue, or in low/high
+ // priority queues.
qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished"
" could not de-queue request, failed to report HostNotFoundError");
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
@@ -1575,17 +1571,12 @@ void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpN
pauseConnection();
QHttpNetworkReply *reply;
if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
- || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
-#if QT_CONFIG(ssl)
- || connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
-#endif
- ) {
-
+ || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
// we choose the reply to emit the proxyAuth signal from somewhat arbitrarily,
// but that does not matter because the signal will ultimately be emitted
// by the QNetworkAccessManager.
- Q_ASSERT(chan->spdyRequestsToSend.count() > 0);
- reply = chan->spdyRequestsToSend.cbegin().value().second;
+ Q_ASSERT(chan->h2RequestsToSend.count() > 0);
+ reply = chan->h2RequestsToSend.cbegin().value().second;
} else { // HTTP
reply = chan->reply;
}
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 6808a0c0ac..fee84bb6c0 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -96,7 +96,6 @@ public:
enum ConnectionType {
ConnectionTypeHTTP,
- ConnectionTypeSPDY,
ConnectionTypeHTTP2,
ConnectionTypeHTTP2Direct
};
@@ -172,7 +171,6 @@ private:
friend class QHttpNetworkConnectionChannel;
friend class QHttp2ProtocolHandler;
friend class QHttpProtocolHandler;
- friend class QSpdyProtocolHandler;
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 716ea6c8b2..c6470622ab 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -48,7 +48,6 @@
#include <private/qhttp2protocolhandler_p.h>
#include <private/qhttpprotocolhandler_p.h>
-#include <private/qspdyprotocolhandler_p.h>
#include <private/http2protocol_p.h>
#ifndef QT_NO_SSL
@@ -854,8 +853,11 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
state = QHttpNetworkConnectionChannel::IdleState;
-
- requeueCurrentlyPipelinedRequests();
+ if (alreadyPipelinedRequests.length()) {
+ // If nothing was in a pipeline, no need in calling
+ // _q_startNextRequest (which it does):
+ requeueCurrentlyPipelinedRequests();
+ }
pendingEncrypt = false;
}
@@ -928,7 +930,7 @@ void QHttpNetworkConnectionChannel::_q_connected()
} else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
state = QHttpNetworkConnectionChannel::IdleState;
protocolHandler.reset(new QHttp2ProtocolHandler(this));
- if (spdyRequestsToSend.count() > 0) {
+ if (h2RequestsToSend.count() > 0) {
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
@@ -977,7 +979,18 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (!reply && state == QHttpNetworkConnectionChannel::IdleState) {
// Not actually an error, it is normal for Keep-Alive connections to close after some time if no request
// is sent on them. No need to error the other replies below. Just bail out here.
- // The _q_disconnected will handle the possibly pipelined replies
+ // The _q_disconnected will handle the possibly pipelined replies. HTTP/2 is special for now,
+ // we do not resend, but must report errors if any request is in progress (note, while
+ // not in its sendRequest(), protocol handler switches the channel to IdleState, thus
+ // this check is under this condition in 'if'):
+ if (protocolHandler.data()) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
+ auto h2Handler = static_cast<QHttp2ProtocolHandler *>(protocolHandler.data());
+ h2Handler->handleConnectionClosure();
+ protocolHandler.reset();
+ }
+ }
return;
} else if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) {
// Try to reconnect/resend before sending an error.
@@ -1094,14 +1107,11 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|| !connection->d_func()->lowPriorityQueue.isEmpty());
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
-#ifndef QT_NO_SSL
- || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY
-#endif
- ) {
- QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
- for (int a = 0; a < spdyPairs.count(); ++a) {
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
+ QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
+ for (int a = 0; a < h2Pairs.count(); ++a) {
// emit error for all replies
- QHttpNetworkReply *currentReply = spdyPairs.at(a).second;
+ QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
Q_ASSERT(currentReply);
emit currentReply->finishedWithError(errorCode, errorString);
}
@@ -1128,12 +1138,8 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth)
{
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
- || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
-#ifndef QT_NO_SSL
- || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY
-#endif
- ) {
- if (spdyRequestsToSend.count() > 0)
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
+ if (h2RequestsToSend.count() > 0)
connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
} else { // HTTP
// Need to dequeue the request before we can emit the error.
@@ -1156,9 +1162,9 @@ void QHttpNetworkConnectionChannel::emitFinishedWithError(QNetworkReply::Network
{
if (reply)
emit reply->finishedWithError(error, QHttpNetworkConnectionChannel::tr(message));
- QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
- for (int a = 0; a < spdyPairs.count(); ++a) {
- QHttpNetworkReply *currentReply = spdyPairs.at(a).second;
+ QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
+ for (int a = 0; a < h2Pairs.count(); ++a) {
+ QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
Q_ASSERT(currentReply);
emit currentReply->finishedWithError(error, QHttpNetworkConnectionChannel::tr(message));
}
@@ -1180,12 +1186,6 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
QByteArray nextProtocol = sslSocket->sslConfiguration().nextNegotiatedProtocol();
if (nextProtocol == QSslConfiguration::NextProtocolHttp1_1) {
// fall through to create a QHttpProtocolHandler
- } else if (nextProtocol == QSslConfiguration::NextProtocolSpdy3_0) {
- protocolHandler.reset(new QSpdyProtocolHandler(this));
- connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeSPDY);
- // no need to re-queue requests, if SPDY was enabled on the request it
- // has gone to the SPDY queue already
- break;
} else if (nextProtocol == QSslConfiguration::ALPNProtocolHTTP2) {
switchedToHttp2 = true;
protocolHandler.reset(new QHttp2ProtocolHandler(this));
@@ -1214,8 +1214,6 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
// it again on other channels that our connection can create/open.
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2)
protocols.removeAll(QSslConfiguration::ALPNProtocolHTTP2);
- else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY)
- protocols.removeAll(QSslConfiguration::NextProtocolSpdy3_0);
if (nProtocols > protocols.size()) {
sslConfiguration->setAllowedNextProtocols(protocols);
@@ -1225,13 +1223,13 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
}
connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP);
- // We use only one channel for SPDY or HTTP/2, but normally six for
+ // We use only one channel for HTTP/2, but normally six for
// HTTP/1.1 - let's restore this number to the reserved number of
// channels:
if (connection->d_func()->activeChannelCount < connection->d_func()->channelCount) {
connection->d_func()->activeChannelCount = connection->d_func()->channelCount;
- // re-queue requests from SPDY queue to HTTP queue, if any
- requeueSpdyRequests();
+ // re-queue requests from HTTP/2 queue to HTTP queue, if any
+ requeueHttp2Requests();
}
break;
}
@@ -1251,11 +1249,9 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
state = QHttpNetworkConnectionChannel::IdleState;
pendingEncrypt = false;
- if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY ||
- connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 ||
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 ||
connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
- // we call setSpdyWasUsed(true) on the replies in the SPDY handler when the request is sent
- if (spdyRequestsToSend.count() > 0) {
+ if (h2RequestsToSend.count() > 0) {
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
@@ -1264,7 +1260,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
if (!reply)
connection->d_func()->dequeueRequest(socket);
if (reply) {
- reply->setSpdyWasUsed(false);
+ reply->setHttp2WasUsed(false);
Q_ASSERT(reply->d_func()->connectionChannel == this);
emit reply->encrypted();
}
@@ -1273,13 +1269,12 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
}
}
-void QHttpNetworkConnectionChannel::requeueSpdyRequests()
+void QHttpNetworkConnectionChannel::requeueHttp2Requests()
{
- QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
- for (int a = 0; a < spdyPairs.count(); ++a) {
- connection->d_func()->requeueRequest(spdyPairs.at(a));
- }
- spdyRequestsToSend.clear();
+ QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
+ for (int a = 0; a < h2Pairs.count(); ++a)
+ connection->d_func()->requeueRequest(h2Pairs.at(a));
+ h2RequestsToSend.clear();
}
void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
@@ -1297,11 +1292,11 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
emit reply->sslErrors(errors);
}
#ifndef QT_NO_SSL
- else { // SPDY
- QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
- for (int a = 0; a < spdyPairs.count(); ++a) {
+ else { // HTTP/2
+ QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
+ for (int a = 0; a < h2Pairs.count(); ++a) {
// emit SSL errors for all replies
- QHttpNetworkReply *currentReply = spdyPairs.at(a).second;
+ QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
Q_ASSERT(currentReply);
emit currentReply->sslErrors(errors);
}
@@ -1321,10 +1316,10 @@ void QHttpNetworkConnectionChannel::_q_preSharedKeyAuthenticationRequired(QSslPr
if (reply)
emit reply->preSharedKeyAuthenticationRequired(authenticator);
} else {
- QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
- for (int a = 0; a < spdyPairs.count(); ++a) {
+ QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
+ for (int a = 0; a < h2Pairs.count(); ++a) {
// emit SSL errors for all replies
- QHttpNetworkReply *currentReply = spdyPairs.at(a).second;
+ QHttpNetworkReply *currentReply = h2Pairs.at(a).second;
Q_ASSERT(currentReply);
emit currentReply->preSharedKeyAuthenticationRequired(authenticator);
}
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 270b3eb9ba..44ad2d7959 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -123,10 +123,7 @@ public:
bool authenticationCredentialsSent;
bool proxyCredentialsSent;
QScopedPointer<QAbstractProtocolHandler> protocolHandler;
- // SPDY or HTTP/2 requests; SPDY is TLS-only, but
- // HTTP/2 can be cleartext also, that's why it's
- // outside of QT_NO_SSL section. Sorted by priority:
- QMultiMap<int, HttpMessagePair> spdyRequestsToSend;
+ QMultiMap<int, HttpMessagePair> h2RequestsToSend;
bool switchedToHttp2 = false;
#ifndef QT_NO_SSL
bool ignoreAllSslErrors;
@@ -135,7 +132,7 @@ public:
void ignoreSslErrors();
void ignoreSslErrors(const QList<QSslError> &errors);
void setSslConfiguration(const QSslConfiguration &config);
- void requeueSpdyRequests(); // when we wanted SPDY but got HTTP
+ void requeueHttp2Requests(); // when we wanted HTTP/2 but got HTTP/1.1
#endif
// to emit the signal for all in-flight replies:
void emitFinishedWithError(QNetworkReply::NetworkError error, const char *message);
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index a8b635c45a..8982b7c745 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -287,14 +287,14 @@ bool QHttpNetworkReply::isPipeliningUsed() const
return d_func()->pipeliningUsed;
}
-bool QHttpNetworkReply::isSpdyUsed() const
+bool QHttpNetworkReply::isHttp2Used() const
{
- return d_func()->spdyUsed;
+ return d_func()->h2Used;
}
-void QHttpNetworkReply::setSpdyWasUsed(bool spdy)
+void QHttpNetworkReply::setHttp2WasUsed(bool h2)
{
- d_func()->spdyUsed = spdy;
+ d_func()->h2Used = h2;
}
qint64 QHttpNetworkReply::removedContentLength() const
@@ -324,15 +324,11 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
forceConnectionCloseEnabled(false),
lastChunkRead(false),
currentChunkSize(0), currentChunkRead(0), readBufferMaxSize(0),
- windowSizeDownload(65536), // 64K initial window size according to SPDY standard
- windowSizeUpload(65536), // 64K initial window size according to SPDY standard
- currentlyReceivedDataInWindow(0),
- currentlyUploadedDataInWindow(0),
totallyUploadedData(0),
removedContentLength(-1),
connection(0),
autoDecompress(false), responseData(), requestIsPrepared(false)
- ,pipeliningUsed(false), spdyUsed(false), downstreamLimited(false)
+ ,pipeliningUsed(false), h2Used(false), downstreamLimited(false)
,userProvidedDownloadBuffer(0)
#ifndef QT_NO_COMPRESS
,inflateStrm(0)
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 12cfe359aa..82128f656e 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -137,8 +137,8 @@ public:
bool isFinished() const;
bool isPipeliningUsed() const;
- bool isSpdyUsed() const;
- void setSpdyWasUsed(bool spdy);
+ bool isHttp2Used() const;
+ void setHttp2WasUsed(bool h2Used);
qint64 removedContentLength() const;
bool isRedirecting() const;
@@ -251,11 +251,7 @@ public:
qint64 currentChunkSize;
qint64 currentChunkRead;
qint64 readBufferMaxSize;
- qint32 windowSizeDownload; // only for SPDY
- qint32 windowSizeUpload; // only for SPDY
- qint32 currentlyReceivedDataInWindow; // only for SPDY
- qint32 currentlyUploadedDataInWindow; // only for SPDY
- qint64 totallyUploadedData; // only for SPDY
+ qint64 totallyUploadedData; // HTTP/2
qint64 removedContentLength;
QPointer<QHttpNetworkConnection> connection;
QPointer<QHttpNetworkConnectionChannel> connectionChannel;
@@ -267,7 +263,7 @@ public:
bool requestIsPrepared;
bool pipeliningUsed;
- bool spdyUsed;
+ bool h2Used;
bool downstreamLimited;
char* userProvidedDownloadBuffer;
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index a3f71b8d2f..f81924d5d3 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(0),
- autoDecompress(false), pipeliningAllowed(false), spdyAllowed(false), http2Allowed(false),
+ autoDecompress(false), pipeliningAllowed(false), http2Allowed(false),
http2Direct(false), withCredentials(true), preConnect(false), redirectCount(0),
redirectPolicy(QNetworkRequest::ManualRedirectPolicy)
{
@@ -59,7 +59,6 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
uploadByteDevice(other.uploadByteDevice),
autoDecompress(other.autoDecompress),
pipeliningAllowed(other.pipeliningAllowed),
- spdyAllowed(other.spdyAllowed),
http2Allowed(other.http2Allowed),
http2Direct(other.http2Direct),
withCredentials(other.withCredentials),
@@ -83,7 +82,6 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
&& (uploadByteDevice == other.uploadByteDevice)
&& (autoDecompress == other.autoDecompress)
&& (pipeliningAllowed == other.pipeliningAllowed)
- && (spdyAllowed == other.spdyAllowed)
&& (http2Allowed == other.http2Allowed)
&& (http2Direct == other.http2Direct)
// we do not clear the customVerb in setOperation
@@ -339,16 +337,6 @@ void QHttpNetworkRequest::setPipeliningAllowed(bool b)
d->pipeliningAllowed = b;
}
-bool QHttpNetworkRequest::isSPDYAllowed() const
-{
- return d->spdyAllowed;
-}
-
-void QHttpNetworkRequest::setSPDYAllowed(bool b)
-{
- d->spdyAllowed = b;
-}
-
bool QHttpNetworkRequest::isHTTP2Allowed() const
{
return d->http2Allowed;
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index fb4896195b..f263e348ef 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -116,9 +116,6 @@ public:
bool isPipeliningAllowed() const;
void setPipeliningAllowed(bool b);
- bool isSPDYAllowed() const;
- void setSPDYAllowed(bool b);
-
bool isHTTP2Allowed() const;
void setHTTP2Allowed(bool b);
@@ -176,7 +173,6 @@ public:
mutable QNonContiguousByteDevice* uploadByteDevice;
bool autoDecompress;
bool pipeliningAllowed;
- bool spdyAllowed;
bool http2Allowed;
bool http2Direct;
bool withCredentials;
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 1900397eab..2933d75d2c 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -236,7 +236,7 @@ QHttpThreadDelegate::QHttpThreadDelegate(QObject *parent) :
, synchronous(false)
, incomingStatusCode(0)
, isPipeliningUsed(false)
- , isSpdyUsed(false)
+ , isHttp2Used(false)
, incomingContentLength(-1)
, removedContentLength(-1)
, incomingErrorCode(QNetworkReply::NoError)
@@ -297,6 +297,11 @@ void QHttpThreadDelegate::startRequest()
connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct;
}
+#if QT_CONFIG(ssl)
+ // See qnetworkreplyhttpimpl, delegate's initialization code.
+ Q_ASSERT(!ssl || incomingSslConfiguration.data());
+#endif // QT_CONFIG(ssl)
+
const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct();
if (isH2) {
#if QT_CONFIG(ssl)
@@ -315,20 +320,6 @@ void QHttpThreadDelegate::startRequest()
}
}
-#ifndef QT_NO_SSL
- if (ssl && !incomingSslConfiguration.data())
- incomingSslConfiguration.reset(new QSslConfiguration);
-
- if (!isH2 && httpRequest.isSPDYAllowed() && ssl) {
- connectionType = QHttpNetworkConnection::ConnectionTypeSPDY;
- urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests
- QList<QByteArray> nextProtocols;
- nextProtocols << QSslConfiguration::NextProtocolSpdy3_0
- << QSslConfiguration::NextProtocolHttp1_1;
- incomingSslConfiguration->setAllowedNextProtocols(nextProtocols);
- }
-#endif // QT_NO_SSL
-
#ifndef QT_NO_NETWORKPROXY
if (transparentProxy.type() != QNetworkProxy::NoProxy)
cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName());
@@ -650,7 +641,7 @@ void QHttpThreadDelegate::headerChangedSlot()
isPipeliningUsed = httpReply->isPipeliningUsed();
incomingContentLength = httpReply->contentLength();
removedContentLength = httpReply->removedContentLength();
- isSpdyUsed = httpReply->isSpdyUsed();
+ isHttp2Used = httpReply->isHttp2Used();
emit downloadMetaData(incomingHeaders,
incomingStatusCode,
@@ -659,7 +650,7 @@ void QHttpThreadDelegate::headerChangedSlot()
downloadBuffer,
incomingContentLength,
removedContentLength,
- isSpdyUsed);
+ isHttp2Used);
}
void QHttpThreadDelegate::synchronousHeaderChangedSlot()
@@ -675,7 +666,7 @@ void QHttpThreadDelegate::synchronousHeaderChangedSlot()
incomingStatusCode = httpReply->statusCode();
incomingReasonPhrase = httpReply->reasonPhrase();
isPipeliningUsed = httpReply->isPipeliningUsed();
- isSpdyUsed = httpReply->isSpdyUsed();
+ isHttp2Used = httpReply->isHttp2Used();
incomingContentLength = httpReply->contentLength();
}
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 355d1afc30..208b2cb149 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -112,7 +112,7 @@ public:
int incomingStatusCode;
QString incomingReasonPhrase;
bool isPipeliningUsed;
- bool isSpdyUsed;
+ bool isHttp2Used;
qint64 incomingContentLength;
qint64 removedContentLength;
QNetworkReply::NetworkError incomingErrorCode;
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 76b95b5823..125427493d 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1237,12 +1237,10 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin
if (sslConfiguration != QSslConfiguration::defaultConfiguration())
request.setSslConfiguration(sslConfiguration);
- // There is no way to enable SPDY/HTTP2 via a request, so we need to check
- // the ssl configuration whether SPDY/HTTP2 is allowed here.
+ // There is no way to enable HTTP2 via a request, so we need to check
+ // the ssl configuration whether HTTP2 is allowed here.
if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::ALPNProtocolHTTP2))
- request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
- else if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::NextProtocolSpdy3_0))
- request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true);
+ request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true);
request.setPeerVerifyName(peerName);
get(request);
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 98498d07d2..a74ece6d5b 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -56,7 +56,6 @@ class QIODevice;
class QAbstractNetworkCache;
class QAuthenticator;
class QByteArray;
-template<typename T> class QList;
class QNetworkCookie;
class QNetworkCookieJar;
class QNetworkReply;
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index b3dec282b0..0bd7825186 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -758,8 +758,9 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
quint64 requestStartOffset = requestRange.left(index).toULongLong();
quint64 requestEndOffset = requestRange.mid(index + 1).toULongLong();
+ // In case an end offset is not given it is skipped from the request range
requestRange = "bytes=" + QByteArray::number(resumeOffset + requestStartOffset) +
- '-' + QByteArray::number(requestEndOffset);
+ '-' + (requestEndOffset ? QByteArray::number(requestEndOffset) : QByteArray());
httpRequest.setHeaderField("Range", requestRange);
} else {
@@ -773,10 +774,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool())
httpRequest.setPipeliningAllowed(true);
- if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool())
- httpRequest.setSPDYAllowed(true);
-
- if (request.attribute(QNetworkRequest::HTTP2AllowedAttribute).toBool())
+ if (request.attribute(QNetworkRequest::Http2AllowedAttribute).toBool())
httpRequest.setHTTP2Allowed(true);
if (request.attribute(QNetworkRequest::Http2DirectAttribute).toBool()) {
@@ -967,7 +965,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
QSharedPointer<char>(),
delegate->incomingContentLength,
delegate->removedContentLength,
- delegate->isSpdyUsed);
+ delegate->isHttp2Used);
replyDownloadData(delegate->synchronousDownloadData);
httpError(delegate->incomingErrorCode, delegate->incomingErrorDetail);
} else {
@@ -979,7 +977,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
QSharedPointer<char>(),
delegate->incomingContentLength,
delegate->removedContentLength,
- delegate->isSpdyUsed);
+ delegate->isHttp2Used);
replyDownloadData(delegate->synchronousDownloadData);
}
@@ -1253,7 +1251,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
QSharedPointer<char> db,
qint64 contentLength,
qint64 removedContentLength,
- bool spdyWasUsed)
+ bool h2Used)
{
Q_Q(QNetworkReplyHttpImpl);
Q_UNUSED(contentLength);
@@ -1279,16 +1277,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
}
q->setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, pu);
- const QVariant http2Allowed = request.attribute(QNetworkRequest::HTTP2AllowedAttribute);
- const QVariant http2Direct = request.attribute(QNetworkRequest::Http2DirectAttribute);
- if ((http2Allowed.isValid() && http2Allowed.toBool())
- || (http2Direct.isValid() && http2Direct.toBool())) {
- q->setAttribute(QNetworkRequest::HTTP2WasUsedAttribute, spdyWasUsed);
- q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, false);
- } else {
- q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, spdyWasUsed);
- q->setAttribute(QNetworkRequest::HTTP2WasUsedAttribute, false);
- }
+ q->setAttribute(QNetworkRequest::Http2WasUsedAttribute, h2Used);
// reconstruct the HTTP header
QList<QPair<QByteArray, QByteArray> > headerMap = hm;
diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp
index 53784407d8..f28b8415d1 100644
--- a/src/network/access/qnetworkreplywasmimpl.cpp
+++ b/src/network/access/qnetworkreplywasmimpl.cpp
@@ -63,6 +63,8 @@ static void q_requestErrorCallback(val event)
return;
val xhr = event["target"];
+ if (xhr.isNull() || xhr.isUndefined())
+ return;
quintptr func = xhr["data-handler"].as<quintptr>();
QNetworkReplyWasmImplPrivate *reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(func);
@@ -84,6 +86,8 @@ static void q_progressCallback(val event)
return;
val xhr = event["target"];
+ if (xhr.isNull() || xhr.isUndefined())
+ return;
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>());
@@ -99,6 +103,8 @@ static void q_loadCallback(val event)
return;
val xhr = event["target"];
+ if (xhr.isNull() || xhr.isUndefined())
+ return;
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>());
@@ -123,8 +129,13 @@ static void q_loadCallback(val event)
} else if (responseType == "arraybuffer" || responseType == "blob") {
// handle this data in the FileReader, triggered by the call to readAsArrayBuffer
val blob = xhr["response"];
+ if (blob.isNull() || blob.isUndefined())
+ return;
val reader = val::global("FileReader").new_();
+ if (reader.isNull() || reader.isUndefined())
+ return;
+
reader.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_readBinary"));
reader.set("data-handler", xhr["data-handler"]);
@@ -151,6 +162,8 @@ static void q_responseHeadersCallback(val event)
return;
val xhr = event["target"];
+ if (xhr.isNull() || xhr.isUndefined())
+ return;
if (xhr["readyState"].as<int>() == 2) { // HEADERS_RECEIVED
std::string responseHeaders = xhr.call<std::string>("getAllResponseHeaders");
@@ -170,6 +183,8 @@ static void q_readBinary(val event)
return;
val fileReader = event["target"];
+ if (fileReader.isNull() || fileReader.isUndefined())
+ return;
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fileReader["data-handler"].as<quintptr>());
@@ -180,6 +195,9 @@ static void q_readBinary(val event)
// Set up source typed array
val result = fileReader["result"]; // ArrayBuffer
+ if (result.isNull() || result.isUndefined())
+ return;
+
val Uint8Array = val::global("Uint8Array");
val sourceTypedArray = Uint8Array.new_(result);
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 118fb6b1fb..1deaa03f71 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -272,24 +272,13 @@ QT_BEGIN_NAMESPACE
The QNetworkSession ConnectInBackground property will be set according to
this attribute.
- \value SpdyAllowedAttribute
- Requests only, type: QMetaType::Bool (default: false)
- Indicates whether the QNetworkAccessManager code is
- allowed to use SPDY with this request. This applies only
- to SSL requests, and depends on the server supporting SPDY.
-
- \value SpdyWasUsedAttribute
- Replies only, type: QMetaType::Bool
- Indicates whether SPDY was used for receiving
- this reply.
-
- \value HTTP2AllowedAttribute
+ \value Http2AllowedAttribute
Requests only, type: QMetaType::Bool (default: false)
Indicates whether the QNetworkAccessManager code is
allowed to use HTTP/2 with this request. This applies
to SSL requests or 'cleartext' HTTP/2.
- \value HTTP2WasUsedAttribute
+ \value Http2WasUsedAttribute
Replies only, type: QMetaType::Bool (default: false)
Indicates whether HTTP/2 was used for receiving this reply.
(This value was introduced in 5.9.)
@@ -329,7 +318,7 @@ QT_BEGIN_NAMESPACE
server supports HTTP/2. The attribute works with SSL or 'cleartext'
HTTP/2. If a server turns out to not support HTTP/2, when HTTP/2 direct
was specified, QNetworkAccessManager gives up, without attempting to
- fall back to HTTP/1.1. If both HTTP2AllowedAttribute and
+ fall back to HTTP/1.1. If both Http2AllowedAttribute and
Http2DirectAttribute are set, Http2DirectAttribute takes priority.
(This value was introduced in 5.11.)
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index e09ff8aaae..95b5dc89b5 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -89,12 +89,10 @@ public:
DownloadBufferAttribute, // internal
SynchronousRequestAttribute, // internal
BackgroundRequestAttribute,
- SpdyAllowedAttribute,
- SpdyWasUsedAttribute,
- EmitAllUploadProgressSignalsAttribute,
+ EmitAllUploadProgressSignalsAttribute = BackgroundRequestAttribute + 3,
FollowRedirectsAttribute,
- HTTP2AllowedAttribute,
- HTTP2WasUsedAttribute,
+ Http2AllowedAttribute,
+ Http2WasUsedAttribute,
OriginalContentLengthAttribute,
RedirectPolicyAttribute,
Http2DirectAttribute,
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
deleted file mode 100644
index f845235bf7..0000000000
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ /dev/null
@@ -1,1304 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qspdyprotocolhandler_p.h>
-#include <private/qnoncontiguousbytedevice_p.h>
-#include <private/qhttpnetworkconnectionchannel_p.h>
-#include <QtCore/QtEndian>
-
-#if !defined(QT_NO_SSL)
-
-QT_BEGIN_NAMESPACE
-
-static const char spdyDictionary[] = {
- 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti
- 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h
- 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p
- 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p
- 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de
- 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete....
- 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace...
- 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept.
- 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
- 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse
- 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc
- 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding....
- 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l
- 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage.
- 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep
- 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges
- 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age.
- 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow
- 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth
- 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio
- 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac
- 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr
- 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co
- 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection
- 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont
- 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base
- 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont
- 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding....
- 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content-
- 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language
- 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont
- 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng
- 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co
- 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation..
- 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
- 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5...
- 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content
- 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range..
- 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten
- 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type..
- 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date..
- 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag..
- 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect
- 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi
- 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f
- 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h
- 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i
- 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match.
- 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo
- 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s
- 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince....
- 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none-
- 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match...
- 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang
- 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if-
- 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi
- 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since
- 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last
- 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie
- 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation...
- 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for
- 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards...
- 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma.
- 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy
- 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate...
- 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza
- 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion....
- 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range...
- 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer
- 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr
- 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after.
- 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve
- 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te.
- 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail
- 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr
- 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e
- 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding.
- 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra
- 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us
- 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent
- 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary
- 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via.
- 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni
- 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww
- 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen
- 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate..
- 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method
- 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get.
- 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu
- 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200
- 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion..
- 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1
- 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur
- 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub
- 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s
- 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki
- 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee
- 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive.
- 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi
- 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012
- 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205
- 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030
- 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043
- 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307
- 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540
- 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084
- 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411
- 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341
- 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164
- 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504
- 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N
- 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho
- 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative
- 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa
- 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204.
- 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte
- 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo
- 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm
- 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4
- 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40
- 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth
- 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40
- 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid
- 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N
- 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found
- 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte
- 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser
- 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro
- 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not
- 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme
- 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503.
- 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service.
- 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila
- 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F
- 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A
- 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J
- 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A
- 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept.
- 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov.
- 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0
- 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon
- 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W
- 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu.
- 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa
- 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun..
- 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk
- 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text.
- 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima
- 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i
- 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg
- 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g
- 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
- 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x
- 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml
- 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl
- 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text
- 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr
- 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ
- 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat
- 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age
- 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de
- 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd
- 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse
- 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c
- 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i
- 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859-
- 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-..
- 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0.
-};
-
-// uncomment to debug
-//static void printHex(const QByteArray &ba)
-//{
-// QByteArray hex;
-// QByteArray clearText;
-// for (int a = 0; a < ba.count(); ++a) {
-// QByteArray currentHexChar = QByteArray(1, ba.at(a)).toHex().rightJustified(2, ' ');
-// QByteArray currentChar;
-// if (ba.at(a) >= 32 && ba.at(a) < 126) { // if ASCII, print the letter
-// currentChar = QByteArray(1, ba.at(a));
-// } else {
-// currentChar = " ";
-// }
-// clearText.append(currentChar.rightJustified(2, ' '));
-// hex.append(currentHexChar);
-// hex.append(' ');
-// clearText.append(' ');
-// }
-// int chunkSize = 102; // 12 == 4 bytes per line
-// for (int a = 0; a < hex.count(); a += chunkSize) {
-// qDebug() << hex.mid(a, chunkSize);
-// qDebug() << clearText.mid(a, chunkSize);
-// }
-//}
-
-QSpdyProtocolHandler::QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel)
- : QObject(0), QAbstractProtocolHandler(channel),
- m_nextStreamID(-1),
- m_maxConcurrentStreams(100), // 100 is recommended in the SPDY RFC
- m_initialWindowSize(0),
- m_waitingForCompleteStream(false)
-{
- m_inflateStream.zalloc = Z_NULL;
- m_inflateStream.zfree = Z_NULL;
- m_inflateStream.opaque = Z_NULL;
- int zlibRet = inflateInit(&m_inflateStream);
- Q_ASSERT(zlibRet == Z_OK);
-
- m_deflateStream.zalloc = Z_NULL;
- m_deflateStream.zfree = Z_NULL;
- m_deflateStream.opaque = Z_NULL;
-
- // Do actually not compress (i.e. compression level = 0)
- // when sending the headers because of the CRIME attack
- zlibRet = deflateInit(&m_deflateStream, /* compression level = */ 0);
- Q_ASSERT(zlibRet == Z_OK);
- Q_UNUSED(zlibRet); // silence -Wunused-variable
-}
-
-QSpdyProtocolHandler::~QSpdyProtocolHandler()
-{
- deflateEnd(&m_deflateStream);
- deflateEnd(&m_inflateStream);
-}
-
-bool QSpdyProtocolHandler::sendRequest()
-{
- Q_ASSERT(!m_reply);
-
- int maxPossibleRequests = m_maxConcurrentStreams - m_inFlightStreams.count();
- Q_ASSERT(maxPossibleRequests >= 0);
- if (maxPossibleRequests == 0)
- return true; // return early if max concurrent requests are exceeded
-
- m_channel->state = QHttpNetworkConnectionChannel::WritingState;
-
- int requestsToSend = qMin(m_channel->spdyRequestsToSend.size(), maxPossibleRequests);
-
- QMultiMap<int, HttpMessagePair>::iterator it = m_channel->spdyRequestsToSend.begin();
- // requests will be ordered by priority (see QMultiMap doc)
- for (int a = 0; a < requestsToSend; ++a) {
- HttpMessagePair currentPair = *it;
- QHttpNetworkRequest currentRequest = currentPair.first;
- QHttpNetworkReply *currentReply = currentPair.second;
-
- currentReply->setSpdyWasUsed(true);
- qint32 streamID = generateNextStreamID();
- m_streamIDs.insert(currentReply, streamID);
-
- currentReply->setRequest(currentRequest);
- currentReply->d_func()->connection = m_connection;
- currentReply->d_func()->connectionChannel = m_channel;
- m_inFlightStreams.insert(streamID, currentPair);
- connect(currentReply, SIGNAL(destroyed(QObject*)), this, SLOT(_q_replyDestroyed(QObject*)));
-
- sendSYN_STREAM(currentPair, streamID, /* associatedToStreamID = */ 0);
- m_channel->spdyRequestsToSend.erase(it++);
- }
- m_channel->state = QHttpNetworkConnectionChannel::IdleState;
- return true;
-}
-
-void QSpdyProtocolHandler::_q_replyDestroyed(QObject* reply)
-{
- qint32 streamID = m_streamIDs.take(reply);
- if (m_inFlightStreams.remove(streamID))
- sendRST_STREAM(streamID, RST_STREAM_CANCEL);
-}
-
-void QSpdyProtocolHandler::_q_receiveReply()
-{
- Q_ASSERT(m_socket);
-
- // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
- // this function is called from _q_disconnected which is called because
- // of ~QHttpNetworkConnectionPrivate
- if (!qobject_cast<QHttpNetworkConnection*>(m_connection)) {
- return;
- }
-
- if (bytesAvailable() < 8)
- return; // cannot read frame headers, wait for more data
-
- char frameHeadersRaw[8];
- if (!readNextChunk(8, frameHeadersRaw))
- return; // this should not happen, we just checked
-
- const QByteArray frameHeaders(frameHeadersRaw, 8); // ### try without memcpy
- if (frameHeadersRaw[0] & 0x80) {
- handleControlFrame(frameHeaders);
- } else {
- handleDataFrame(frameHeaders);
- }
-
- // after handling the current frame, check whether there is more data waiting
- if (m_socket->bytesAvailable() > 0)
- QMetaObject::invokeMethod(m_channel, "_q_receiveReply", Qt::QueuedConnection);
-}
-
-void QSpdyProtocolHandler::_q_readyRead()
-{
- _q_receiveReply();
-}
-
-static qint16 twoBytesToInt(const char *bytes)
-{
- return qFromBigEndian<qint16>(bytes);
-}
-
-static qint32 threeBytesToInt(const char *bytes)
-{
- return qFromBigEndian<qint32>(bytes) >> 8;
-}
-
-static qint32 fourBytesToInt(const char *bytes)
-{
- return qFromBigEndian<qint32>(bytes);
-}
-
-static void appendIntToThreeBytes(char *output, qint32 number)
-{
- qToBigEndian<qint16>(number, output + 1);
- qToBigEndian<qint8>(number >> 16, output);
-}
-
-static void appendIntToFourBytes(char *output, qint32 number)
-{
- qToBigEndian<qint32>(number, output);
-}
-
-static QByteArray intToFourBytes(qint32 number) // ### try to use appendIntToFourBytes where possible
-{
- char data[4];
- qToBigEndian<qint32>(number, data);
- QByteArray ret(data, 4);
- return ret;
-}
-
-static QByteArray intToThreeBytes(qint32 number)
-{
- char data[4];
- qToBigEndian<qint32>(number << 8, data);
- QByteArray ret(data, 3);
- return ret;
-}
-
-static qint32 getStreamID(const char *bytes)
-{
- // eliminate most significant bit; it might be 0 or 1 depending on whether
- // we are dealing with a control or data frame
- return fourBytesToInt(bytes) & 0x3fffffff;
-}
-
-static QByteArray headerField(const QByteArray &name, const QByteArray &value)
-{
- QByteArray ret;
- ret.reserve(name.count() + value.count() + 8); // 4 byte for length each
- ret.append(intToFourBytes(name.count()));
- ret.append(name);
- ret.append(intToFourBytes(value.count()));
- ret.append(value);
- return ret;
-}
-
-bool QSpdyProtocolHandler::uncompressHeader(const QByteArray &input, QByteArray *output)
-{
- const size_t chunkSize = 1024;
- char outputRaw[chunkSize];
- // input bytes will not be changed by zlib, so it is safe to const_cast here
- m_inflateStream.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(input.constData()));
- m_inflateStream.avail_in = input.count();
- m_inflateStream.total_in = input.count();
- int zlibRet;
-
- do {
- m_inflateStream.next_out = reinterpret_cast<Bytef *>(outputRaw);
- m_inflateStream.avail_out = chunkSize;
- zlibRet = inflate(&m_inflateStream, Z_SYNC_FLUSH);
- if (zlibRet == Z_NEED_DICT) {
- zlibRet = inflateSetDictionary(&m_inflateStream,
- reinterpret_cast<const Bytef*>(spdyDictionary),
- /* dictionaryLength = */ 1423);
- Q_ASSERT(zlibRet == Z_OK);
- continue;
- }
- switch (zlibRet) {
- case Z_BUF_ERROR: {
- if (m_inflateStream.avail_in == 0) {
- int outputSize = chunkSize - m_inflateStream.avail_out;
- output->append(outputRaw, outputSize);
- m_inflateStream.avail_out = chunkSize;
- }
- break;
- }
- case Z_OK: {
- int outputSize = chunkSize - m_inflateStream.avail_out;
- output->append(outputRaw, outputSize);
- break;
- }
- default: {
- qWarning("got unexpected zlib return value: %d", zlibRet);
- return false;
- }
- }
- } while (m_inflateStream.avail_in > 0 && zlibRet != Z_STREAM_END);
-
- Q_ASSERT(m_inflateStream.avail_in == 0);
- return true;
-}
-
-QByteArray QSpdyProtocolHandler::composeHeader(const QHttpNetworkRequest &request)
-{
- QByteArray uncompressedHeader;
- uncompressedHeader.reserve(300); // rough estimate
-
- // calculate additional headers first, because we need to know the size
- // ### do not partially copy the list, but restrict the set header fields
- // in QHttpNetworkConnection
- QVector<QPair<QByteArray, QByteArray> > additionalHeaders;
- for (int a = 0; a < request.header().count(); ++a) {
- QByteArray key = request.header().at(a).first;
- if (key == "Connection" || key == "Host" || key == "Keep-Alive"
- || key == "Proxy-Connection" || key == "Transfer-Encoding")
- continue; // those headers are not valid (section 3.2.1)
- additionalHeaders.append(request.header().at(a));
- }
-
- qint32 numberOfHeaderPairs = 5 + additionalHeaders.count(); // 5 mandatory below + the additional ones
- uncompressedHeader.append(intToFourBytes(numberOfHeaderPairs));
-
- // mandatory header fields:
-
- uncompressedHeader.append(headerField(":method", request.methodName()));
-#ifndef QT_NO_NETWORKPROXY
- bool useProxy = m_connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy;
- uncompressedHeader.append(headerField(":path", request.uri(useProxy)));
-#else
- uncompressedHeader.append(headerField(":path", request.uri(false)));
-#endif
- uncompressedHeader.append(headerField(":version", "HTTP/1.1"));
-
- uncompressedHeader.append(headerField(":host", request.url().authority(QUrl::FullyEncoded | QUrl::RemoveUserInfo).toLatin1()));
-
- uncompressedHeader.append(headerField(":scheme", request.url().scheme().toLatin1()));
-
- // end of mandatory header fields
-
- // now add the additional headers
- for (int a = 0; a < additionalHeaders.count(); ++a) {
- uncompressedHeader.append(headerField(additionalHeaders.at(a).first.toLower(),
- additionalHeaders.at(a).second));
- }
-
- m_deflateStream.total_in = uncompressedHeader.count();
- m_deflateStream.avail_in = uncompressedHeader.count();
- m_deflateStream.next_in = reinterpret_cast<unsigned char *>(uncompressedHeader.data());
- int outputBytes = uncompressedHeader.count() + 30; // 30 bytes of compression header overhead
- m_deflateStream.avail_out = outputBytes;
- unsigned char *out = new unsigned char[outputBytes];
- m_deflateStream.next_out = out;
- int availOutBefore = m_deflateStream.avail_out;
- int zlibRet = deflate(&m_deflateStream, Z_SYNC_FLUSH); // do everything in one go since we use no compression
- int compressedHeaderSize = availOutBefore - m_deflateStream.avail_out;
- Q_ASSERT(zlibRet == Z_OK); // otherwise, we need to allocate more outputBytes
- Q_UNUSED(zlibRet); // silence -Wunused-variable
- Q_ASSERT(m_deflateStream.avail_in == 0);
- QByteArray compressedHeader(reinterpret_cast<char *>(out), compressedHeaderSize);
- delete[] out;
-
- return compressedHeader;
-}
-
-quint64 QSpdyProtocolHandler::bytesAvailable() const
-{
- Q_ASSERT(m_socket);
- return m_spdyBuffer.byteAmount() + m_socket->bytesAvailable();
-}
-
-bool QSpdyProtocolHandler::readNextChunk(qint64 length, char *sink)
-{
- qint64 expectedReadBytes = length;
- qint64 requiredBytesFromBuffer = 0;
-
- if (m_waitingForCompleteStream) {
- requiredBytesFromBuffer = qMin(length, m_spdyBuffer.byteAmount());
- // ### if next chunk from buffer bigger than what we want to read,
- // we have to call read() (which memcpy's). Otherwise, we can just
- // read the next chunk without memcpy'ing.
- qint64 bytesReadFromBuffer = m_spdyBuffer.read(sink, requiredBytesFromBuffer);
- Q_ASSERT(bytesReadFromBuffer == requiredBytesFromBuffer);
- if (length <= bytesReadFromBuffer) {
- return true; // buffer > required size -> no need to read from socket
- }
- expectedReadBytes -= requiredBytesFromBuffer;
- }
- qint64 readBytes = m_socket->read(sink + requiredBytesFromBuffer, expectedReadBytes);
-
- if (readBytes < expectedReadBytes) {
- m_waitingForCompleteStream = true;
- // ### this is inefficient, we should not put back so much data into the buffer
- QByteArray temp(sink, requiredBytesFromBuffer + readBytes);
- m_spdyBuffer.append(temp);
- return false;
- } else {
- return true; // buffer must be cleared by calling function
- }
-}
-
-void QSpdyProtocolHandler::sendControlFrame(FrameType type,
- ControlFrameFlags flags,
- const char *data,
- quint32 length)
-{
- // frame type and stream ID
- char header[8];
- header[0] = 0x80u; // leftmost bit == 1 -> is a control frame
- header[1] = 0x03; // 3 bit == version 3
- header[2] = 0;
- switch (type) {
- case FrameType_CREDENTIAL: {
- qWarning("sending SPDY CREDENTIAL frame is not yet implemented"); // QTBUG-36188
- return;
- }
- default:
- header[3] = type;
- }
-
- // flags
- header[4] = 0;
- if (flags & ControlFrame_FLAG_FIN || length == 0) {
- Q_ASSERT(type == FrameType_SYN_STREAM || type == FrameType_SYN_REPLY
- || type == FrameType_HEADERS || length == 0);
- header[4] |= ControlFrame_FLAG_FIN;
- }
- if (flags & ControlFrame_FLAG_UNIDIRECTIONAL) {
- Q_ASSERT(type == FrameType_SYN_STREAM);
- header[4] |= ControlFrame_FLAG_UNIDIRECTIONAL;
- }
-
- // length
- appendIntToThreeBytes(header + 5, length);
-
- qint64 written = m_socket->write(header, 8);
- Q_ASSERT(written == 8);
- written = m_socket->write(data, length);
- Q_ASSERT(written == length);
- Q_UNUSED(written); // silence -Wunused-variable
-}
-
-void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair,
- qint32 streamID, qint32 associatedToStreamID)
-{
- QHttpNetworkRequest request = messagePair.first;
- QHttpNetworkReply *reply = messagePair.second;
-
- ControlFrameFlags flags = 0;
-
- if (!request.uploadByteDevice()) {
- // no upload -> this is the last frame, send the FIN flag
- flags |= ControlFrame_FLAG_FIN;
- reply->d_func()->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;
- } else {
- reply->d_func()->state = QHttpNetworkReplyPrivate::SPDYUploading;
-
- // hack: set the stream ID on the device directly, so when we get
- // the signal for uploading we know which stream we are sending on
- m_streamIDs.insert(request.uploadByteDevice(), streamID);
-
- QObject::connect(request.uploadByteDevice(), SIGNAL(readyRead()), this,
- SLOT(_q_uploadDataReadyRead()), Qt::QueuedConnection);
- QObject::connect(request.uploadByteDevice(), SIGNAL(destroyed(QObject*)), this,
- SLOT(_q_uploadDataDestroyed(QObject *)));
- }
-
- QByteArray namesAndValues = composeHeader(request);
- quint32 length = namesAndValues.count() + 10; // 10 == 4 for Stream-ID + 4 for Associated-To-Stream-ID
- // + 2 for Priority, Unused and Slot
-
- QByteArray wireData;
- wireData.reserve(length);
- wireData.append(intToFourBytes(streamID));
- wireData.append(intToFourBytes(associatedToStreamID));
-
- // priority (3 bits) / unused (5 bits) / slot (8 bits)
- char prioAndSlot[2];
- switch (request.priority()) {
- case QHttpNetworkRequest::HighPriority:
- prioAndSlot[0] = 0x00; // == prio 0 (highest)
- break;
- case QHttpNetworkRequest::NormalPriority:
- prioAndSlot[0] = 0x80u; // == prio 4
- break;
- case QHttpNetworkRequest::LowPriority:
- prioAndSlot[0] = 0xe0u; // == prio 7 (lowest)
- break;
- }
- prioAndSlot[1] = 0x00; // slot in client certificates (not supported currently)
- wireData.append(prioAndSlot, 2);
-
- wireData.append(namesAndValues);
-
- sendControlFrame(FrameType_SYN_STREAM, flags, wireData.constData(), length);
-
- if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYUploading)
- uploadData(streamID);
-}
-
-void QSpdyProtocolHandler::_q_uploadDataDestroyed(QObject *uploadData)
-{
- m_streamIDs.remove(uploadData);
-}
-
-void QSpdyProtocolHandler::sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode)
-{
- char wireData[8];
- appendIntToFourBytes(wireData, streamID);
- appendIntToFourBytes(wireData + 4, statusCode);
- sendControlFrame(FrameType_RST_STREAM, /* flags = */ 0, wireData, /* length = */ 8);
-}
-
-void QSpdyProtocolHandler::sendPING(quint32 pingID)
-{
- char rawData[4];
- appendIntToFourBytes(rawData, pingID);
- sendControlFrame(FrameType_PING, /* flags = */ 0, rawData, /* length = */ 4);
-}
-
-bool QSpdyProtocolHandler::uploadData(qint32 streamID)
-{
- // we only rely on SPDY flow control here and don't care about TCP buffers
- if (!m_inFlightStreams.contains(streamID)) {
- sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);
- return false;
- }
-
- HttpMessagePair messagePair = m_inFlightStreams.value(streamID);
- QHttpNetworkRequest request = messagePair.first;
- QHttpNetworkReply *reply = messagePair.second;
- Q_ASSERT(reply);
- QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
- Q_ASSERT(replyPrivate);
-
- if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
- qWarning("Trying to upload to closed stream");
- return false;
- }
-
- qint32 dataLeftInWindow = replyPrivate->windowSizeUpload
- - replyPrivate->currentlyUploadedDataInWindow;
-
- while (dataLeftInWindow > 0 && !request.uploadByteDevice()->atEnd()) {
-
- // get pointer to upload data
- qint64 currentReadSize = 0;
- const char *readPointer = request.uploadByteDevice()->readPointer(dataLeftInWindow,
- currentReadSize);
-
- if (currentReadSize == -1) {
- // premature eof happened
- m_connection->d_func()->emitReplyError(m_socket, reply,
- QNetworkReply::UnknownNetworkError);
- return false;
- } else if (readPointer == 0 || currentReadSize == 0) {
- // nothing to read currently, break the loop
- break;
- } else {
- DataFrameFlags flags = 0;
- // we will send the FIN flag later if appropriate
- qint64 currentWriteSize = sendDataFrame(streamID, flags, currentReadSize, readPointer);
- if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
- // socket broke down
- m_connection->d_func()->emitReplyError(m_socket, reply,
- QNetworkReply::UnknownNetworkError);
- return false;
- } else {
- replyPrivate->currentlyUploadedDataInWindow += currentWriteSize;
- replyPrivate->totallyUploadedData += currentWriteSize;
- dataLeftInWindow = replyPrivate->windowSizeUpload
- - replyPrivate->currentlyUploadedDataInWindow;
- request.uploadByteDevice()->advanceReadPointer(currentWriteSize);
-
- emit reply->dataSendProgress(replyPrivate->totallyUploadedData,
- request.contentLength());
- }
- }
- }
- if (replyPrivate->totallyUploadedData == request.contentLength()) {
- DataFrameFlags finFlag = DataFrame_FLAG_FIN;
- qint64 writeSize = sendDataFrame(streamID, finFlag, 0, 0);
- Q_ASSERT(writeSize == 0);
- Q_UNUSED(writeSize); // silence -Wunused-variable
- replyPrivate->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;
- if (reply->request().uploadByteDevice())
- reply->request().uploadByteDevice()->disconnect(this);
- // ### this will not work if the content length is not known, but
- // then again many servers will fail in this case anyhow according
- // to the SPDY RFC
- }
- return true;
-}
-
-void QSpdyProtocolHandler::_q_uploadDataReadyRead()
-{
- QNonContiguousByteDevice *device = qobject_cast<QNonContiguousByteDevice *>(sender());
- Q_ASSERT(device);
- qint32 streamID = m_streamIDs.value(device);
- Q_ASSERT(streamID > 0);
- uploadData(streamID);
-}
-
-void QSpdyProtocolHandler::sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindowSize)
-{
- char windowUpdateData[8];
- appendIntToFourBytes(windowUpdateData, streamID);
- appendIntToFourBytes(windowUpdateData + 4, deltaWindowSize);
-
- sendControlFrame(FrameType_WINDOW_UPDATE, /* flags = */ 0, windowUpdateData, /* length = */ 8);
-}
-
-qint64 QSpdyProtocolHandler::sendDataFrame(qint32 streamID, DataFrameFlags flags,
- quint32 length, const char *data)
-{
- QByteArray wireData;
- wireData.reserve(8);
-
- wireData.append(intToFourBytes(streamID));
- wireData.append(flags);
- wireData.append(intToThreeBytes(length));
-
- Q_ASSERT(m_socket);
- m_socket->write(wireData);
-
- if (data) {
- qint64 ret = m_socket->write(data, length);
- return ret;
- } else {
- return 0; // nothing to write, e.g. FIN flag
- }
-}
-
-void QSpdyProtocolHandler::handleControlFrame(const QByteArray &frameHeaders) // ### make it char *
-{
- Q_ASSERT(frameHeaders.count() >= 8);
- qint16 version = twoBytesToInt(frameHeaders.constData());
- version &= 0x3fff; // eliminate most significant bit to determine version
- Q_ASSERT(version == 3);
-
- qint16 type = twoBytesToInt(frameHeaders.constData() + 2);
-
- char flags = frameHeaders.at(4);
- qint32 length = threeBytesToInt(frameHeaders.constData() + 5);
- Q_ASSERT(length > 0);
-
- QByteArray frameData;
- frameData.resize(length);
- if (!readNextChunk(length, frameData.data())) {
- // put back the frame headers to the buffer
- m_spdyBuffer.prepend(frameHeaders);
- return; // we couldn't read the whole frame and need to wait
- } else {
- m_spdyBuffer.clear();
- m_waitingForCompleteStream = false;
- }
-
- switch (type) {
- case FrameType_SYN_STREAM: {
- handleSYN_STREAM(flags, length, frameData);
- break;
- }
- case FrameType_SYN_REPLY: {
- handleSYN_REPLY(flags, length, frameData);
- break;
- }
- case FrameType_RST_STREAM: {
- handleRST_STREAM(flags, length, frameData);
- break;
- }
- case FrameType_SETTINGS: {
- handleSETTINGS(flags, length, frameData);
- break;
- }
- case FrameType_PING: {
- handlePING(flags, length, frameData);
- break;
- }
- case FrameType_GOAWAY: {
- handleGOAWAY(flags, length, frameData);
- break;
- }
- case FrameType_HEADERS: {
- handleHEADERS(flags, length, frameData);
- break;
- }
- case FrameType_WINDOW_UPDATE: {
- handleWINDOW_UPDATE(flags, length, frameData);
- break;
- }
- default:
- qWarning("cannot handle frame of type %d", int(type));
- }
-}
-
-void QSpdyProtocolHandler::handleSYN_STREAM(char /*flags*/, quint32 /*length*/,
- const QByteArray &frameData)
-{
- // not implemented; will be implemented when servers start using it
- // we just tell the server that we do not accept that
-
- qint32 streamID = getStreamID(frameData.constData());
-
- sendRST_STREAM(streamID, RST_STREAM_REFUSED_STREAM);
-}
-
-void QSpdyProtocolHandler::handleSYN_REPLY(char flags, quint32 /*length*/, const QByteArray &frameData)
-{
- parseHttpHeaders(flags, frameData);
-}
-
-void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameData)
-{
- qint32 streamID = getStreamID(frameData.constData());
- const auto it = m_inFlightStreams.constFind(streamID);
- if (it == m_inFlightStreams.cend()) {
- sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);
- return;
- }
-
- flags &= 0x3f;
- bool flag_fin = flags & 0x01;
-
- QByteArray headerValuePairs = frameData.mid(4);
-
- HttpMessagePair pair = it.value();
- QHttpNetworkReply *httpReply = pair.second;
- Q_ASSERT(httpReply != 0);
-
- if (httpReply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
- sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);
- return;
- }
-
- QByteArray uncompressedHeader;
- if (!uncompressHeader(headerValuePairs, &uncompressedHeader)) {
- qWarning("error reading header from SYN_REPLY message");
- return;
- }
-
- qint32 headerCount = fourBytesToInt(uncompressedHeader.constData());
- if (headerCount * 8 > uncompressedHeader.size()) {
- qWarning("error parsing header from SYN_REPLY message");
- sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
- return;
- }
- qint32 readPointer = 4;
- for (qint32 a = 0; a < headerCount; ++a) {
- qint32 count = fourBytesToInt(uncompressedHeader.constData() + readPointer);
- readPointer += 4;
- QByteArray name = uncompressedHeader.mid(readPointer, count);
- readPointer += count;
- if (readPointer > uncompressedHeader.size()) {
- qWarning("error parsing header from SYN_REPLY message");
- sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
- return;
- }
- count = fourBytesToInt(uncompressedHeader.constData() + readPointer);
- readPointer += 4;
- QByteArray value = uncompressedHeader.mid(readPointer, count);
- readPointer += count;
- if (readPointer > uncompressedHeader.size()) {
- qWarning("error parsing header from SYN_REPLY message");
- sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
- return;
- }
- if (name == ":status") {
- httpReply->setStatusCode(value.left(3).toInt());
- httpReply->d_func()->reasonPhrase = QString::fromLatin1(value.mid(4));
- } else if (name == ":version") {
- int majorVersion = value.at(5) - 48;
- int minorVersion = value.at(7) - 48;
- httpReply->d_func()->majorVersion = majorVersion;
- httpReply->d_func()->minorVersion = minorVersion;
- } else if (name == "content-length") {
- httpReply->setContentLength(value.toLongLong());
- } else {
- value.replace('\0', name == "set-cookie" ? "\n" : ", ");
- httpReply->setHeaderField(name, value);
- }
- }
- emit httpReply->headerChanged();
-
- if (flag_fin) {
- if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
- sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
- replyFinished(httpReply, streamID);
- }
-}
-
-void QSpdyProtocolHandler::handleRST_STREAM(char /*flags*/, quint32 length,
- const QByteArray &frameData)
-{
- // flags are ignored
-
- Q_ASSERT(length == 8);
- Q_UNUSED(length); // silence -Wunused-parameter
- qint32 streamID = getStreamID(frameData.constData());
- QHttpNetworkReply *httpReply = m_inFlightStreams.value(streamID).second;
-
- qint32 statusCodeInt = fourBytesToInt(frameData.constData() + 4);
- RST_STREAM_STATUS_CODE statusCode = static_cast<RST_STREAM_STATUS_CODE>(statusCodeInt);
- QNetworkReply::NetworkError errorCode;
- QByteArray errorMessage;
-
- switch (statusCode) {
- case RST_STREAM_PROTOCOL_ERROR:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "SPDY protocol error";
- break;
- case RST_STREAM_INVALID_STREAM:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "SPDY stream is not active";
- break;
- case RST_STREAM_REFUSED_STREAM:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "SPDY stream was refused";
- break;
- case RST_STREAM_UNSUPPORTED_VERSION:
- errorCode = QNetworkReply::ProtocolUnknownError;
- errorMessage = "SPDY version is unknown to the server";
- break;
- case RST_STREAM_CANCEL:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "SPDY stream is no longer needed";
- break;
- case RST_STREAM_INTERNAL_ERROR:
- errorCode = QNetworkReply::InternalServerError;
- errorMessage = "Internal server error";
- break;
- case RST_STREAM_FLOW_CONTROL_ERROR:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "peer violated the flow control protocol";
- break;
- case RST_STREAM_STREAM_IN_USE:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "server received a SYN_REPLY for an already open stream";
- break;
- case RST_STREAM_STREAM_ALREADY_CLOSED:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "server received data or a SYN_REPLY for an already half-closed stream";
- break;
- case RST_STREAM_INVALID_CREDENTIALS:
- errorCode = QNetworkReply::ContentAccessDenied;
- errorMessage = "server received invalid credentials";
- break;
- case RST_STREAM_FRAME_TOO_LARGE:
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "server cannot process the frame because it is too large";
- break;
- default:
- qWarning("could not understand servers RST_STREAM status code");
- errorCode = QNetworkReply::ProtocolFailure;
- errorMessage = "got SPDY RST_STREAM message with unknown error code";
- }
- if (httpReply)
- replyFinishedWithError(httpReply, streamID, errorCode, errorMessage.constData());
-}
-
-void QSpdyProtocolHandler::handleSETTINGS(char flags, quint32 /*length*/, const QByteArray &frameData)
-{
- Q_ASSERT(frameData.count() > 0);
-
- SETTINGS_Flags settingsFlags = static_cast<SETTINGS_Flags>(flags);
- if (settingsFlags & FLAG_SETTINGS_CLEAR_SETTINGS) {
- // ### clear all persistent settings; since we do not persist settings
- // as of now, we don't need to clear anything either
- }
-
- qint32 numberOfEntries = fourBytesToInt(frameData.constData());
- Q_ASSERT(numberOfEntries > 0);
- for (int a = 0, frameDataIndex = 4; a < numberOfEntries; ++a, frameDataIndex += 8) {
- SETTINGS_ID_Flag idFlag = static_cast<SETTINGS_ID_Flag>(frameData[frameDataIndex]);
- if (idFlag & FLAG_SETTINGS_PERSIST_VALUE) {
- // ### we SHOULD persist the settings here according to the RFC, but we don't have to,
- // so implement that later
- } // the other value is only sent by us, but not received
-
- quint32 uniqueID = static_cast<SETTINGS_ID>(
- threeBytesToInt(frameData.constData() + frameDataIndex + 1));
- quint32 value = fourBytesToInt(frameData.constData() + frameDataIndex + 4);
- switch (uniqueID) {
- case SETTINGS_UPLOAD_BANDWIDTH: {
- // ignored for now, just an estimated informative value
- break;
- }
- case SETTINGS_DOWNLOAD_BANDWIDTH: {
- // ignored for now, just an estimated informative value
- break;
- }
- case SETTINGS_ROUND_TRIP_TIME: {
- // ignored for now, just an estimated informative value
- break;
- }
- case SETTINGS_MAX_CONCURRENT_STREAMS: {
- m_maxConcurrentStreams = value;
- break;
- }
- case SETTINGS_CURRENT_CWND: {
- // ignored for now, just an informative value
- break;
- }
- case SETTINGS_DOWNLOAD_RETRANS_RATE: {
- // ignored for now, just an estimated informative value
- break;
- }
- case SETTINGS_INITIAL_WINDOW_SIZE: {
- m_initialWindowSize = value;
- break;
- }
- case SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE: {
- // client certificates are not supported
- break;
- }
- default:
- qWarning("found unknown settings value %u", uint(value));
- }
- }
-}
-
-void QSpdyProtocolHandler::handlePING(char /*flags*/, quint32 length, const QByteArray &frameData)
-{
- // flags are ignored
-
- Q_ASSERT(length == 4);
- Q_UNUSED(length); // silence -Wunused-parameter
- quint32 pingID = fourBytesToInt(frameData.constData());
-
- // odd numbered IDs must be ignored
- if ((pingID & 1) == 0) // is even?
- sendPING(pingID);
-}
-
-void QSpdyProtocolHandler::handleGOAWAY(char /*flags*/, quint32 /*length*/,
- const QByteArray &frameData)
-{
- // flags are ignored
-
- qint32 statusCode = static_cast<GOAWAY_STATUS>(fourBytesToInt(frameData.constData() + 4));
- QNetworkReply::NetworkError errorCode;
- switch (statusCode) {
- case GOAWAY_OK: {
- errorCode = QNetworkReply::NoError;
- break;
- }
- case GOAWAY_PROTOCOL_ERROR: {
- errorCode = QNetworkReply::ProtocolFailure;
- break;
- }
- case GOAWAY_INTERNAL_ERROR: {
- errorCode = QNetworkReply::InternalServerError;
- break;
- }
- default:
- qWarning("unexpected status code %d", int(statusCode));
- errorCode = QNetworkReply::ProtocolUnknownError;
- }
-
- qint32 lastGoodStreamID = getStreamID(frameData.constData());
-
- // emit errors for all replies after the last good stream ID
- Q_ASSERT(m_connection);
- for (qint32 currentStreamID = lastGoodStreamID + 2; currentStreamID <= m_nextStreamID;
- ++currentStreamID) {
- QHttpNetworkReply *reply = m_inFlightStreams.value(currentStreamID).second;
- Q_ASSERT(reply);
- m_connection->d_func()->emitReplyError(m_socket, reply, errorCode);
- }
- // ### we could make sure a new session is initiated anyhow
-}
-
-void QSpdyProtocolHandler::handleHEADERS(char flags, quint32 /*length*/,
- const QByteArray &frameData)
-{
- parseHttpHeaders(flags, frameData);
-}
-
-void QSpdyProtocolHandler::handleWINDOW_UPDATE(char /*flags*/, quint32 /*length*/,
- const QByteArray &frameData)
-{
- qint32 streamID = getStreamID(frameData.constData());
- qint32 deltaWindowSize = fourBytesToInt(frameData.constData() + 4);
-
- const auto it = m_inFlightStreams.constFind(streamID);
- if (it == m_inFlightStreams.cend()) {
- sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);
- return;
- }
-
- QHttpNetworkReply *reply = it.value().second;
- Q_ASSERT(reply);
- QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
- Q_ASSERT(replyPrivate);
-
- // Ignore WINDOW_UPDATE if we are already done.
- if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed)
- return;
-
- replyPrivate->currentlyUploadedDataInWindow = replyPrivate->windowSizeUpload - deltaWindowSize;
- uploadData(streamID); // we hopefully can continue to upload
-}
-
-
-void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)
-{
- Q_ASSERT(frameHeaders.count() >= 8);
-
- qint32 streamID = getStreamID(frameHeaders.constData());
- const auto it = m_inFlightStreams.constFind(streamID);
- if (it == m_inFlightStreams.cend()) {
- sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);
- return;
- }
-
- unsigned char flags = static_cast<unsigned char>(frameHeaders.at(4));
- flags &= 0x3f;
- bool flag_fin = flags & 0x01;
- bool flag_compress = flags & 0x02;
- qint32 length = threeBytesToInt(frameHeaders.constData() + 5);
-
- QByteArray data;
- data.resize(length);
- if (!readNextChunk(length, data.data())) {
- // put back the frame headers to the buffer
- m_spdyBuffer.prepend(frameHeaders);
- return; // we couldn't read the whole frame and need to wait
- } else {
- m_spdyBuffer.clear();
- m_waitingForCompleteStream = false;
- }
-
- HttpMessagePair pair = it.value();
- QHttpNetworkRequest httpRequest = pair.first;
- QHttpNetworkReply *httpReply = pair.second;
- Q_ASSERT(httpReply != 0);
-
- QHttpNetworkReplyPrivate *replyPrivate = httpReply->d_func();
-
- if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed) {
- sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);
- return;
- }
-
- // check whether we need to send WINDOW_UPDATE (i.e. tell the sender it can send more)
- replyPrivate->currentlyReceivedDataInWindow += length;
- qint32 dataLeftInWindow = replyPrivate->windowSizeDownload - replyPrivate->currentlyReceivedDataInWindow;
-
- if (replyPrivate->currentlyReceivedDataInWindow > 0
- && dataLeftInWindow < replyPrivate->windowSizeDownload / 2) {
-
- // socket read buffer size is 64K actually, hard coded in the channel
- // We can read way more than 64K per socket, because the window size
- // here is per stream.
- if (replyPrivate->windowSizeDownload >= m_socket->readBufferSize()) {
- replyPrivate->windowSizeDownload = m_socket->readBufferSize();
- } else {
- replyPrivate->windowSizeDownload *= 1.5;
- }
- QMetaObject::invokeMethod(this, "sendWINDOW_UPDATE", Qt::QueuedConnection,
- Q_ARG(qint32, streamID),
- Q_ARG(quint32, replyPrivate->windowSizeDownload));
- // setting the current data count to 0 is a race condition,
- // because we call sendWINDOW_UPDATE through the event loop.
- // But then again, the whole situation is a race condition because
- // we don't know when the packet will arrive at the server; so
- // this is most likely good enough here.
- replyPrivate->currentlyReceivedDataInWindow = 0;
- }
-
- httpReply->d_func()->compressedData.append(data);
-
-
- replyPrivate->totalProgress += length;
-
- if (httpRequest.d->autoDecompress && httpReply->d_func()->isCompressed()) {
- QByteDataBuffer inDataBuffer; // ### should we introduce one in the http reply?
- inDataBuffer.append(data);
- qint64 compressedCount = httpReply->d_func()->uncompressBodyData(&inDataBuffer,
- &replyPrivate->responseData);
- Q_ASSERT(compressedCount >= 0);
- Q_UNUSED(compressedCount); // silence -Wunused-variable
- } else {
- replyPrivate->responseData.append(data);
- }
-
- if (replyPrivate->shouldEmitSignals()) {
- emit httpReply->readyRead();
- emit httpReply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
- }
-
- if (flag_compress) {
- qWarning("SPDY level compression is not supported");
- }
-
- if (flag_fin) {
- if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
- sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
- replyFinished(httpReply, streamID);
- }
-}
-
-void QSpdyProtocolHandler::replyFinished(QHttpNetworkReply *httpReply, qint32 streamID)
-{
- httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed;
- httpReply->disconnect(this);
- if (httpReply->request().uploadByteDevice())
- httpReply->request().uploadByteDevice()->disconnect(this);
- int streamsRemoved = m_inFlightStreams.remove(streamID);
- Q_ASSERT(streamsRemoved == 1);
- Q_UNUSED(streamsRemoved); // silence -Wunused-variable
- emit httpReply->finished();
-}
-
-void QSpdyProtocolHandler::replyFinishedWithError(QHttpNetworkReply *httpReply, qint32 streamID,
- QNetworkReply::NetworkError errorCode, const char *errorMessage)
-{
- Q_ASSERT(httpReply);
- httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed;
- httpReply->disconnect(this);
- if (httpReply->request().uploadByteDevice())
- httpReply->request().uploadByteDevice()->disconnect(this);
- int streamsRemoved = m_inFlightStreams.remove(streamID);
- Q_ASSERT(streamsRemoved == 1);
- Q_UNUSED(streamsRemoved); // silence -Wunused-variable
- emit httpReply->finishedWithError(errorCode, QSpdyProtocolHandler::tr(errorMessage));
-}
-
-qint32 QSpdyProtocolHandler::generateNextStreamID()
-{
- // stream IDs initiated by the client must be odd
- m_nextStreamID += 2;
- return m_nextStreamID;
-}
-
-QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_SSL)
diff --git a/src/network/access/qspdyprotocolhandler_p.h b/src/network/access/qspdyprotocolhandler_p.h
deleted file mode 100644
index 14e2ff388a..0000000000
--- a/src/network/access/qspdyprotocolhandler_p.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSPDYPROTOCOLHANDLER_H
-#define QSPDYPROTOCOLHANDLER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the Network Access API. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtNetwork/private/qtnetworkglobal_p.h>
-#include <private/qabstractprotocolhandler_p.h>
-#include <QtNetwork/qnetworkreply.h>
-#include <private/qbytedata_p.h>
-
-#include <zlib.h>
-
-QT_REQUIRE_CONFIG(http);
-
-#if !defined(QT_NO_SSL)
-
-QT_BEGIN_NAMESPACE
-
-class QHttpNetworkRequest;
-
-#ifndef HttpMessagePair
-typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
-#endif
-
-class QSpdyProtocolHandler : public QObject, public QAbstractProtocolHandler {
- Q_OBJECT
-public:
- QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel);
- ~QSpdyProtocolHandler();
-
- enum DataFrameFlag {
- DataFrame_FLAG_FIN = 0x01,
- DataFrame_FLAG_COMPRESS = 0x02
- };
-
- Q_DECLARE_FLAGS(DataFrameFlags, DataFrameFlag)
-
- enum ControlFrameFlag {
- ControlFrame_FLAG_FIN = 0x01,
- ControlFrame_FLAG_UNIDIRECTIONAL = 0x02
- };
-
- Q_DECLARE_FLAGS(ControlFrameFlags, ControlFrameFlag)
-
- enum SETTINGS_Flag {
- FLAG_SETTINGS_CLEAR_SETTINGS = 0x01
- };
-
- Q_DECLARE_FLAGS(SETTINGS_Flags, SETTINGS_Flag)
-
- enum SETTINGS_ID_Flag {
- FLAG_SETTINGS_PERSIST_VALUE = 0x01,
- FLAG_SETTINGS_PERSISTED = 0x02
- };
-
- Q_DECLARE_FLAGS(SETTINGS_ID_Flags, SETTINGS_ID_Flag)
-
- virtual void _q_receiveReply() override;
- virtual void _q_readyRead() override;
- virtual bool sendRequest() override;
-
-private slots:
- void _q_uploadDataReadyRead();
- void _q_replyDestroyed(QObject*);
- void _q_uploadDataDestroyed(QObject *);
-
-private:
-
- enum FrameType {
- FrameType_SYN_STREAM = 1,
- FrameType_SYN_REPLY = 2,
- FrameType_RST_STREAM = 3,
- FrameType_SETTINGS = 4,
- FrameType_PING = 6,
- FrameType_GOAWAY = 7,
- FrameType_HEADERS = 8,
- FrameType_WINDOW_UPDATE = 9,
- FrameType_CREDENTIAL // has a special type
- };
-
- enum StatusCode {
- StatusCode_PROTOCOL_ERROR = 1,
- StatusCode_INVALID_STREAM = 2,
- StatusCode_REFUSED_STREAM = 3,
- StatusCode_UNSUPPORTED_VERSION = 4,
- StatusCode_CANCEL = 5,
- StatusCode_INTERNAL_ERROR = 6,
- StatusCode_FLOW_CONTROL_ERROR = 7,
- StatusCode_STREAM_IN_USE = 8,
- StatusCode_STREAM_ALREADY_CLOSED = 9,
- StatusCode_INVALID_CREDENTIALS = 10,
- StatusCode_FRAME_TOO_LARGE = 11
- };
-
- enum SETTINGS_ID {
- SETTINGS_UPLOAD_BANDWIDTH = 1,
- SETTINGS_DOWNLOAD_BANDWIDTH = 2,
- SETTINGS_ROUND_TRIP_TIME = 3,
- SETTINGS_MAX_CONCURRENT_STREAMS = 4,
- SETTINGS_CURRENT_CWND = 5,
- SETTINGS_DOWNLOAD_RETRANS_RATE = 6,
- SETTINGS_INITIAL_WINDOW_SIZE = 7,
- SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8
- };
-
- enum GOAWAY_STATUS {
- GOAWAY_OK = 0,
- GOAWAY_PROTOCOL_ERROR = 1,
- GOAWAY_INTERNAL_ERROR = 11
- };
-
- enum RST_STREAM_STATUS_CODE {
- RST_STREAM_PROTOCOL_ERROR = 1,
- RST_STREAM_INVALID_STREAM = 2,
- RST_STREAM_REFUSED_STREAM = 3,
- RST_STREAM_UNSUPPORTED_VERSION = 4,
- RST_STREAM_CANCEL = 5,
- RST_STREAM_INTERNAL_ERROR = 6,
- RST_STREAM_FLOW_CONTROL_ERROR = 7,
- RST_STREAM_STREAM_IN_USE = 8,
- RST_STREAM_STREAM_ALREADY_CLOSED = 9,
- RST_STREAM_INVALID_CREDENTIALS = 10,
- RST_STREAM_FRAME_TOO_LARGE = 11
- };
-
- quint64 bytesAvailable() const;
- bool readNextChunk(qint64 length, char *sink);
-
- void sendControlFrame(FrameType type, ControlFrameFlags flags, const char *data, quint32 length);
-
- void sendSYN_STREAM(const HttpMessagePair &pair, qint32 streamID,
- qint32 associatedToStreamID);
- void sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode);
- void sendPING(quint32 pingID);
-
- bool uploadData(qint32 streamID);
- Q_INVOKABLE void sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindowSize);
-
- qint64 sendDataFrame(qint32 streamID, DataFrameFlags flags, quint32 length,
- const char *data);
-
- QByteArray composeHeader(const QHttpNetworkRequest &request);
- bool uncompressHeader(const QByteArray &input, QByteArray *output);
-
- void handleControlFrame(const QByteArray &frameHeaders);
- void handleDataFrame(const QByteArray &frameHeaders);
-
- void handleSYN_STREAM(char, quint32, const QByteArray &frameData);
- void handleSYN_REPLY(char flags, quint32, const QByteArray &frameData);
- void handleRST_STREAM(char flags, quint32 length, const QByteArray &frameData);
- void handleSETTINGS(char flags, quint32 length, const QByteArray &frameData);
- void handlePING(char, quint32 length, const QByteArray &frameData);
- void handleGOAWAY(char flags, quint32, const QByteArray &frameData);
- void handleHEADERS(char flags, quint32, const QByteArray &frameData);
- void handleWINDOW_UPDATE(char, quint32, const QByteArray &frameData);
-
- qint32 generateNextStreamID();
- void parseHttpHeaders(char flags, const QByteArray &frameData);
-
- void replyFinished(QHttpNetworkReply *httpReply, qint32 streamID);
- void replyFinishedWithError(QHttpNetworkReply *httpReply, qint32 streamID,
- QNetworkReply::NetworkError errorCode, const char *errorMessage);
-
- qint32 m_nextStreamID;
- QHash<quint32, HttpMessagePair> m_inFlightStreams;
- qint32 m_maxConcurrentStreams;
- quint32 m_initialWindowSize;
- QByteDataBuffer m_spdyBuffer;
- bool m_waitingForCompleteStream;
- z_stream m_deflateStream;
- z_stream m_inflateStream;
- QHash<QObject *, qint32> m_streamIDs;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::DataFrameFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::ControlFrameFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_Flags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_ID_Flags)
-
-QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_SSL)
-
-#endif // QSPDYPROTOCOLHANDLER_H
diff --git a/src/network/configure.json b/src/network/configure.json
index f80f38f143..0ecee2c572 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -98,6 +98,30 @@
"condition": "!config.msvc"
}
]
+ },
+ "gssapi": {
+ "label": "KRB5 GSSAPI Support",
+ "test": {
+ "head": [
+ "#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))",
+ "# include <TargetConditionals.h>",
+ "# if defined(TARGET_OS_MAC) && TARGET_OS_MAC",
+ "# include <GSS/GSS.h>",
+ "# endif",
+ "#else",
+ "# include <gssapi/gssapi.h>",
+ "#endif"
+ ],
+ "main": [
+ "gss_ctx_id_t ctx;",
+ "gss_context_time(nullptr, ctx, nullptr);"
+ ]
+ },
+ "sources": [
+ { "libs": "-framework GSS", "condition": "config.darwin" },
+ { "type": "pkgConfig", "args": "krb5-gssapi" },
+ "-lgssapi_krb5"
+ ]
}
},
@@ -200,15 +224,6 @@
},
"use": "openssl"
},
- "gssapi": {
- "label": "KRB5 GSSAPI support",
- "type": "compile",
- "test": {
- "include": [ "gssapi/gssapi.h" ],
- "main": ["gss_ctx_id_t ctx;"],
- "qmake": "LIBS += -lgssapi_krb5"
- }
- },
"netlistmgr": {
"label": "Network List Manager",
"type": "compile",
@@ -385,7 +400,11 @@
"purpose": "Provides bearer management for the network stack.",
"section": "Networking",
"condition": "features.thread && features.library && features.networkinterface && features.properties",
- "output": [ "publicFeature", "feature" ]
+ "output": [
+ "publicFeature",
+ "feature",
+ { "type": "define", "negative": true, "name": "QT_NO_BEARERMANAGEMENT" }
+ ]
},
"localserver": {
"label": "QLocalServer",
@@ -404,7 +423,7 @@
"label": "GSSAPI",
"purpose": "Enable SPNEGO authentication through GSSAPI",
"section": "Networking",
- "condition": "!config.win32 && tests.gssapi",
+ "condition": "!config.win32 && libs.gssapi",
"output": [ "publicFeature", "feature" ]
},
"sspi": {
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index a55648dbc7..110d9f56bf 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -83,7 +83,7 @@ macos | ios {
SOURCES += kernel/qnetconmonitor_stub.cpp
}
-qtConfig(gssapi): LIBS_PRIVATE += -lgssapi_krb5
+qtConfig(gssapi): QMAKE_USE_PRIVATE += gssapi
uikit:HEADERS += kernel/qnetworkinterface_uikit_p.h
osx:SOURCES += kernel/qnetworkproxy_mac.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 4100dfd784..33a30eb1cd 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -59,8 +59,12 @@
#define SECURITY_WIN32 1
#include <security.h>
#elif QT_CONFIG(gssapi) // GSSAPI
+#if defined(Q_OS_DARWIN)
+#include <GSS/GSS.h>
+#else
#include <gssapi/gssapi.h>
-#endif
+#endif // Q_OS_DARWIN
+#endif // Q_CONFIG(sspi)
QT_BEGIN_NAMESPACE
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 9ce2d72bd3..f9335c3bb9 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -595,7 +595,9 @@ QHostInfo::QHostInfo(const QHostInfo &other)
}
/*!
- Move-constucts a new QHostInfo from \a other.
+ \fn QHostInfo(QHostInfo &&other)
+
+ Move-constructs a new QHostInfo from \a other.
\note The moved-from object \a other is placed in a
partially-formed state, in which the only valid operations are
diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp
index a010df8e3a..1566e7f914 100644
--- a/src/network/kernel/qnetconmonitor_win.cpp
+++ b/src/network/kernel/qnetconmonitor_win.cpp
@@ -103,7 +103,7 @@ class QNetworkConnectionEvents : public INetworkConnectionEvents
{
public:
QNetworkConnectionEvents(QNetworkConnectionMonitorPrivate *monitor);
- ~QNetworkConnectionEvents();
+ virtual ~QNetworkConnectionEvents();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
@@ -471,7 +471,7 @@ class QNetworkListManagerEvents : public INetworkListManagerEvents
{
public:
QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor);
- ~QNetworkListManagerEvents();
+ virtual ~QNetworkListManagerEvents();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index 4caedaa38f..c65ea58860 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -50,7 +50,6 @@
QT_BEGIN_NAMESPACE
class QDeadlineTimer;
-template<typename T> class QList;
class QNetworkAddressEntryPrivate;
class Q_NETWORK_EXPORT QNetworkAddressEntry
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index c28c5ea9e6..4c57bff3bc 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -485,6 +485,7 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
struct ifreq req;
};
int socket = -1;
+ memset(&mediareq, 0, sizeof(mediareq));
// ensure both structs start with the name field, of size IFNAMESIZ
Q_STATIC_ASSERT(sizeof(mediareq.ifm_name) == sizeof(req.ifr_name));
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 110550c423..a2a89ed94b 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -493,8 +493,10 @@ template<> void QSharedDataPointer<QNetworkProxyPrivate>::detach()
}
/*!
- Constructs a QNetworkProxy with DefaultProxy type; the proxy type is
- determined by applicationProxy(), which defaults to NoProxy.
+ Constructs a QNetworkProxy with DefaultProxy type.
+
+ The proxy type is determined by applicationProxy(), which defaults to
+ NoProxy or a system-wide proxy if one is configured.
\sa setType(), setApplicationProxy()
*/
diff --git a/src/network/network.pro b/src/network/network.pro
index 9082439f1c..d8453e879c 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -26,7 +26,7 @@ qtConfig(bearermanagement) {
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
jar/QtAndroidBearer.jar
ANDROID_LIB_DEPENDENCIES = \
- plugins/bearer/libqandroidbearer.so
+ plugins/bearer/libplugins_bearer_qandroidbearer.so
MODULE_PLUGIN_TYPES = \
bearer
ANDROID_PERMISSIONS += \
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 9edabd7822..dd115c33dc 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -53,6 +53,8 @@
#include <qnetworkinterface.h>
#include <qoperatingsystemversion.h>
+#include <algorithm>
+
//#define QNATIVESOCKETENGINE_DEBUG
#if defined(QNATIVESOCKETENGINE_DEBUG)
# include <qstring.h>
@@ -1141,13 +1143,14 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
qint64 ret = -1;
int recvResult = 0;
DWORD flags;
- // We start at 1500 bytes (the MTU for Ethernet V2), which should catch
- // almost all uses (effective MTU for UDP under IPv4 is 1468), except
- // for localhost datagrams and those reassembled by the IP layer.
- char udpMessagePeekBuffer[1500];
- std::vector<WSABUF> buf;
+ // We increase the amount we peek by 2048 * 5 on each iteration
+ // Grabs most cases fast and early.
+ char udpMessagePeekBuffer[2048];
+ const int increments = 5;
+ QVarLengthArray<WSABUF, 10> buf;
for (;;) {
- buf.resize(buf.size() + 5, {sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
+ buf.reserve(buf.size() + increments);
+ std::fill_n(std::back_inserter(buf), increments, WSABUF{sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
flags = MSG_PEEK;
DWORD bytesRead = 0;
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 7e92d3a526..738c8d4ac5 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -54,7 +54,6 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
|QSsl::SslOptionDisableSessionPersistence;
const char QSslConfiguration::ALPNProtocolHTTP2[] = "h2";
-const char QSslConfiguration::NextProtocolSpdy3_0[] = "spdy/3";
const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
/*!
@@ -134,12 +133,6 @@ const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
*/
/*!
- \variable QSslConfiguration::NextProtocolSpdy3_0
- \brief The value used for negotiating SPDY 3.0 during the Next
- Protocol Negotiation.
-*/
-
-/*!
\variable QSslConfiguration::NextProtocolHttp1_1
\brief The value used for negotiating HTTP 1.1 during the Next
Protocol Negotiation.
@@ -631,11 +624,10 @@ QList<QSslCipher> QSslConfiguration::supportedCiphers()
Returns this connection's CA certificate database. The CA certificate
database is used by the socket during the handshake phase to
validate the peer's certificate. It can be modified prior to the
- handshake with setCaCertificates(), or with \l{QSslSocket}'s
- \l{QSslSocket::}{addCaCertificate()} and
- \l{QSslSocket::}{addCaCertificates()}.
+ handshake with setCaCertificates(), or with addCaCertificate() and
+ addCaCertificates().
- \sa setCaCertificates()
+ \sa setCaCertificates(), addCaCertificate(), addCaCertificates()
*/
QList<QSslCertificate> QSslConfiguration::caCertificates() const
{
@@ -652,7 +644,7 @@ QList<QSslCertificate> QSslConfiguration::caCertificates() const
that is not available (as is commonly the case on iOS), the default database
is empty.
- \sa caCertificates()
+ \sa caCertificates(), addCaCertificates(), addCaCertificate()
*/
void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certificates)
{
@@ -661,6 +653,72 @@ void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certific
}
/*!
+ Searches all files in the \a path for certificates encoded in the
+ specified \a format and adds them to this socket's CA certificate
+ database. \a path must be a file or a pattern matching one or more
+ files, as specified by \a syntax. Returns \c true if one or more
+ certificates are added to the socket's CA certificate database;
+ otherwise returns \c false.
+
+ The CA certificate database is used by the socket during the
+ handshake phase to validate the peer's certificate.
+
+ For more precise control, use addCaCertificate().
+
+ \sa addCaCertificate(), QSslCertificate::fromPath()
+*/
+bool QSslConfiguration::addCaCertificates(const QString &path, QSsl::EncodingFormat format,
+ QRegExp::PatternSyntax syntax)
+{
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(path, format, syntax);
+ if (certs.isEmpty())
+ return false;
+
+ d->caCertificates += certs;
+ return true;
+}
+
+/*!
+ \since 5.15
+
+ Adds \a certificate to this configuration's CA certificate database.
+ The certificate database must be set prior to the SSL handshake.
+ The CA certificate database is used by the socket during the
+ handshake phase to validate the peer's certificate.
+
+ \note The default configuration uses the system CA certificate database. If
+ that is not available (as is commonly the case on iOS), the default database
+ is empty.
+
+ \sa caCertificates(), setCaCertificates(), addCaCertificates()
+*/
+void QSslConfiguration::addCaCertificate(const QSslCertificate &certificate)
+{
+ d->caCertificates += certificate;
+ d->allowRootCertOnDemandLoading = false;
+}
+
+/*!
+ \since 5.15
+
+ Adds \a certificates to this configuration's CA certificate database.
+ The certificate database must be set prior to the SSL handshake.
+ The CA certificate database is used by the socket during the
+ handshake phase to validate the peer's certificate.
+
+ \note The default configuration uses the system CA certificate database. If
+ that is not available (as is commonly the case on iOS), the default database
+ is empty.
+
+ \sa caCertificates(), setCaCertificates(), addCaCertificate()
+*/
+void QSslConfiguration::addCaCertificates(const QList<QSslCertificate> &certificates)
+{
+ d->caCertificates += certificates;
+ d->allowRootCertOnDemandLoading = false;
+}
+
+/*!
\since 5.5
This function provides the CA certificate database
@@ -668,7 +726,8 @@ void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certific
returned by this function is used to initialize the database
returned by caCertificates() on the default QSslConfiguration.
- \sa caCertificates(), setCaCertificates(), defaultConfiguration()
+ \sa caCertificates(), setCaCertificates(), defaultConfiguration(),
+ addCaCertificate(), addCaCertificates()
*/
QList<QSslCertificate> QSslConfiguration::systemCaCertificates()
{
@@ -967,7 +1026,7 @@ QByteArray QSslConfiguration::nextNegotiatedProtocol() const
Whether or not the negotiation succeeded can be queried through
nextProtocolNegotiationStatus().
- \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), allowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
+ \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), allowedNextProtocols(), QSslConfiguration::NextProtocolHttp1_1
*/
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void QSslConfiguration::setAllowedNextProtocols(const QList<QByteArray> &protocols)
@@ -985,7 +1044,7 @@ void QSslConfiguration::setAllowedNextProtocols(QList<QByteArray> protocols)
server through the Next Protocol Negotiation (NPN) or Application-Layer
Protocol Negotiation (ALPN) TLS extension, as set by setAllowedNextProtocols().
- \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
+ \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolHttp1_1
*/
QList<QByteArray> QSslConfiguration::allowedNextProtocols() const
{
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index c25c2686de..ad6e23638f 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -66,7 +66,6 @@
QT_BEGIN_NAMESPACE
-template<typename T> class QList;
class QSslCertificate;
class QSslCipher;
class QSslKey;
@@ -131,6 +130,11 @@ public:
// Certificate Authority (CA) settings
QList<QSslCertificate> caCertificates() const;
void setCaCertificates(const QList<QSslCertificate> &certificates);
+ bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
+ QRegExp::PatternSyntax syntax = QRegExp::FixedString);
+ void addCaCertificate(const QSslCertificate &certificate);
+ void addCaCertificates(const QList<QSslCertificate> &certificates);
+
static QList<QSslCertificate> systemCaCertificates();
void setSslOption(QSsl::SslOption option, bool on);
@@ -188,7 +192,6 @@ public:
NextProtocolNegotiationStatus nextProtocolNegotiationStatus() const;
static const char ALPNProtocolHTTP2[];
- static const char NextProtocolSpdy3_0[];
static const char NextProtocolHttp1_1[];
private:
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index e81e5582f4..8566d78aef 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -157,32 +157,36 @@ SSL* QSslContext::createSsl()
for (int a = 0; a < protocols.count(); ++a) {
if (protocols.at(a).size() > 255) {
qCWarning(lcSsl) << "TLS NPN extension" << protocols.at(a)
- << "is too long and will be truncated to 255 characters.";
- protocols[a] = protocols.at(a).left(255);
+ << "is too long and will be ignored.";
+ continue;
+ } else if (protocols.at(a).isEmpty()) {
+ continue;
}
m_supportedNPNVersions.append(protocols.at(a).size()).append(protocols.at(a));
}
- m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
- m_npnContext.len = m_supportedNPNVersions.count();
- m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
+ if (m_supportedNPNVersions.size()) {
+ m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
+ m_npnContext.len = m_supportedNPNVersions.count();
+ m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
- // Callback's type has a parameter 'const unsigned char ** out'
- // since it was introduced in 1.0.2. Internally, OpenSSL's own code
- // (tests/examples) cast it to unsigned char * (since it's 'out').
- // We just re-use our NPN callback and cast here:
- typedef int (*alpn_callback_t) (SSL *, const unsigned char **, unsigned char *,
- const unsigned char *, unsigned int, void *);
- // With ALPN callback is for a server side only, for a client m_npnContext.status
- // will stay in NextProtocolNegotiationNone.
- q_SSL_CTX_set_alpn_select_cb(ctx, alpn_callback_t(next_proto_cb), &m_npnContext);
- // Client:
- q_SSL_set_alpn_protos(ssl, m_npnContext.data, m_npnContext.len);
- }
+ if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
+ // Callback's type has a parameter 'const unsigned char ** out'
+ // since it was introduced in 1.0.2. Internally, OpenSSL's own code
+ // (tests/examples) cast it to unsigned char * (since it's 'out').
+ // We just re-use our NPN callback and cast here:
+ typedef int (*alpn_callback_t) (SSL *, const unsigned char **, unsigned char *,
+ const unsigned char *, unsigned int, void *);
+ // With ALPN callback is for a server side only, for a client m_npnContext.status
+ // will stay in NextProtocolNegotiationNone.
+ q_SSL_CTX_set_alpn_select_cb(ctx, alpn_callback_t(next_proto_cb), &m_npnContext);
+ // Client:
+ q_SSL_set_alpn_protos(ssl, m_npnContext.data, m_npnContext.len);
+ }
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
- // And in case our peer does not support ALPN, but supports NPN:
- q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
+ // And in case our peer does not support ALPN, but supports NPN:
+ q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
+ }
}
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ca6c58117d..690251727d 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -139,10 +139,21 @@
before the handshake phase with setLocalCertificate() and
setPrivateKey().
\li The CA certificate database can be extended and customized with
- addCaCertificate(), addCaCertificates(), addDefaultCaCertificate(),
- addDefaultCaCertificates(), and QSslConfiguration::defaultConfiguration().setCaCertificates().
+ QSslConfiguration::addCaCertificate(),
+ QSslConfiguration::addCaCertificates().
\endlist
+ To extend the list of \e default CA certificates used by the SSL sockets
+ during the SSL handshake you must update the default configuration, as
+ in the snippet below:
+
+ \code
+ QList<QSslCertificate> certificates = getCertificates();
+ QSslConfiguration configuration = QSslConfiguration::defaultConfiguration();
+ configuration.addCaCertificates(certificates);
+ QSslConfiguration::setDefaultConfiguration(configuration);
+ \endcode
+
\note If available, root certificates on Unix (excluding \macos) will be
loaded on demand from the standard certificate directories. If you do not
want to load root certificates on demand, you need to call either
@@ -1384,6 +1395,10 @@ QList<QSslCipher> QSslSocket::supportedCiphers()
#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() instead.
+
Searches all files in the \a path for certificates encoded in the
specified \a format and adds them to this socket's CA certificate
database. \a path must be a file or a pattern matching one or more
@@ -1411,6 +1426,10 @@ bool QSslSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat for
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificate() instead.
+
Adds the \a certificate to this socket's CA certificate database.
The CA certificate database is used by the socket during the
handshake phase to validate the peer's certificate.
@@ -1427,6 +1446,10 @@ void QSslSocket::addCaCertificate(const QSslCertificate &certificate)
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() instead.
+
Adds the \a certificates to this socket's CA certificate database.
The CA certificate database is used by the socket during the
handshake phase to validate the peer's certificate.
@@ -1489,6 +1512,10 @@ QList<QSslCertificate> QSslSocket::caCertificates() const
#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() on the default QSslConfiguration instead.
+
Searches all files in the \a path for certificates with the
specified \a encoding and adds them to the default CA certificate
database. \a path can be an explicit file, or it can contain
@@ -1498,8 +1525,8 @@ QList<QSslCertificate> QSslSocket::caCertificates() const
Each SSL socket's CA certificate database is initialized to the
default CA certificate database.
- \sa QSslConfiguration::caCertificates(), addCaCertificates(),
- addDefaultCaCertificate()
+ \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates(),
+ QSslConfiguration::addDefaultCaCertificate()
*/
bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat encoding,
QRegExp::PatternSyntax syntax)
@@ -1508,11 +1535,15 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificate() on the default QSslConfiguration instead.
+
Adds \a certificate to the default CA certificate database. Each
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
@@ -1520,11 +1551,15 @@ void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() on the default QSslConfiguration instead.
+
Adds \a certificates to the default CA certificate database. Each
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::caCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certificates)
{
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 35943c7d7e..843e2d15f5 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -164,18 +164,22 @@ public:
#endif // QT_DEPRECATED_SINCE(5, 5)
// CA settings.
- bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificates()") bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
- void addCaCertificate(const QSslCertificate &certificate);
- void addCaCertificates(const QList<QSslCertificate> &certificates);
+ QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificate()") void addCaCertificate(const QSslCertificate &certificate);
+ QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificates()") void addCaCertificates(const QList<QSslCertificate> &certificates);
+#endif // QT_DEPRECATED_SINCE(5, 15)
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED_X("Use QSslConfiguration::setCaCertificates()") void setCaCertificates(const QList<QSslCertificate> &certificates);
QT_DEPRECATED_X("Use QSslConfiguration::caCertificates()") QList<QSslCertificate> caCertificates() const;
#endif // QT_DEPRECATED_SINCE(5, 5)
- static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
- static void addDefaultCaCertificate(const QSslCertificate &certificate);
- static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates);
+ QT_DEPRECATED static void addDefaultCaCertificate(const QSslCertificate &certificate);
+ QT_DEPRECATED static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates);
+#endif // QT_DEPRECATED_SINCE(5, 15)
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates);
QT_DEPRECATED static QList<QSslCertificate> defaultCaCertificates();
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 1725937bc2..e0e065679d 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -928,6 +928,13 @@ bool QSslSocketBackendPrivate::initSslContext()
QCFType<CFMutableArrayRef> cfNames(CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks));
if (cfNames) {
for (const QByteArray &name : protocolNames) {
+ if (name.size() > 255) {
+ qCWarning(lcSsl) << "TLS ALPN extension" << name
+ << "is too long and will be ignored.";
+ continue;
+ } else if (name.isEmpty()) {
+ continue;
+ }
QCFString cfName(QString::fromLatin1(name).toCFString());
CFArrayAppendValue(cfNames, cfName);
}
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
index 28be4f2e79..1d935c5217 100644
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ b/src/network/ssl/qsslsocket_openssl11.cpp
@@ -143,13 +143,12 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
if (!s_loadRootCertsOnDemand)
setDefaultCaCertificates(systemCaCertificates());
#ifdef Q_OS_WIN
- //Enabled for fetching additional root certs from windows update on windows 6+
+ //Enabled for fetching additional root certs from windows update on windows.
//This flag is set false by setDefaultCaCertificates() indicating the app uses
//its own cert bundle rather than the system one.
//Same logic that disables the unix on demand cert loading.
//Unlike unix, we do preload the certificates from the cert store.
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::WindowsVista)
- s_loadRootCertsOnDemand = true;
+ s_loadRootCertsOnDemand = true;
#endif
}
diff --git a/src/network/ssl/qsslsocket_qt.cpp b/src/network/ssl/qsslsocket_qt.cpp
index b0fb60ea76..9ff9a66c05 100644
--- a/src/network/ssl/qsslsocket_qt.cpp
+++ b/src/network/ssl/qsslsocket_qt.cpp
@@ -72,6 +72,7 @@ static QAsn1Element _q_PKCS7_data(const QByteArray &data)
Some test vectors:
http://www.drh-consultancy.demon.co.uk/test.txt
+ \internal
*/
static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QString &passPhrase, int n, int r)
{
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index c254659a33..d7fb080b49 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -408,13 +408,17 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
for (QByteArray proto : nextAllowedProtocols) {
if (proto.size() > 255) {
qCWarning(lcSsl) << "TLS ALPN extension" << proto
- << "is too long and will be truncated to 255 characters.";
- proto = proto.left(255);
+ << "is too long and will be ignored.";
+ continue;
+ } else if (proto.isEmpty()) {
+ continue;
}
protocolString += char(proto.length()) + proto;
}
return protocolString;
}();
+ if (names.isEmpty())
+ return alpnString;
const quint16 namesSize = names.size();
const quint32 alpnId = SecApplicationProtocolNegotiationExt_ALPN;
@@ -824,12 +828,17 @@ bool QSslSocketBackendPrivate::acceptContext()
&expiry // ptsTimeStamp
);
+ if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ // Need more data
+ return true;
+ }
+
if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
// inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
// be stored.
intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer));
- } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
+ } else { /* No 'extra' data, message not incomplete */
intermediateBuffer.clear();
}
@@ -1065,7 +1074,6 @@ bool QSslSocketBackendPrivate::verifyHandshake()
}
schannelState = SchannelState::Done;
- peerCertVerified = true;
return true;
}
@@ -1148,7 +1156,6 @@ void QSslSocketBackendPrivate::reset()
connectionEncrypted = false;
shutdown = false;
- peerCertVerified = false;
renegotiating = false;
}
@@ -1311,7 +1318,9 @@ void QSslSocketBackendPrivate::transmit()
#endif
intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
}
- } else if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ }
+
+ if (status == SEC_E_INCOMPLETE_MESSAGE) {
// Need more data before we can decrypt.. to the buffer it goes!
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
@@ -1356,6 +1365,7 @@ void QSslSocketBackendPrivate::transmit()
#endif
schannelState = SchannelState::Renegotiate;
renegotiating = true;
+
// We need to call 'continueHandshake' or else there's no guarantee it ever gets called
continueHandshake();
break;
@@ -1521,7 +1531,7 @@ void QSslSocketBackendPrivate::continueHandshake()
case SchannelState::VerifyHandshake:
// if we're in shutdown or renegotiating then we might not need to verify
// (since we already did)
- if (!peerCertVerified && !verifyHandshake()) {
+ if (!verifyHandshake()) {
shutdown = true; // Skip sending shutdown alert
q->abort(); // We don't want to send buffered data
disconnectFromHost();
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
index 9879e2fc60..6ab200e1f9 100644
--- a/src/network/ssl/qsslsocket_schannel_p.h
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -147,7 +147,6 @@ private:
ULONG contextAttributes = 0;
bool renegotiating = false;
- bool peerCertVerified = false;
};
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index e8ff40304e..2546f6dc13 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1391,6 +1391,8 @@ void QGL2PaintEngineEx::renderHintsChanged()
state()->renderHintsChanged = true;
#if !defined(QT_OPENGL_ES_2)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (!d->ctx->contextHandle()->isOpenGLES()) {
if ((state()->renderHints & QPainter::Antialiasing)
#if QT_DEPRECATED_SINCE(5, 14)
@@ -1401,6 +1403,7 @@ void QGL2PaintEngineEx::renderHintsChanged()
else
d->glDisable(GL_MULTISAMPLE);
}
+QT_WARNING_POP
#endif
d->lastTextureUsed = GLuint(-1);
diff --git a/src/platformsupport/edid/qedidparser.cpp b/src/platformsupport/edid/qedidparser.cpp
index 06c8852825..6bf1f1db96 100644
--- a/src/platformsupport/edid/qedidparser.cpp
+++ b/src/platformsupport/edid/qedidparser.cpp
@@ -42,8 +42,6 @@
#include "qedidparser_p.h"
#include "qedidvendortable_p.h"
-#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-
#define EDID_DESCRIPTOR_ALPHANUMERIC_STRING 0xfe
#define EDID_DESCRIPTOR_PRODUCT_NAME 0xfc
#define EDID_DESCRIPTOR_SERIAL_NUMBER 0xff
@@ -139,9 +137,9 @@ bool QEdidParser::parse(const QByteArray &blob)
manufacturer = m_vendorCache.value(pnpIdString);
if (manufacturer.isEmpty()) {
// Find the manufacturer from the vendor lookup table
- for (size_t i = 0; i < ARRAY_LENGTH(q_edidVendorTable); i++) {
- if (strncmp(q_edidVendorTable[i].id, pnpId, 3) == 0) {
- manufacturer = QString::fromUtf8(q_edidVendorTable[i].name);
+ for (const auto &vendor : q_edidVendorTable) {
+ if (strncmp(vendor.id, pnpId, 3) == 0) {
+ manufacturer = QString::fromUtf8(vendor.name);
break;
}
}
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 6011941982..8c6cc8fbc1 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -1110,16 +1110,32 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
glyph_buffer.reset(new uchar[glyph_buffer_size]);
if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
- Q_ASSERT(format == Format_Mono);
uchar *src = slot->bitmap.buffer;
uchar *dst = glyph_buffer.data();
int h = slot->bitmap.rows;
-
- int bytes = ((info.width + 7) & ~7) >> 3;
- while (h--) {
- memcpy (dst, src, bytes);
- dst += pitch;
- src += slot->bitmap.pitch;
+ // Some fonts return bitmaps even when we requested something else:
+ if (format == Format_Mono) {
+ int bytes = ((info.width + 7) & ~7) >> 3;
+ while (h--) {
+ memcpy (dst, src, bytes);
+ dst += pitch;
+ src += slot->bitmap.pitch;
+ }
+ } else if (format == Format_A8) {
+ while (h--) {
+ for (int x = 0; x < int{info.width}; x++)
+ dst[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
+ dst += pitch;
+ src += slot->bitmap.pitch;
+ }
+ } else {
+ while (h--) {
+ uint *dd = reinterpret_cast<uint *>(dst);
+ for (int x = 0; x < int{info.width}; x++)
+ dd[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffffff : 0x00000000);
+ dst += pitch;
+ src += slot->bitmap.pitch;
+ }
}
} else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) {
Q_ASSERT(format == Format_ARGB);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 047773d8e3..4887a501ba 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -48,6 +48,8 @@
#import <UIKit/UIFont.h>
#endif
+#include <QtCore/qelapsedtimer.h>
+
#include "qcoretextfontdatabase_p.h"
#include "qfontengine_coretext_p.h"
#if QT_CONFIG(settings)
@@ -100,20 +102,6 @@ static const char *languageForWritingSystem[] = {
};
enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-#ifdef Q_OS_OSX
-static NSInteger languageMapSort(id obj1, id obj2, void *context)
-{
- NSArray<NSString *> *map1 = reinterpret_cast<NSArray<NSString *> *>(obj1);
- NSArray<NSString *> *map2 = reinterpret_cast<NSArray<NSString *> *>(obj2);
- NSArray<NSString *> *languages = reinterpret_cast<NSArray<NSString *> *>(context);
-
- NSString *lang1 = [map1 objectAtIndex:0];
- NSString *lang2 = [map2 objectAtIndex:0];
-
- return [languages indexOfObject:lang1] - [languages indexOfObject:lang2];
-}
-#endif
-
QCoreTextFontDatabase::QCoreTextFontDatabase()
: m_hasPopulatedAliases(false)
{
@@ -127,39 +115,77 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
void QCoreTextFontDatabase::populateFontDatabase()
{
+ qCDebug(lcQpaFonts) << "Populating font database...";
+ QElapsedTimer elapsed;
+ if (lcQpaFonts().isDebugEnabled())
+ elapsed.start();
+
QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames();
for (NSString *familyName in familyNames.as<const NSArray *>())
QPlatformFontDatabase::registerFontFamily(QString::fromNSString(familyName));
+ qCDebug(lcQpaFonts) << "Populating available families took" << elapsed.restart() << "ms";
+
// Force creating the theme fonts to get the descriptors in m_systemFontDescriptors
if (m_themeFonts.isEmpty())
(void)themeFonts();
+ qCDebug(lcQpaFonts) << "Resolving theme fonts took" << elapsed.restart() << "ms";
+
Q_FOREACH (CTFontDescriptorRef fontDesc, m_systemFontDescriptors)
populateFromDescriptor(fontDesc);
+ qCDebug(lcQpaFonts) << "Populating system descriptors took" << elapsed.restart() << "ms";
+
Q_ASSERT(!m_hasPopulatedAliases);
}
-bool QCoreTextFontDatabase::populateFamilyAliases()
+bool QCoreTextFontDatabase::populateFamilyAliases(const QString &missingFamily)
{
#if defined(Q_OS_MACOS)
if (m_hasPopulatedAliases)
return false;
+ // There's no API to go from a localized family name to its non-localized
+ // name, so we have to resort to enumerating all the available fonts and
+ // doing a reverse lookup.
+
+ qCDebug(lcQpaFonts) << "Populating family aliases...";
+ QElapsedTimer elapsed;
+ elapsed.start();
+
+ QString nonLocalizedMatch;
QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames();
+ NSFontManager *fontManager = NSFontManager.sharedFontManager;
for (NSString *familyName in familyNames.as<const NSArray *>()) {
- NSFontManager *fontManager = [NSFontManager sharedFontManager];
NSString *localizedFamilyName = [fontManager localizedNameForFamily:familyName face:nil];
if (![localizedFamilyName isEqual:familyName]) {
- QPlatformFontDatabase::registerAliasToFontFamily(
- QString::fromNSString(familyName),
- QString::fromNSString(localizedFamilyName));
+ QString nonLocalizedFamily = QString::fromNSString(familyName);
+ QString localizedFamily = QString::fromNSString(localizedFamilyName);
+ QPlatformFontDatabase::registerAliasToFontFamily(nonLocalizedFamily, localizedFamily);
+ if (localizedFamily == missingFamily)
+ nonLocalizedMatch = nonLocalizedFamily;
}
}
m_hasPopulatedAliases = true;
+
+ if (lcQpaFonts().isWarningEnabled()) {
+ QString warningMessage;
+ QDebug msg(&warningMessage);
+
+ msg << "Populating font family aliases took" << elapsed.restart() << "ms.";
+ if (!nonLocalizedMatch.isNull())
+ msg << "Replace uses of" << missingFamily << "with its non-localized name" << nonLocalizedMatch;
+ else
+ msg << "Replace uses of missing font family" << missingFamily << "with one that exists";
+ msg << "to avoid this cost.";
+
+ qCWarning(lcQpaFonts) << qPrintable(warningMessage);
+ }
+
return true;
#else
+ Q_UNUSED(missingFamily);
return false;
#endif
}
@@ -173,7 +199,7 @@ void QCoreTextFontDatabase::populateFamily(const QString &familyName)
// A single family might match several different fonts with different styles eg.
QCFType<CFArrayRef> matchingFonts = (CFArrayRef) CTFontDescriptorCreateMatchingFontDescriptors(nameOnlyDescriptor, 0);
if (!matchingFonts) {
- qWarning() << "QCoreTextFontDatabase: Found no matching fonts for family" << familyName;
+ qCWarning(lcQpaFonts) << "QCoreTextFontDatabase: Found no matching fonts for family" << familyName;
return;
}
@@ -406,142 +432,116 @@ template class QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>;
template class QCoreTextFontDatabaseEngineFactory<QFontEngineFT>;
#endif
-QFont::StyleHint styleHintFromNSString(NSString *style)
+QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family)
{
- if ([style isEqual: @"sans-serif"])
- return QFont::SansSerif;
- else if ([style isEqual: @"monospace"])
- return QFont::Monospace;
- else if ([style isEqual: @"cursive"])
- return QFont::Cursive;
- else if ([style isEqual: @"serif"])
- return QFont::Serif;
- else if ([style isEqual: @"fantasy"])
- return QFont::Fantasy;
- else // if ([style isEqual: @"default"])
- return QFont::AnyStyle;
-}
+ if (family.isEmpty())
+ return QStringList();
-#ifdef Q_OS_OSX
-static QString familyNameFromPostScriptName(NSString *psName)
-{
- QCFType<CTFontDescriptorRef> fontDescriptor = (CTFontDescriptorRef) CTFontDescriptorCreateWithNameAndSize((CFStringRef)psName, 12.0);
- QCFString familyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute);
- QString name = QString::fromCFString(familyName);
- if (name.isEmpty())
- qWarning() << "QCoreTextFontDatabase: Failed to resolve family name for PostScript name " << QString::fromCFString((CFStringRef)psName);
+ auto attributes = @{ id(kCTFontFamilyNameAttribute): family.toNSString() };
+ QCFType<CTFontDescriptorRef> fontDescriptor = CTFontDescriptorCreateWithAttributes(CFDictionaryRef(attributes));
+ if (!fontDescriptor) {
+ qCWarning(lcQpaFonts) << "Failed to create fallback font descriptor for" << family;
+ return QStringList();
+ }
- return name;
-}
-#endif
+ QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(fontDescriptor, 12.0, 0);
+ if (!font) {
+ qCWarning(lcQpaFonts) << "Failed to create fallback font for" << family;
+ return QStringList();
+ }
-static void addExtraFallbacks(QStringList *fallbackList)
-{
-#if defined(Q_OS_MACOS)
- // Since we are only returning a list of default fonts for the current language, we do not
- // cover all unicode completely. This was especially an issue for some of the common script
- // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
- // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
- // of Unicode 2.1.
- if (!fallbackList->contains(QStringLiteral("Arial Unicode MS")))
- fallbackList->append(QStringLiteral("Arial Unicode MS"));
- // Since some symbols (specifically Braille) are not in Arial Unicode MS, we
- // add Apple Symbols to cover those too.
- if (!fallbackList->contains(QStringLiteral("Apple Symbols")))
- fallbackList->append(QStringLiteral("Apple Symbols"));
-#else
- Q_UNUSED(fallbackList)
-#endif
+ QCFType<CFArrayRef> cascadeList = CFArrayRef(CTFontCopyDefaultCascadeListForLanguages(font,
+ (CFArrayRef)[NSUserDefaults.standardUserDefaults stringArrayForKey:@"AppleLanguages"]));
+ if (!cascadeList) {
+ qCWarning(lcQpaFonts) << "Failed to create fallback cascade list for" << family;
+ return QStringList();
+ }
+
+ QStringList fallbackList;
+ const int numCascades = CFArrayGetCount(cascadeList);
+ for (int i = 0; i < numCascades; ++i) {
+ CTFontDescriptorRef fontFallback = CTFontDescriptorRef(CFArrayGetValueAtIndex(cascadeList, i));
+ QCFString fallbackFamilyName = CFStringRef(CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute));
+ fallbackList.append(QString::fromCFString(fallbackFamilyName));
+ }
+
+ return fallbackList;
}
QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
Q_UNUSED(style);
- Q_UNUSED(script);
QMacAutoReleasePool pool;
- static QHash<QString, QStringList> fallbackLists;
-
- if (!family.isEmpty()) {
- QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(family));
- if (QCFType<CTFontDescriptorRef> fontDescriptor = CTFontDescriptorCreateWithAttributes(attributes)) {
- if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(fontDescriptor, 12.0, 0)) {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"];
-
- QCFType<CFArrayRef> cascadeList = (CFArrayRef) CTFontCopyDefaultCascadeListForLanguages(font, (CFArrayRef) languages);
- if (cascadeList) {
- QStringList fallbackList;
- const int numCascades = CFArrayGetCount(cascadeList);
- for (int i = 0; i < numCascades; ++i) {
- CTFontDescriptorRef fontFallback = (CTFontDescriptorRef) CFArrayGetValueAtIndex(cascadeList, i);
- QCFString fallbackFamilyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute);
- fallbackList.append(QString::fromCFString(fallbackFamilyName));
- }
-
- addExtraFallbacks(&fallbackList);
- extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
- fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
-
- return fallbackList;
+ QStringList fallbackList = fallbacksForFamily(family);
+
+ if (fallbackList.isEmpty()) {
+ // We were not able to find a fallback for the specific family,
+ // or the family was empty, so we fall back to the style hint.
+ QString styleFamily = [styleHint]{
+ switch (styleHint) {
+ case QFont::SansSerif: return QStringLiteral("Helvetica");
+ case QFont::Serif: return QStringLiteral("Times New Roman");
+ case QFont::Monospace: return QStringLiteral("Menlo");
+#ifdef Q_OS_MACOS
+ case QFont::Cursive: return QStringLiteral("Apple Chancery");
+#endif
+ case QFont::Fantasy: return QStringLiteral("Zapfino");
+ case QFont::TypeWriter: return QStringLiteral("American Typewriter");
+ case QFont::AnyStyle: Q_FALLTHROUGH();
+ case QFont::System: {
+ QCFType<CTFontRef> font = CTFontCreateUIFontForLanguage(kCTFontUIFontSystem, 12.0, NULL);
+ return static_cast<QString>(QCFString(CTFontCopyFullName(font)));
}
+ default: return QString(); // No matching font on this platform
}
+ }();
+ if (!styleFamily.isEmpty()) {
+ fallbackList = fallbacksForFamily(styleFamily);
+ if (!fallbackList.contains(styleFamily))
+ fallbackList.prepend(styleFamily);
}
}
- // We were not able to find a fallback for the specific family,
- // so we fall back to the stylehint.
-
- static const QString styleLookupKey = QString::fromLatin1(".QFontStyleHint_%1");
-
- static bool didPopulateStyleFallbacks = false;
- if (!didPopulateStyleFallbacks) {
-#if defined(Q_OS_MACX)
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSArray<NSString *> *languages = [defaults stringArrayForKey:@"AppleLanguages"];
-
- NSDictionary<NSString *, id> *fallbackDict = [NSDictionary<NSString *, id> dictionaryWithContentsOfFile:@"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"];
-
- for (NSString *style in [fallbackDict allKeys]) {
- NSArray *list = [fallbackDict valueForKey:style];
- QFont::StyleHint fallbackStyleHint = styleHintFromNSString(style);
- QStringList fallbackList;
- for (id item in list) {
- // sort the array based on system language preferences
- if ([item isKindOfClass:[NSArray class]]) {
- NSArray *langs = [reinterpret_cast<NSArray *>(item)
- sortedArrayUsingFunction:languageMapSort context:languages];
- for (NSArray<NSString *> *map in langs)
- fallbackList.append(familyNameFromPostScriptName([map objectAtIndex:1]));
- }
- else if ([item isKindOfClass: [NSString class]])
- fallbackList.append(familyNameFromPostScriptName(item));
- }
+ if (fallbackList.isEmpty())
+ return fallbackList;
- fallbackList.append(QLatin1String("Apple Color Emoji"));
+ // .Apple Symbols Fallback will be at the beginning of the list and we will
+ // detect that this has glyphs for Arabic and other writing systems.
+ // Since it is a symbol font, it should be the last resort, so that
+ // the proper fonts for these writing systems are preferred.
+ int symbolIndex = fallbackList.indexOf(QLatin1String(".Apple Symbols Fallback"));
+ if (symbolIndex >= 0)
+ fallbackList.move(symbolIndex, fallbackList.size() - 1);
- addExtraFallbacks(&fallbackList);
- fallbackLists[styleLookupKey.arg(fallbackStyleHint)] = fallbackList;
- }
-#else
- QStringList staticFallbackList;
- staticFallbackList << QString::fromLatin1("Helvetica,Apple Color Emoji,Geeza Pro,Arial Hebrew,Thonburi,Kailasa"
- "Hiragino Kaku Gothic ProN,.Heiti J,Apple SD Gothic Neo,.Heiti K,Heiti SC,Heiti TC"
- "Bangla Sangam MN,Devanagari Sangam MN,Gujarati Sangam MN,Gurmukhi MN,Kannada Sangam MN"
- "Malayalam Sangam MN,Oriya Sangam MN,Sinhala Sangam MN,Tamil Sangam MN,Telugu Sangam MN"
- "Euphemia UCAS,.PhoneFallback").split(QLatin1String(","));
-
- for (int i = QFont::Helvetica; i <= QFont::Fantasy; ++i)
- fallbackLists[styleLookupKey.arg(i)] = staticFallbackList;
+#if defined(Q_OS_MACOS)
+ // Since we are only returning a list of default fonts for the current language, we do not
+ // cover all Unicode completely. This was especially an issue for some of the common script
+ // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
+ // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
+ // of Unicode 2.1.
+ if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
+ fallbackList.append(QStringLiteral("Arial Unicode MS"));
+ // Since some symbols (specifically Braille) are not in Arial Unicode MS, we
+ // add Apple Symbols to cover those too.
+ if (!fallbackList.contains(QStringLiteral("Apple Symbols")))
+ fallbackList.append(QStringLiteral("Apple Symbols"));
#endif
- didPopulateStyleFallbacks = true;
+ // Since iOS 13, the cascade list may contain meta-fonts which have not been
+ // populated to the database, such as ".AppleJapaneseFont". It is important that we
+ // include this in the fallback list, in order to get fallback support for all
+ // languages
+ for (const QString &fallback : fallbackList) {
+ if (!QPlatformFontDatabase::isFamilyPopulated(fallback))
+ const_cast<QCoreTextFontDatabase *>(this)->populateFamily(fallback);
}
- Q_ASSERT(!fallbackLists.isEmpty());
- return fallbackLists[styleLookupKey.arg(styleHint)];
+ extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
+ fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
+
+ return fallbackList;
}
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index 05f6ed641c..69ff454d1e 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -71,7 +71,7 @@ public:
QCoreTextFontDatabase();
~QCoreTextFontDatabase();
void populateFontDatabase() override;
- bool populateFamilyAliases() override;
+ bool populateFamilyAliases(const QString &missingFamily) override;
void populateFamily(const QString &familyName) override;
void invalidate() override;
@@ -92,6 +92,7 @@ protected:
private:
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
+ static QStringList fallbacksForFamily(const QString &family);
mutable QString defaultFontName;
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index 737d85d5c3..c51db59e1f 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2016 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
** Contact: https://www.qt.io/licensing/
**
@@ -69,6 +69,7 @@ extern "C" {
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcEvdevTouch, "qt.qpa.input")
+Q_LOGGING_CATEGORY(qLcEvents, "qt.qpa.input.events")
/* android (and perhaps some other linux-derived stuff) don't define everything
* in linux/input.h, so we'll need to do that ourselves.
@@ -77,7 +78,7 @@ Q_LOGGING_CATEGORY(qLcEvdevTouch, "qt.qpa.input")
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
#endif
#ifndef ABS_MT_POSITION_X
-#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
+#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
#endif
#ifndef ABS_MT_POSITION_Y
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
@@ -91,6 +92,9 @@ Q_LOGGING_CATEGORY(qLcEvdevTouch, "qt.qpa.input")
#ifndef ABS_MT_TRACKING_ID
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
#endif
+#ifndef ABS_MT_PRESSURE
+#define ABS_MT_PRESSURE 0x3a
+#endif
#ifndef SYN_MT_REPORT
#define SYN_MT_REPORT 2
#endif
@@ -535,7 +539,10 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_currentData.state = Qt::TouchPointReleased;
if (m_typeB)
m_contacts[m_currentSlot].maj = m_currentData.maj;
- } else if (data->code == ABS_PRESSURE) {
+ } else if (data->code == ABS_PRESSURE || data->code == ABS_MT_PRESSURE) {
+ if (Q_UNLIKELY(qLcEvents().isDebugEnabled()))
+ qCDebug(qLcEvents, "EV_ABS code 0x%x: pressure %d; bounding to [%d,%d]",
+ data->code, data->value, hw_pressure_min, hw_pressure_max);
m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max);
if (m_typeB || m_singleTouch)
m_contacts[m_currentSlot].pressure = m_currentData.pressure;
@@ -574,6 +581,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_lastTouchPoints = m_touchPoints;
m_touchPoints.clear();
Qt::TouchPointStates combinedStates;
+ bool hasPressure = false;
for (auto i = m_contacts.begin(), end = m_contacts.end(); i != end; /*erasing*/) {
auto it = i++;
@@ -604,6 +612,9 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
continue;
}
+ if (contact.pressure)
+ hasPressure = true;
+
addTouchPoint(contact, &combinedStates);
}
@@ -648,7 +659,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_contacts.clear();
- if (!m_touchPoints.isEmpty() && combinedStates != Qt::TouchPointStationary)
+ if (!m_touchPoints.isEmpty() && (hasPressure || combinedStates != Qt::TouchPointStationary))
reportPoints();
}
@@ -774,6 +785,9 @@ void QEvdevTouchScreenData::reportPoints()
tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
else
tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min);
+
+ if (Q_UNLIKELY(qLcEvents().isDebugEnabled()))
+ qCDebug(qLcEvents) << "reporting" << tp;
}
// Let qguiapp pick the target window.
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
index b280f27fac..bf2df93d11 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
@@ -98,8 +98,8 @@ void QEvdevTouchManager::addDevice(const QString &deviceNode)
qCDebug(qLcEvdevTouch, "evdevtouch: Adding device at %ls", qUtf16Printable(deviceNode));
auto handler = qt_make_unique<QEvdevTouchScreenHandlerThread>(deviceNode, m_spec);
if (handler) {
- m_activeDevices.add(deviceNode, std::move(handler));
connect(handler.get(), &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount);
+ m_activeDevices.add(deviceNode, std::move(handler));
} else {
qWarning("evdevtouch: Failed to open touch device %ls", qUtf16Printable(deviceNode));
}
diff --git a/src/platformsupport/input/tslib/qtslib.cpp b/src/platformsupport/input/tslib/qtslib.cpp
index df57147af6..e105f5ea98 100644
--- a/src/platformsupport/input/tslib/qtslib.cpp
+++ b/src/platformsupport/input/tslib/qtslib.cpp
@@ -68,7 +68,9 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key,
return;
}
+#ifdef TSLIB_VERSION_EVENTPATH /* also introduced in 1.15 */
qCDebug(qLcTsLib) << "tslib device is" << ts_get_eventpath(m_dev);
+#endif
m_notify = new QSocketNotifier(ts_fd(m_dev), QSocketNotifier::Read, this);
connect(m_notify, &QSocketNotifier::activated, this, &QTsLibMouseHandler::readMouseData);
}
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index d9d76c1146..06d1251a65 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -355,10 +355,14 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
}
qCDebug(qLcKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName;
- const QByteArray formatStr = userConnectorConfig.value(QStringLiteral("format"), QStringLiteral("xrgb8888"))
+ const QByteArray formatStr = userConnectorConfig.value(QStringLiteral("format"), QString())
.toByteArray().toLower();
uint32_t drmFormat;
- if (formatStr == "xrgb8888") {
+ bool drmFormatExplicit = true;
+ if (formatStr.isEmpty()) {
+ drmFormat = DRM_FORMAT_XRGB8888;
+ drmFormatExplicit = false;
+ } else if (formatStr == "xrgb8888") {
drmFormat = DRM_FORMAT_XRGB8888;
} else if (formatStr == "xbgr8888") {
drmFormat = DRM_FORMAT_XBGR8888;
@@ -381,7 +385,10 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
} else {
qWarning("Invalid pixel format \"%s\" for output %s", formatStr.constData(), connectorName.constData());
drmFormat = DRM_FORMAT_XRGB8888;
+ drmFormatExplicit = false;
}
+ qCDebug(qLcKmsDebug) << "Format is" << Qt::hex << drmFormat << Qt::dec << "requested_by_user =" << drmFormatExplicit
+ << "for output" << connectorName;
const QString cloneSource = userConnectorConfig.value(QStringLiteral("clones")).toString();
if (!cloneSource.isEmpty())
@@ -427,6 +434,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
output.forced_plane_id = 0;
output.forced_plane_set = false;
output.drm_format = drmFormat;
+ output.drm_format_requested_by_user = drmFormatExplicit;
output.clone_source = cloneSource;
output.size = framebufferSize;
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
index 77070c293d..b1150e2875 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h
+++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
@@ -202,6 +202,7 @@ struct QKmsOutput
uint32_t forced_plane_id = 0;
bool forced_plane_set = false;
uint32_t drm_format = DRM_FORMAT_XRGB8888;
+ bool drm_format_requested_by_user = false;
QString clone_source;
QVector<QKmsPlane> available_planes;
struct QKmsPlane *eglfs_plane = nullptr;
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 1f1675e490..dd01138722 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -248,13 +248,12 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
static bool read_jpeg_image(QImage *outImage,
QSize scaledSize, QRect scaledClipRect,
- QRect clipRect, volatile int inQuality,
+ QRect clipRect, int quality,
Rgb888ToRgb32Converter converter,
j_decompress_ptr info, struct my_error_mgr* err )
{
if (!setjmp(err->setjmp_buffer)) {
// -1 means default quality.
- int quality = inQuality;
if (quality < 0)
quality = 75;
@@ -529,7 +528,14 @@ static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo)
}
}
-static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
+static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
+ JSAMPROW *row_pointer,
+ const QImage &image,
+ QIODevice *device,
+ int sourceQuality,
+ const QString &description,
+ bool optimize,
+ bool progressive)
{
bool success = false;
const QVector<QRgb> cmap = image.colorTable();
@@ -537,10 +543,6 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
if (image.format() == QImage::Format_Invalid || image.format() == QImage::Format_Alpha8)
return false;
- struct jpeg_compress_struct cinfo;
- JSAMPROW row_pointer[1];
- row_pointer[0] = 0;
-
struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);
struct my_error_mgr jerr;
@@ -713,6 +715,27 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
}
delete iod_dest;
+ return success;
+}
+
+static bool write_jpeg_image(const QImage &image,
+ QIODevice *device,
+ int sourceQuality,
+ const QString &description,
+ bool optimize,
+ bool progressive)
+{
+ // protect these objects from the setjmp/longjmp pair inside
+ // do_write_jpeg_image (by making them non-local).
+ struct jpeg_compress_struct cinfo;
+ JSAMPROW row_pointer[1];
+ row_pointer[0] = 0;
+
+ const bool success = do_write_jpeg_image(cinfo, row_pointer,
+ image, device,
+ sourceQuality, description,
+ optimize, progressive);
+
delete [] row_pointer[0];
return success;
}
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index 78632a9bea..730247cd7f 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -1,9 +1,5 @@
TARGET = qtforandroid
-# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
-# Yes, the plugin imports itself statically
-DEFINES += QT_STATICPLUGIN
-
LIBS += -ljnigraphics -landroid
QT += \
@@ -19,7 +15,8 @@ INCLUDEPATH += \
$$PWD \
$$QT_SOURCE_TREE/src/3rdparty/android
-SOURCES += $$PWD/androidplatformplugin.cpp \
+SOURCES += $$PWD/main.cpp \
+ $$PWD/androidplatformplugin.cpp \
$$PWD/androidcontentfileengine.cpp \
$$PWD/androiddeadlockprotector.cpp \
$$PWD/androidjnimain.cpp \
@@ -92,8 +89,5 @@ qtConfig(vulkan) {
}
PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QAndroidIntegrationPlugin
load(qt_plugin)
-
-#Non-standard install directory, QTBUG-29859
-DESTDIR = $$DESTDIR/android
-target.path = $${target.path}/android
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 915f7f0f5b..fd2644717e 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -60,6 +60,7 @@
#include "qandroideventdispatcher.h"
#include <android/api-level.h>
+#include <QtCore/qresource.h>
#include <QtCore/qthread.h>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
@@ -68,8 +69,6 @@
#include <qpa/qwindowsysteminterface.h>
-Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
-
QT_BEGIN_NAMESPACE
static JavaVM *m_javaVM = nullptr;
@@ -77,6 +76,7 @@ static jclass m_applicationClass = nullptr;
static jobject m_classLoaderObject = nullptr;
static jmethodID m_loadClassMethodID = nullptr;
static AAssetManager *m_assetManager = nullptr;
+static jobject m_assets = nullptr;
static jobject m_resourcesObj = nullptr;
static jobject m_activityObject = nullptr;
static jmethodID m_createSurfaceMethodID = nullptr;
@@ -441,6 +441,11 @@ namespace QtAndroid
return block;
}
+ jobject assets()
+ {
+ return m_assets;
+ }
+
} // namespace QtAndroid
static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString)
@@ -521,6 +526,10 @@ static jboolean startQtApplication(JNIEnv */*env*/, jclass /*clazz*/)
vm->AttachCurrentThread(&env, &args);
}
+ // Register resources if they are available
+ if (QFile{QStringLiteral("assets:/android_rcc_bundle.rcc")}.exists())
+ QResource::registerResource(QStringLiteral("assets:/android_rcc_bundle.rcc"));
+
QVarLengthArray<const char *> params(m_applicationParams.size());
for (int i = 0; i < m_applicationParams.size(); i++)
params[i] = static_cast<const char *>(m_applicationParams[i].constData());
@@ -590,6 +599,8 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
if (m_bitmapDrawableClass)
env->DeleteGlobalRef(m_bitmapDrawableClass);
+ if (m_assets)
+ env->DeleteGlobalRef(m_assets);
m_androidPlatformIntegration = nullptr;
delete m_androidAssetsFileEngineHandler;
m_androidAssetsFileEngineHandler = nullptr;
@@ -842,7 +853,8 @@ static int registerNatives(JNIEnv *env)
if (object) {
FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
- m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(object, methodID));
+ m_assets = env->NewGlobalRef(env->CallObjectMethod(object, methodID));
+ m_assetManager = AAssetManager_fromJava(env, m_assets);
GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(object, methodID));
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 08f1d50fe3..17ae30a1be 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -82,6 +82,7 @@ namespace QtAndroid
double scaledDensity();
double pixelDensity();
JavaVM *javaVM();
+ jobject assets();
AAssetManager *assetManager();
jclass applicationClass();
jobject activity();
diff --git a/src/plugins/platforms/android/main.cpp b/src/plugins/platforms/android/main.cpp
new file mode 100644
index 0000000000..c304fc8d69
--- /dev/null
+++ b/src/plugins/platforms/android/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qpa/qplatformintegrationplugin.h>
+#include "qandroidplatformintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "android.json")
+
+public:
+ QPlatformIntegration *create(const QString& system, const QStringList& paramList) override;
+};
+
+QPlatformIntegration *QAndroidIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ if (!system.compare(QLatin1String("android"), Qt::CaseInsensitive))
+ return new QAndroidPlatformIntegration(paramList);
+
+ return nullptr;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
index e1dcebfa4c..26e72a480f 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
@@ -39,40 +39,139 @@
#include "qandroidassetsfileenginehandler.h"
#include "androidjnimain.h"
+#include <optional>
#include <QCoreApplication>
#include <QVector>
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
-typedef QVector<QString> FilesList;
+static const QLatin1String assetsPrefix("assets:");
+const static int prefixSize = 7;
-struct AndroidAssetDir
+static inline QString cleanedAssetPath(QString file)
{
- AndroidAssetDir(AAssetDir* ad)
+ if (file.startsWith(assetsPrefix))
+ file.remove(0, prefixSize);
+ file.replace(QLatin1String("//"), QLatin1String("/"));
+ if (file.startsWith(QLatin1Char('/')))
+ file.remove(0, 1);
+ if (file.endsWith(QLatin1Char('/')))
+ file.chop(1);
+ return file;
+}
+
+static inline QString prefixedPath(QString path)
+{
+ path = assetsPrefix + QLatin1Char('/') + path;
+ path.replace(QLatin1String("//"), QLatin1String("/"));
+ return path;
+}
+
+struct AssetItem {
+ enum class Type {
+ File,
+ Folder
+ };
+
+ AssetItem (const QString &rawName)
+ : name(rawName)
+ {
+ if (name.endsWith(QLatin1Char('/'))) {
+ type = Type::Folder;
+ name.chop(1);
+ }
+ }
+ Type type = Type::File;
+ QString name;
+};
+
+using AssetItemList = QVector<AssetItem>;
+
+class FolderIterator : public AssetItemList
+{
+public:
+ static QSharedPointer<FolderIterator> fromCache(const QString &path)
{
- if (ad) {
- const char *fileName;
- while ((fileName = AAssetDir_getNextFileName(ad)))
- m_items.push_back(QString::fromUtf8(fileName));
- AAssetDir_close(ad);
+ QMutexLocker lock(&m_assetsCacheMutex);
+ QSharedPointer<FolderIterator> *folder = m_assetsCache.object(path);
+ if (!folder) {
+ folder = new QSharedPointer<FolderIterator>{new FolderIterator{path}};
+ if (!m_assetsCache.insert(path, folder)) {
+ QSharedPointer<FolderIterator> res = *folder;
+ delete folder;
+ return res;
+ }
}
+ return *folder;
+ }
+
+ FolderIterator(const QString &path)
+ : m_path(path)
+ {
+ QJNIObjectPrivate files = QJNIObjectPrivate::callStaticObjectMethod(QtAndroid::applicationClass(),
+ "listAssetContent",
+ "(Landroid/content/res/AssetManager;Ljava/lang/String;)[Ljava/lang/String;",
+ QtAndroid::assets(), QJNIObjectPrivate::fromString(path).object());
+ if (files.isValid()) {
+ QJNIEnvironmentPrivate env;
+ jobjectArray jFiles = static_cast<jobjectArray>(files.object());
+ const jint nFiles = env->GetArrayLength(jFiles);
+ for (int i = 0; i < nFiles; ++i)
+ push_back({QJNIObjectPrivate(env->GetObjectArrayElement(jFiles, i)).toString()});
+ }
+ m_path = assetsPrefix + QLatin1Char('/') + m_path + QLatin1Char('/');
+ m_path.replace(QLatin1String("//"), QLatin1String("/"));
+ }
+
+ QString currentFileName() const
+ {
+ if (m_index < 0 || m_index >= size())
+ return {};
+ return at(m_index).name;
+ }
+ QString currentFilePath() const
+ {
+ if (m_index < 0 || m_index >= size())
+ return {};
+ return m_path + at(m_index).name;
+ }
+
+ bool hasNext() const
+ {
+ return !empty() && m_index + 1 < size();
+ }
+
+ std::optional<std::pair<QString, AssetItem>> next()
+ {
+ if (!hasNext())
+ return {};
+ ++m_index;
+ return std::pair<QString, AssetItem>(currentFileName(), at(m_index));
}
- FilesList m_items;
+
+private:
+ int m_index = -1;
+ QString m_path;
+ static QCache<QString, QSharedPointer<FolderIterator>> m_assetsCache;
+ static QMutex m_assetsCacheMutex;
};
+QCache<QString, QSharedPointer<FolderIterator>> FolderIterator::m_assetsCache(std::max(50, qEnvironmentVariableIntValue("QT_ANDROID_MAX_ASSETS_CACHE_SIZE")));
+QMutex FolderIterator::m_assetsCacheMutex;
+
class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator
{
public:
AndroidAbstractFileEngineIterator(QDir::Filters filters,
const QStringList &nameFilters,
- QSharedPointer<AndroidAssetDir> asset,
const QString &path)
: QAbstractFileEngineIterator(filters, nameFilters)
{
- m_items = asset->m_items;
- m_index = -1;
- m_path = path;
+ m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path)));
+ if (m_stack.last()->empty())
+ m_stack.pop_back();
}
QFileInfo currentFileInfo() const override
@@ -82,54 +181,59 @@ public:
QString currentFileName() const override
{
- if (m_index < 0 || m_index >= m_items.size())
- return QString();
- QString fileName = m_items[m_index];
- if (fileName.endsWith(QLatin1Char('/')))
- fileName.chop(1);
- return fileName;
+ if (!m_currentIterator)
+ return {};
+ return m_currentIterator->currentFileName();
}
virtual QString currentFilePath() const
{
- return m_path + currentFileName();
+ if (!m_currentIterator)
+ return {};
+ return m_currentIterator->currentFilePath();
}
bool hasNext() const override
{
- return m_items.size() && (m_index < m_items.size() - 1);
+ if (m_stack.empty())
+ return false;
+ if (!m_stack.last()->hasNext()) {
+ m_stack.pop_back();
+ return hasNext();
+ }
+ return true;
}
QString next() override
{
- if (!hasNext())
- return QString();
- m_index++;
- return currentFileName();
+ if (m_stack.empty()) {
+ m_currentIterator.reset();
+ return {};
+ }
+ m_currentIterator = m_stack.last();
+ auto res = m_currentIterator->next();
+ if (!res)
+ return {};
+ if (res->second.type == AssetItem::Type::Folder) {
+ m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath())));
+ if (m_stack.last()->empty())
+ m_stack.pop_back();
+ }
+ return res->first;
}
private:
- QString m_path;
- FilesList m_items;
- int m_index;
+ mutable QSharedPointer<FolderIterator> m_currentIterator;
+ mutable QVector<QSharedPointer<FolderIterator>> m_stack;
};
class AndroidAbstractFileEngine: public QAbstractFileEngine
{
public:
- explicit AndroidAbstractFileEngine(AAsset *asset, const QString &fileName)
- {
- m_assetFile = asset;
- m_fileName = fileName;
- }
-
- explicit AndroidAbstractFileEngine(QSharedPointer<AndroidAssetDir> asset, const QString &fileName)
+ explicit AndroidAbstractFileEngine(AAssetManager *assetManager, const QString &fileName)
+ : m_assetManager(assetManager)
{
- m_assetFile = 0;
- m_assetDir = asset;
- m_fileName = fileName;
- if (!m_fileName.endsWith(QLatin1Char('/')))
- m_fileName += QLatin1Char('/');
+ setFileName(fileName);
}
~AndroidAbstractFileEngine()
@@ -139,7 +243,11 @@ public:
bool open(QIODevice::OpenMode openMode) override
{
- return m_assetFile != 0 && (openMode & QIODevice::WriteOnly) == 0;
+ if (m_isFolder || (openMode & QIODevice::WriteOnly))
+ return false;
+ close();
+ m_assetFile = AAssetManager_open(m_assetManager, m_fileName.toUtf8(), AASSET_MODE_BUFFER);
+ return m_assetFile;
}
bool close() override
@@ -200,7 +308,7 @@ public:
FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
if (m_assetFile)
flags |= FileType;
- if (!m_assetDir.isNull())
+ else if (m_isFolder)
flags |= DirectoryType;
return type & flags;
@@ -213,19 +321,19 @@ public:
case DefaultName:
case AbsoluteName:
case CanonicalName:
- return m_fileName;
+ return prefixedPath(m_fileName);
case BaseName:
if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1)
- return m_fileName.mid(pos);
+ return prefixedPath(m_fileName.mid(pos));
else
- return m_fileName;
+ return prefixedPath(m_fileName);
case PathName:
case AbsolutePathName:
case CanonicalPathName:
if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1)
- return m_fileName.left(pos);
+ return prefixedPath(m_fileName.left(pos));
else
- return m_fileName;
+ return prefixedPath(m_fileName);
default:
return QString();
}
@@ -233,164 +341,46 @@ public:
void setFileName(const QString &file) override
{
- if (file == m_fileName)
- return;
-
- m_fileName = file;
- if (!m_fileName.endsWith(QLatin1Char('/')))
- m_fileName += QLatin1Char('/');
-
close();
+ m_fileName = cleanedAssetPath(file);
+ m_isFolder = !open(QIODevice::ReadOnly) && !FolderIterator::fromCache(m_fileName)->empty();
}
Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override
{
- if (!m_assetDir.isNull())
- return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName);
- return 0;
+ if (m_isFolder)
+ return new AndroidAbstractFileEngineIterator(filters, filterNames, m_fileName);
+ return nullptr;
}
private:
- AAsset *m_assetFile;
- QSharedPointer<AndroidAssetDir> m_assetDir;
+ AAsset *m_assetFile = nullptr;
+ AAssetManager *m_assetManager;
QString m_fileName;
+ bool m_isFolder;
};
AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler()
- : m_assetsCache(std::max(5, qEnvironmentVariableIntValue("QT_ANDROID_MAX_ASSETS_CACHE_SIZE")))
- , m_hasPrepopulatedCache(false)
- , m_hasTriedPrepopulatingCache(false)
{
m_assetManager = QtAndroid::assetManager();
}
-AndroidAssetsFileEngineHandler::~AndroidAssetsFileEngineHandler()
-{
-}
-
-void AndroidAssetsFileEngineHandler::prepopulateCache() const
-{
- Q_ASSERT(!m_hasTriedPrepopulatingCache);
- m_hasTriedPrepopulatingCache = true;
-
- Q_ASSERT(m_assetsCache.isEmpty());
-
- // Failsafe: Don't read cache files that are larger than 1MB
- static qint64 maxPrepopulatedCacheSize = qMax(1024LL * 1024LL,
- qgetenv("QT_ANDROID_MAX_PREPOPULATED_ASSETS_CACHE_SIZE").toLongLong());
-
- const char *fileName = "--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list";
- AAsset *asset = AAssetManager_open(m_assetManager, fileName, AASSET_MODE_BUFFER);
- if (asset) {
- m_hasPrepopulatedCache = true;
- AndroidAbstractFileEngine fileEngine(asset, QString::fromLatin1(fileName));
- if (fileEngine.open(QIODevice::ReadOnly)) {
- qint64 size = fileEngine.size();
-
- if (size <= maxPrepopulatedCacheSize) {
- QByteArray bytes(size, Qt::Uninitialized);
- qint64 read = fileEngine.read(bytes.data(), size);
- if (read != size) {
- qWarning("Failed to read prepopulated cache");
- return;
- }
-
- QDataStream stream(&bytes, QIODevice::ReadOnly);
- stream.setVersion(QDataStream::Qt_5_3);
- if (stream.status() != QDataStream::Ok) {
- qWarning("Failed to read prepopulated cache");
- return;
- }
-
- while (!stream.atEnd()) {
- QString directoryName;
- stream >> directoryName;
-
- int fileCount;
- stream >> fileCount;
-
- QVector<QString> fileList;
- fileList.reserve(fileCount);
- while (fileCount--) {
- QString fileName;
- stream >> fileName;
- fileList.append(fileName);
- }
-
- QSharedPointer<AndroidAssetDir> *aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(0));
- (*aad)->m_items = fileList;
-
- // Cost = 0, because we should always cache everything if there's a prepopulated cache
- QByteArray key = directoryName != QLatin1String("/")
- ? QByteArray("assets:/") + directoryName.toUtf8()
- : QByteArray("assets:");
-
- bool ok = m_assetsCache.insert(key, aad, 0);
- if (!ok)
- qWarning("Failed to insert in cache: %s", qPrintable(directoryName));
- }
- } else {
- qWarning("Prepopulated cache is too large to read.\n"
- "Use environment variable QT_ANDROID_MAX_PREPOPULATED_ASSETS_CACHE_SIZE to adjust size.");
- }
- }
- }
-}
-
QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &fileName) const
{
if (fileName.isEmpty())
- return 0;
+ return nullptr;
- static QLatin1String assetsPrefix("assets:");
if (!fileName.startsWith(assetsPrefix))
- return 0;
-
- static int prefixSize = assetsPrefix.size() + 1;
-
- QByteArray path;
- if (!fileName.endsWith(QLatin1Char('/'))) {
- path = fileName.toUtf8();
- if (path.size() > prefixSize) {
- AAsset *asset = AAssetManager_open(m_assetManager,
- path.constData() + prefixSize,
- AASSET_MODE_BUFFER);
- if (asset)
- return new AndroidAbstractFileEngine(asset, fileName);
- }
- }
-
- if (!path.size())
- path = fileName.left(fileName.length() - 1).toUtf8();
-
-
- m_assetsCacheMutext.lock();
- if (!m_hasTriedPrepopulatingCache)
- prepopulateCache();
-
- QSharedPointer<AndroidAssetDir> *aad = m_assetsCache.object(path);
- m_assetsCacheMutext.unlock();
- if (!aad) {
- if (!m_hasPrepopulatedCache && path.size() > prefixSize) {
- AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, path.constData() + prefixSize);
- if (assetDir) {
- if (AAssetDir_getNextFileName(assetDir)) {
- AAssetDir_rewind(assetDir);
- aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(assetDir));
- m_assetsCacheMutext.lock();
- m_assetsCache.insert(path, aad);
- m_assetsCacheMutext.unlock();
- return new AndroidAbstractFileEngine(*aad, fileName);
- } else {
- AAssetDir_close(assetDir);
- }
- }
- }
- } else {
- return new AndroidAbstractFileEngine(*aad, fileName);
- }
- return 0;
+ return nullptr;
+
+ QString path = fileName.mid(prefixSize);
+ path.replace(QLatin1String("//"), QLatin1String("/"));
+ if (path.startsWith(QLatin1Char('/')))
+ path.remove(0, 1);
+ if (path.endsWith(QLatin1Char('/')))
+ path.chop(1);
+ return new AndroidAbstractFileEngine(m_assetManager, path);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
index f99dc9a11a..51cc5b07a8 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
@@ -49,22 +49,14 @@
QT_BEGIN_NAMESPACE
-struct AndroidAssetDir;
class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler
{
public:
AndroidAssetsFileEngineHandler();
- virtual ~AndroidAssetsFileEngineHandler();
QAbstractFileEngine *create(const QString &fileName) const override;
private:
- void prepopulateCache() const;
-
AAssetManager *m_assetManager;
- mutable QCache<QByteArray, QSharedPointer<AndroidAssetDir>> m_assetsCache;
- mutable QMutex m_assetsCacheMutext;
- mutable bool m_hasPrepopulatedCache;
- mutable bool m_hasTriedPrepopulatingCache;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 7fc68c3d7c..d3a8a53241 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -465,7 +465,8 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
return QStringList(QLatin1String("android"));
}
return QStringList(QLatin1String("fusion"));
-
+ case DialogButtonBoxLayout:
+ return QVariant(QPlatformDialogHelper::AndroidLayout);
case MouseDoubleClickDistance:
{
int minimumDistance = qEnvironmentVariableIntValue("QT_ANDROID_MINIMUM_MOUSE_DOUBLE_CLICK_DISTANCE");
@@ -489,8 +490,6 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
Q_FALLTHROUGH();
}
- case DialogButtonBoxLayout:
- return QVariant(QPlatformDialogHelper::AndroidLayout);
default:
return QPlatformTheme::themeHint(hint);
}
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 02e00039ae..4cf9e64447 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -21,8 +21,6 @@ SOURCES += main.mm \
qcocoamenuloader.mm \
qcocoahelpers.mm \
qmultitouch_mac.mm \
- qcocoaaccessibilityelement.mm \
- qcocoaaccessibility.mm \
qcocoacursor.mm \
qcocoaclipboard.mm \
qcocoadrag.mm \
@@ -57,8 +55,6 @@ HEADERS += qcocoaintegration.h \
qcocoamenuloader.h \
qcocoahelpers.h \
qmultitouch_mac_p.h \
- qcocoaaccessibilityelement.h \
- qcocoaaccessibility.h \
qcocoacursor.h \
qcocoaclipboard.h \
qcocoadrag.h \
@@ -83,13 +79,21 @@ qtConfig(vulkan) {
HEADERS += qcocoavulkaninstance.h
}
+qtConfig(accessibility) {
+ QT += accessibility_support-private
+ SOURCES += qcocoaaccessibilityelement.mm \
+ qcocoaaccessibility.mm
+ HEADERS += qcocoaaccessibilityelement.h \
+ qcocoaaccessibility.h
+}
+
RESOURCES += qcocoaresources.qrc
LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -framework IOSurface -lcups
QT += \
core-private gui-private \
- accessibility_support-private clipboard_support-private theme_support-private \
+ clipboard_support-private theme_support-private \
fontdatabase_support-private graphics_support-private
qtConfig(vulkan): QT += vulkan_support-private
@@ -99,17 +103,20 @@ CONFIG += no_app_extension_api_only
qtHaveModule(widgets) {
QT_FOR_CONFIG += widgets
- SOURCES += \
- qpaintengine_mac.mm \
- qprintengine_mac.mm \
- qcocoaprintersupport.mm \
- qcocoaprintdevice.mm \
-
- HEADERS += \
- qpaintengine_mac_p.h \
- qprintengine_mac_p.h \
- qcocoaprintersupport.h \
- qcocoaprintdevice.h \
+ SOURCES += qpaintengine_mac.mm
+ HEADERS += qpaintengine_mac_p.h
+
+ qtHaveModule(printsupport) {
+ QT += printsupport-private
+ SOURCES += \
+ qprintengine_mac.mm \
+ qcocoaprintersupport.mm \
+ qcocoaprintdevice.mm
+ HEADERS += \
+ qcocoaprintersupport.h \
+ qcocoaprintdevice.h \
+ qprintengine_mac_p.h
+ }
qtConfig(colordialog) {
SOURCES += qcocoacolordialoghelper.mm
@@ -126,7 +133,7 @@ qtHaveModule(widgets) {
HEADERS += qcocoafontdialoghelper.h
}
- QT += widgets-private printsupport-private
+ QT += widgets-private
}
OTHER_FILES += cocoa.json
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 2cf6672da9..2df85c791b 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -171,12 +171,8 @@ QT_USE_NAMESPACE
// This function will only be called when NSApp is actually running.
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
- // The reflection delegate gets precedence
- if (reflectionDelegate) {
- if ([reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)])
- return [reflectionDelegate applicationShouldTerminate:sender];
- return NSTerminateNow;
- }
+ if ([reflectionDelegate respondsToSelector:_cmd])
+ return [reflectionDelegate applicationShouldTerminate:sender];
if ([self canQuit]) {
if (!startedQuit) {
@@ -228,10 +224,6 @@ QT_USE_NAMESPACE
*/
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager setEventHandler:self
- andSelector:@selector(appleEventQuit:withReplyEvent:)
- forEventClass:kCoreEventClass
- andEventID:kAEQuitApplication];
- [eventManager setEventHandler:self
andSelector:@selector(getUrl:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
@@ -241,7 +233,6 @@ QT_USE_NAMESPACE
- (void)removeAppleEventHandlers
{
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
- [eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication];
[eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
}
@@ -282,26 +273,22 @@ QT_USE_NAMESPACE
QWindowSystemInterface::handleFileOpenEvent(qtFileName);
}
- if (reflectionDelegate &&
- [reflectionDelegate respondsToSelector:@selector(application:openFiles:)])
+ if ([reflectionDelegate respondsToSelector:_cmd])
[reflectionDelegate application:sender openFiles:filenames];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
- // If we have a reflection delegate, that will get to call the shots.
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:
- @selector(applicationShouldTerminateAfterLastWindowClosed:)])
+ if ([reflectionDelegate respondsToSelector:_cmd])
return [reflectionDelegate applicationShouldTerminateAfterLastWindowClosed:sender];
+
return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together.
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:@selector(applicationDidBecomeActive:)])
+ if ([reflectionDelegate respondsToSelector:_cmd])
[reflectionDelegate applicationDidBecomeActive:notification];
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
@@ -309,8 +296,7 @@ QT_USE_NAMESPACE
- (void)applicationDidResignActive:(NSNotification *)notification
{
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:@selector(applicationDidResignActive:)])
+ if ([reflectionDelegate respondsToSelector:_cmd])
[reflectionDelegate applicationDidResignActive:notification];
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
@@ -318,10 +304,7 @@ QT_USE_NAMESPACE
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
- Q_UNUSED(theApplication);
- Q_UNUSED(flag);
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:@selector(applicationShouldHandleReopen:hasVisibleWindows:)])
+ if ([reflectionDelegate respondsToSelector:_cmd])
return [reflectionDelegate applicationShouldHandleReopen:theApplication hasVisibleWindows:flag];
/*
@@ -354,16 +337,13 @@ QT_USE_NAMESPACE
- (BOOL)respondsToSelector:(SEL)aSelector
{
- BOOL result = [super respondsToSelector:aSelector];
- if (!result && reflectionDelegate)
- result = [reflectionDelegate respondsToSelector:aSelector];
- return result;
+ return [super respondsToSelector:aSelector] || [reflectionDelegate respondsToSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL invocationSelector = [invocation selector];
- if (reflectionDelegate && [reflectionDelegate respondsToSelector:invocationSelector])
+ if ([reflectionDelegate respondsToSelector:invocationSelector])
[invocation invokeWithTarget:reflectionDelegate];
else
[self doesNotRecognizeSelector:invocationSelector];
@@ -375,14 +355,6 @@ QT_USE_NAMESPACE
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
QWindowSystemInterface::handleFileOpenEvent(QUrl(QString::fromNSString(urlString)));
}
-
-- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
-{
- Q_UNUSED(event);
- Q_UNUSED(replyEvent);
- [NSApp terminate:self];
-}
-
@end
@implementation QCocoaApplicationDelegate (Menus)
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 9be6814ae7..a874936ce6 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -54,6 +54,8 @@ class QCocoaBackingStore : public QRasterBackingStore
protected:
QCocoaBackingStore(QWindow *window);
QCFType<CGColorSpaceRef> colorSpace() const;
+ QMacNotificationObserver m_backingPropertiesObserver;
+ virtual void backingPropertiesChanged() = 0;
};
class QNSWindowBackingStore : public QCocoaBackingStore
@@ -69,6 +71,7 @@ private:
bool windowHasUnifiedToolbar() const;
QImage::Format format() const override;
void redrawRoundedBottomCorners(CGRect) const;
+ void backingPropertiesChanged() override;
};
class QCALayerBackingStore : public QCocoaBackingStore
@@ -115,6 +118,8 @@ private:
bool recreateBackBufferIfNeeded();
bool prepareForFlush();
+ void backingPropertiesChanged() override;
+
std::list<std::unique_ptr<GraphicsBuffer>> m_buffers;
};
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 15e0236107..b17302a640 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -51,6 +51,17 @@ QT_BEGIN_NAMESPACE
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QRasterBackingStore(window)
{
+ // Ideally this would be plumbed from the platform layer to QtGui, and
+ // the QBackingStore would be recreated, but we don't have that code yet,
+ // so at least make sure we invalidate our backingstore when the backing
+ // properties (color space e.g.) are changed.
+ NSView *view = static_cast<QCocoaWindow *>(window->handle())->view();
+ m_backingPropertiesObserver = QMacNotificationObserver(view.window,
+ NSWindowDidChangeBackingPropertiesNotification, [this]() {
+ qCDebug(lcQpaBackingStore) << "Backing properties for"
+ << this->window() << "did change";
+ backingPropertiesChanged();
+ });
}
QCFType<CGColorSpaceRef> QCocoaBackingStore::colorSpace() const
@@ -64,6 +75,37 @@ QCFType<CGColorSpaceRef> QCocoaBackingStore::colorSpace() const
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
: QCocoaBackingStore(window)
{
+ // Choose an appropriate window depth based on the requested surface format.
+ // On deep color displays the default bit depth is 16-bit, so unless we need
+ // that level of precision we opt out of it (and the expensive RGB32 -> RGB64
+ // conversions that come with it if our backingstore depth does not match).
+
+ NSWindow *nsWindow = static_cast<QCocoaWindow *>(window->handle())->view().window;
+ auto colorSpaceName = NSColorSpaceFromDepth(nsWindow.depthLimit);
+
+ static const int kDefaultBitDepth = 8;
+ auto surfaceFormat = window->requestedFormat();
+ auto bitsPerSample = qMax(kDefaultBitDepth, qMax(surfaceFormat.redBufferSize(),
+ qMax(surfaceFormat.greenBufferSize(), surfaceFormat.blueBufferSize())));
+
+ // NSBestDepth does not seem to guarantee a window depth deep enough for the
+ // given bits per sample, even if documented as such. For example, requesting
+ // 10 bits per sample will not give us a 16-bit format, even if that's what's
+ // available. Work around this by manually bumping the bit depth.
+ bitsPerSample = !(bitsPerSample & (bitsPerSample - 1))
+ ? bitsPerSample : qNextPowerOfTwo(bitsPerSample);
+
+ auto bestDepth = NSBestDepth(colorSpaceName, bitsPerSample, 0, NO, nullptr);
+
+ // Disable dynamic depth limit, otherwise our depth limit will be overwritten
+ // by AppKit if the window moves to a screen with a different depth. We call
+ // this before setting the depth limit, as the call will reset the depth to 0.
+ [nsWindow setDynamicDepthLimit:NO];
+
+ qCDebug(lcQpaBackingStore) << "Using" << NSBitsPerSampleFromDepth(bestDepth)
+ << "bit window depth for" << nsWindow;
+
+ nsWindow.depthLimit = bestDepth;
}
QNSWindowBackingStore::~QNSWindowBackingStore()
@@ -212,9 +254,6 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion &region, const
CGRect viewRect = viewLocalRect.toCGRect();
- if (windowHasUnifiedToolbar())
- NSDrawWindowBackground(viewRect);
-
[backingStoreImage drawInRect:viewRect fromRect:backingStoreRect.toCGRect()
operation:compositingOperation fraction:1.0 respectFlipped:YES hints:nil];
@@ -302,6 +341,11 @@ void QNSWindowBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
#endif
}
+void QNSWindowBackingStore::backingPropertiesChanged()
+{
+ m_image = QImage();
+}
+
// ----------------------------------------------------------------------------
QCALayerBackingStore::QCALayerBackingStore(QWindow *window)
@@ -516,17 +560,26 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
flushedView.layer.contents = nil;
}
- qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
- << "to" << flushedView.layer << "of" << flushedView;
-
- flushedView.layer.contents = backBufferSurface;
+ if (flushedView == backingStoreView) {
+ qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
+ << "to" << flushedView.layer << "of" << flushedView;
+ flushedView.layer.contents = backBufferSurface;
+ } else {
+ auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView];
+ auto scale = flushedView.layer.contentsScale;
+ subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale));
+
+ // We make a copy of the image data up front, which means we don't
+ // need to mark the IOSurface as being in use. FIXME: Investigate
+ // if there's a cheaper way to get sub-image data to a layer.
+ m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess);
+ QImage subImage = m_buffers.back()->asImage()->copy(QRectF::fromCGRect(subviewRect).toRect());
+ m_buffers.back()->unlock();
- if (flushedView != backingStoreView) {
- const CGSize backingStoreSize = backingStoreView.bounds.size;
- flushedView.layer.contentsRect = CGRectApplyAffineTransform(
- [flushedView convertRect:flushedView.bounds toView:backingStoreView],
- // The contentsRect is in unit coordinate system
- CGAffineTransformMakeScale(1.0 / backingStoreSize.width, 1.0 / backingStoreSize.height));
+ qCInfo(lcQpaBackingStore) << "Flushing" << subImage
+ << "to" << flushedView.layer << "of subview" << flushedView;
+ QCFType<CGImageRef> cgImage = subImage.toCGImage();
+ flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
}
// Since we may receive multiple flushes before a new frame is started, we do not
@@ -565,6 +618,12 @@ QImage QCALayerBackingStore::toImage() const
return imageCopy;
}
+void QCALayerBackingStore::backingPropertiesChanged()
+{
+ m_buffers.clear();
+ m_buffers.resize(1);
+}
+
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const
{
return m_buffers.back().get();
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index d3bb0711f0..e87fc39c42 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -881,7 +881,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
return;
}
- int serial = serialNumber.load();
+ int serial = serialNumber.loadRelaxed();
if (!threadData->canWait || (serial != lastSerial)) {
lastSerial = serial;
QCoreApplication::sendPostedEvents();
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 5f32400af0..03677ef0bc 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -214,7 +214,7 @@ static QString strippedText(QString s)
NSString *filepath = info.filePath().toNSString();
NSURL *url = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()];
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
- || [self panel:nil shouldEnableURL:url];
+ || [self panel:mOpenPanel shouldEnableURL:url];
[self updateProperties];
[mSavePanel setNameFieldStringValue:selectable ? info.fileName().toNSString() : @""];
@@ -233,7 +233,7 @@ static QString strippedText(QString s)
NSString *filepath = info.filePath().toNSString();
NSURL *url = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()];
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
- || [self panel:nil shouldEnableURL:url];
+ || [self panel:mSavePanel shouldEnableURL:url];
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
[mSavePanel setNameFieldStringValue:selectable ? info.fileName().toNSString() : @""];
@@ -263,7 +263,7 @@ static QString strippedText(QString s)
NSString *filepath = info.filePath().toNSString();
NSURL *url = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()];
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
- || [self panel:nil shouldEnableURL:url];
+ || [self panel:mSavePanel shouldEnableURL:url];
[self updateProperties];
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 9bd19dd07c..d0e69bdca5 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -59,7 +59,7 @@
#include "qguiapplication.h"
#include <qdebug.h>
-#ifndef QT_NO_WIDGETS
+#if !defined(QT_NO_WIDGETS) && defined(QT_PRINTSUPPORT_LIB)
#include "qcocoaprintersupport.h"
#include "qprintengine_mac_p.h"
#include <qpa/qplatformprintersupport.h>
@@ -153,24 +153,24 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport()
{
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) && defined(QT_PRINTSUPPORT_LIB)
return new QCocoaPrinterSupport();
#else
- qFatal("Printing is not supported when Qt is configured with -no-widgets");
+ qFatal("Printing is not supported when Qt is configured with -no-widgets or -no-feature-printer");
return nullptr;
#endif
}
void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine)
{
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) && defined(QT_PRINTSUPPORT_LIB)
QMacPrintEnginePrivate *macPrintEnginePriv = static_cast<QMacPrintEngine *>(printEngine)->d_func();
if (macPrintEnginePriv->state == QPrinter::Idle && !macPrintEnginePriv->isPrintSessionInitialized())
macPrintEnginePriv->initialize();
return macPrintEnginePriv->printInfo;
#else
Q_UNUSED(printEngine);
- qFatal("Printing is not supported when Qt is configured with -no-widgets");
+ qFatal("Printing is not supported when Qt is configured with -no-widgets or -no-feature-printer");
return nullptr;
#endif
}
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 9b6dc94d33..cb25bd7d81 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -52,6 +52,8 @@
@property (class, strong, readonly) NSColor *unemphasizedSelectedTextColor NS_AVAILABLE_MAC(10_14);
@property (class, strong, readonly) NSColor *unemphasizedSelectedContentBackgroundColor NS_AVAILABLE_MAC(10_14);
@property (class, strong, readonly) NSArray<NSColor *> *alternatingContentBackgroundColors NS_AVAILABLE_MAC(10_14);
+// Missing from non-Mojave SDKs, even if introduced in 10.10
+@property (class, strong, readonly) NSColor *linkColor NS_AVAILABLE_MAC(10_10);
@end
#endif
@@ -111,6 +113,8 @@ QPalette * qt_mac_createSystemPalette()
palette->setBrush(QPalette::ToolTipBase, qt_mac_toQBrush([NSColor controlColor]));
+ palette->setColor(QPalette::Normal, QPalette::Link, qt_mac_toQColor([NSColor linkColor]));
+
return palette;
}
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
index 6779bda491..738c40aba6 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
@@ -65,7 +65,7 @@ public:
void updateMenu(QPlatformMenu *menu) override;
QRect geometry() const override;
void showMessage(const QString &title, const QString &msg,
- const QIcon& icon, MessageIcon iconType, int secs) override;
+ const QIcon& icon, MessageIcon iconType, int msecs) override;
bool isSystemTrayAvailable() const override;
bool supportsMessages() const override;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index db64702b8d..1390ace632 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -264,7 +264,7 @@ bool QCocoaSystemTrayIcon::supportsMessages() const
}
void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message,
- const QIcon& icon, MessageIcon, int)
+ const QIcon& icon, MessageIcon, int msecs)
{
if (!m_sys)
return;
@@ -282,6 +282,10 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
center.delegate = m_sys->item;
[center deliverNotification:notification];
+ if (msecs) {
+ NSTimeInterval timeout = msecs / 1000.0;
+ [center performSelector:@selector(removeDeliveredNotification:) withObject:notification afterDelay:timeout];
+ }
[notification release];
}
QT_END_NAMESPACE
@@ -434,8 +438,7 @@ QT_END_NAMESPACE
}
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
- Q_UNUSED(center);
- Q_UNUSED(notification);
+ [center removeDeliveredNotification:notification];
emit systray->messageClicked();
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 7621508bdd..f212b3e3f0 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1272,14 +1272,11 @@ void QCocoaWindow::windowWillClose()
bool QCocoaWindow::windowShouldClose()
{
qCDebug(lcQpaWindow) << "QCocoaWindow::windowShouldClose" << window();
- // This callback should technically only determine if the window
- // should (be allowed to) close, but since our QPA API to determine
- // that also involves actually closing the window we do both at the
- // same time, instead of doing the latter in windowWillClose.
- bool accepted = false;
- QWindowSystemInterface::handleCloseEvent(window(), &accepted);
- QWindowSystemInterface::flushWindowSystemEvents();
- return accepted;
+ // This callback should technically only determine if the window
+ // should (be allowed to) close, but since our QPA API to determine
+ // that also involves actually closing the window we do both at the
+ // same time, instead of doing the latter in windowWillClose.
+ return QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window());
}
// ----------------------------- QPA forwarding -----------------------------
@@ -1646,21 +1643,6 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
applyContentBorderThickness(nsWindow);
- // Prevent CoreGraphics RGB32 -> RGB64 backing store conversions on deep color
- // displays by forcing 8-bit components, unless a deep color format has been
- // requested. This conversion uses significant CPU time.
- QSurface::SurfaceType surfaceType = QPlatformWindow::window()->surfaceType();
- bool usesCoreGraphics = surfaceType == QSurface::RasterSurface || surfaceType == QSurface::RasterGLSurface;
- QSurfaceFormat surfaceFormat = QPlatformWindow::window()->format();
- bool usesDeepColor = surfaceFormat.redBufferSize() > 8 ||
- surfaceFormat.greenBufferSize() > 8 ||
- surfaceFormat.blueBufferSize() > 8;
- bool usesLayer = view().layer;
- if (usesCoreGraphics && !usesDeepColor && !usesLayer) {
- [nsWindow setDynamicDepthLimit:NO];
- [nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB];
- }
-
if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace)
nsWindow.colorSpace = NSColorSpace.sRGBColorSpace;
diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm
index 37e972dba9..41b96b2df6 100644
--- a/src/plugins/platforms/cocoa/qnsview_dragging.mm
+++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm
@@ -270,6 +270,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
// The drag was started from within the application
response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(),
point, qtAllowed, buttons, modifiers);
+ nativeDrag->setAcceptedAction(response.acceptedAction());
} else {
QCocoaDropData mimeData(sender.draggingPasteboard);
response = QWindowSystemInterface::handleDrop(target, &mimeData,
@@ -282,6 +283,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
{
Q_UNUSED(session);
Q_UNUSED(screenPoint);
+ Q_UNUSED(operation);
if (!m_platformWindow)
return;
@@ -290,8 +292,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
if (!target)
return;
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
+ QCocoaIntegration::instance()->drag();
// Qt starts drag-and-drop on a mouse button press event. Cococa in
// this case won't send the matching release event, so we have to
diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm
index d2e6f848a0..ce5488ead0 100644
--- a/src/plugins/platforms/cocoa/qnsview_drawing.mm
+++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm
@@ -43,9 +43,7 @@
- (void)initDrawing
{
- self.wantsLayer = [self layerExplicitlyRequested]
- || [self shouldUseMetalLayer]
- || [self layerEnabledByMacOS];
+ [self updateLayerBacking];
// Enable high-DPI OpenGL for retina displays. Enabling has the side
// effect that Cocoa will start calling glViewport(0, 0, width, height),
@@ -71,22 +69,13 @@
return YES;
}
-- (void)drawRect:(NSRect)dirtyRect
-{
- Q_UNUSED(dirtyRect);
+// ----------------------- Layer setup -----------------------
- if (!m_platformWindow)
- return;
-
- QRegion exposedRegion;
- const NSRect *dirtyRects;
- NSInteger numDirtyRects;
- [self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
- for (int i = 0; i < numDirtyRects; ++i)
- exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
-
- qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
- m_platformWindow->handleExposeEvent(exposedRegion);
+- (void)updateLayerBacking
+{
+ self.wantsLayer = [self layerEnabledByMacOS]
+ || [self layerExplicitlyRequested]
+ || [self shouldUseMetalLayer];
}
- (BOOL)layerEnabledByMacOS
@@ -123,40 +112,81 @@
return surfaceType == QWindow::MetalSurface || surfaceType == QWindow::VulkanSurface;
}
+/*
+ This method is called by AppKit when layer-backing is requested by
+ setting wantsLayer too YES (via -[NSView _updateLayerBackedness]),
+ or in cases where AppKit itself decides that a view should be
+ layer-backed.
+
+ Note however that some code paths in AppKit will not go via this
+ method for creating the backing layer, and will instead create the
+ layer manually, and just call setLayer. An example of this is when
+ an NSOpenGLContext is attached to a view, in which case AppKit will
+ create a new layer in NSOpenGLContextSetLayerOnViewIfNecessary.
+
+ For this reason we leave the implementation of this override as
+ minimal as possible, only focusing on creating the appropriate
+ layer type, and then leave it up to setLayer to do the work of
+ making sure the layer is set up correctly.
+*/
- (CALayer *)makeBackingLayer
{
if ([self shouldUseMetalLayer]) {
// Check if Metal is supported. If it isn't then it's most likely
// too late at this point and the QWindow will be non-functional,
// but we can at least print a warning.
- if (![MTLCreateSystemDefaultDevice() autorelease]) {
- qWarning() << "QWindow initialization error: Metal is not supported";
- return [super makeBackingLayer];
+ if ([MTLCreateSystemDefaultDevice() autorelease]) {
+ return [CAMetalLayer layer];
+ } else {
+ qCWarning(lcQpaDrawing) << "Failed to create QWindow::MetalSurface."
+ << "Metal is not supported by any of the GPUs in this system.";
}
-
- CAMetalLayer *layer = [CAMetalLayer layer];
-
- // Set the contentsScale for the layer. This is normally done in
- // viewDidChangeBackingProperties, however on startup that function
- // is called before the layer is created here. The layer's drawableSize
- // is updated from layoutSublayersOfLayer as usual.
- layer.contentsScale = self.window.backingScaleFactor;
-
- return layer;
}
return [super makeBackingLayer];
}
+/*
+ This method is called by AppKit whenever the view is asked to change
+ its layer, which can happen both as a result of enabling layer-backing,
+ or when a layer is set explicitly. The latter can happen both when a
+ view is layer-hosting, or when AppKit internals are switching out the
+ layer-backed view, as described above for makeBackingLayer.
+*/
- (void)setLayer:(CALayer *)layer
{
- qCDebug(lcQpaDrawing) << "Making" << self << "layer-backed with" << layer
- << "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested"
+ qCDebug(lcQpaDrawing) << "Making" << self
+ << (self.wantsLayer ? "layer-backed" : "layer-hosted")
+ << "with" << layer << "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested"
: [self shouldUseMetalLayer] ? "needed by surface type" : "enabled by macOS");
+
+ if (layer.delegate && layer.delegate != self) {
+ qCWarning(lcQpaDrawing) << "Layer already has delegate" << layer.delegate
+ << "This delegate is responsible for all view updates for" << self;
+ } else {
+ layer.delegate = self;
+ }
+
[super setLayer:layer];
- layer.delegate = self;
+
+ // When adding a view to a view hierarchy the backing properties will change
+ // which results in updating the contents scale, but in case of switching the
+ // layer on a view that's already in a view hierarchy we need to manually ensure
+ // the scale is up to date.
+ if (self.superview)
+ [self updateLayerContentsScale];
+
+ if (self.opaque && lcQpaDrawing().isDebugEnabled()) {
+ // If the view claims to be opaque we expect it to fill the entire
+ // layer with content, in which case we want to detect any areas
+ // where it doesn't.
+ layer.backgroundColor = NSColor.magentaColor.CGColor;
+ }
+
}
+// ----------------------- Layer updates -----------------------
+
- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
{
// We need to set this explicitly since the super implementation
@@ -164,64 +194,106 @@
return NSViewLayerContentsRedrawDuringViewResize;
}
-#if 0 // Disabled until we enable lazy backingstore resizing
- (NSViewLayerContentsPlacement)layerContentsPlacement
{
- // Always place the layer at top left without any automatic scaling,
- // so that we can re-use larger layers when resizing a window down.
+ // Always place the layer at top left without any automatic scaling.
+ // This will highlight situations where we're missing content for the
+ // layer by not responding to the displayLayer: request synchronously.
+ // It also allows us to re-use larger layers when resizing a window down.
return NSViewLayerContentsPlacementTopLeft;
}
-#endif
-- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
+- (void)viewDidChangeBackingProperties
{
- CGSize drawableSize = layer.bounds.size;
- drawableSize.width *= layer.contentsScale;
- drawableSize.height *= layer.contentsScale;
- layer.drawableSize = drawableSize;
+ qCDebug(lcQpaDrawing) << "Backing properties changed for" << self;
+
+ if (self.layer)
+ [self updateLayerContentsScale];
+
+ // Ideally we would plumb this situation through QPA in a way that lets
+ // clients invalidate their own caches, recreate QBackingStore, etc.
+ // For now we trigger an expose, and let QCocoaBackingStore deal with
+ // buffer invalidation internally.
+ [self setNeedsDisplay:YES];
}
-- (void)layoutSublayersOfLayer:(CALayer *)layer
+- (void)updateLayerContentsScale
{
- if ([layer isKindOfClass:CAMetalLayer.class])
- [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
+ // We expect clients to fill the layer with retina aware content,
+ // based on the devicePixelRatio of the QWindow, so we set the
+ // layer's content scale to match that. By going via devicePixelRatio
+ // instead of applying the NSWindow's backingScaleFactor, we also take
+ // into account OpenGL views with wantsBestResolutionOpenGLSurface set
+ // to NO. In this case the window will have a backingScaleFactor of 2,
+ // but the QWindow will have a devicePixelRatio of 1.
+ auto devicePixelRatio = m_platformWindow->devicePixelRatio();
+ qCDebug(lcQpaDrawing) << "Updating" << self.layer << "content scale to" << devicePixelRatio;
+ self.layer.contentsScale = devicePixelRatio;
}
-- (void)displayLayer:(CALayer *)layer
+/*
+ This method is called by AppKit to determine whether it should update
+ the contentScale of the layer to match the window backing scale.
+
+ We always return NO since we're updating the contents scale manually.
+*/
+- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)scale fromWindow:(NSWindow *)window
{
- if (!NSThread.isMainThread) {
- // Qt is calling AppKit APIs such as -[NSOpenGLContext setView:] on secondary threads,
- // which we shouldn't do. This may result in AppKit (wrongly) triggering a display on
- // the thread where we made the call, so block it here and defer to the main thread.
- qCWarning(lcQpaDrawing) << "Display non non-main thread! Deferring to main thread";
- dispatch_async(dispatch_get_main_queue(), ^{ self.needsDisplay = YES; });
- return;
- }
+ Q_UNUSED(layer); Q_UNUSED(scale); Q_UNUSED(window);
+ return NO;
+}
- Q_ASSERT(layer == self.layer);
+// ----------------------- Draw callbacks -----------------------
+
+/*
+ This method is called by AppKit for the non-layer case, where we are
+ drawing into the NSWindow's surface.
+*/
+- (void)drawRect:(NSRect)dirtyBoundingRect
+{
+ Q_ASSERT_X(!self.layer, "QNSView",
+ "The drawRect code path should not be hit when we are layer backed");
if (!m_platformWindow)
return;
- qCDebug(lcQpaDrawing) << "[QNSView displayLayer]" << m_platformWindow->window();
+ QRegion exposedRegion;
+ const NSRect *dirtyRects;
+ NSInteger numDirtyRects;
+ [self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
+ for (int i = 0; i < numDirtyRects; ++i)
+ exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
- // FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
- m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
+ if (exposedRegion.isEmpty())
+ exposedRegion = QRectF::fromCGRect(dirtyBoundingRect).toRect();
+
+ qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
+ m_platformWindow->handleExposeEvent(exposedRegion);
}
-- (void)viewDidChangeBackingProperties
+/*
+ This method is called by AppKit when we are layer-backed, where
+ we are drawing into the layer.
+*/
+- (void)displayLayer:(CALayer *)layer
{
- CALayer *layer = self.layer;
- if (!layer)
- return;
+ Q_ASSERT_X(self.layer && layer == self.layer, "QNSView",
+ "The displayLayer code path should only be hit for our own layer");
- layer.contentsScale = self.window.backingScaleFactor;
+ if (!m_platformWindow)
+ return;
- // Metal layers must be manually updated on e.g. screen change
- if ([layer isKindOfClass:CAMetalLayer.class]) {
- [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
- [self setNeedsDisplay:YES];
+ if (!NSThread.isMainThread) {
+ // Qt is calling AppKit APIs such as -[NSOpenGLContext setView:] on secondary threads,
+ // which we shouldn't do. This may result in AppKit (wrongly) triggering a display on
+ // the thread where we made the call, so block it here and defer to the main thread.
+ qCWarning(lcQpaDrawing) << "Display non non-main thread! Deferring to main thread";
+ dispatch_async(dispatch_get_main_queue(), ^{ self.needsDisplay = YES; });
+ return;
}
+
+ qCDebug(lcQpaDrawing) << "[QNSView displayLayer]" << m_platformWindow->window();
+ m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
}
@end
diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm
index 7c566442f0..30613eca32 100644
--- a/src/plugins/platforms/cocoa/qnsview_mouse.mm
+++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm
@@ -394,14 +394,16 @@
}
// Close the popups if the click was outside.
if (!inside) {
+ bool selfClosed = false;
Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type();
while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
+ selfClosed = self == popup->view();
QWindowSystemInterface::handleCloseEvent(popup->window());
QWindowSystemInterface::flushWindowSystemEvents();
}
// Consume the mouse event when closing the popup, except for tool tips
// were it's expected that the event is processed normally.
- if (type != Qt::ToolTip)
+ if (type != Qt::ToolTip || selfClosed)
return;
}
}
diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm
index 52f765eb31..6b4e110af2 100644
--- a/src/plugins/platforms/cocoa/qnswindow.mm
+++ b/src/plugins/platforms/cocoa/qnswindow.mm
@@ -253,20 +253,10 @@ static bool isMouseEvent(NSEvent *ev)
return m_platformWindow ? m_platformWindow->isOpaque() : [super isOpaque];
}
-/*!
- Borderless windows need a transparent background
-
- Technically windows with NSWindowStyleMaskTexturedBackground
- (such as windows with unified toolbars) need to draw the textured
- background of the NSWindow, and can't have a transparent
- background, but as NSWindowStyleMaskBorderless is 0, you can't
- have a window with NSWindowStyleMaskTexturedBackground that is
- also borderless.
-*/
- (NSColor *)backgroundColor
{
- return self.styleMask == NSWindowStyleMaskBorderless
- ? [NSColor clearColor] : [super backgroundColor];
+ return self.styleMask == NSWindowStyleMaskBorderless ?
+ [NSColor clearColor] : [super backgroundColor];
}
- (void)sendEvent:(NSEvent*)theEvent
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 3677877538..00b2267f0d 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -38,14 +38,18 @@
****************************************************************************/
#include "qpaintengine_mac_p.h"
+#if defined(QT_PRINTSUPPORT_LIB)
#include "qprintengine_mac_p.h"
+#endif
#include <qbitmap.h>
#include <qpaintdevice.h>
#include <qpainterpath.h>
#include <qpixmapcache.h>
#include <private/qpaintengine_raster_p.h>
+#if defined(QT_PRINTSUPPORT_LIB)
#include <qprinter.h>
+#endif
#include <qstack.h>
#include <qwidget.h>
#include <qvarlengtharray.h>
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index d7aba66b2f..03be44e095 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -941,6 +941,8 @@ public:
{
Q_Q(QWindowsDirect2DPaintEngine);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
// Default path (no optimization)
if (!(path.shape() == QVectorPath::LinesHint || path.shape() == QVectorPath::PolygonHint)
|| !pen.dashBrush
@@ -948,6 +950,7 @@ public:
|| q->state()->renderHints.testFlag(QPainter::HighQualityAntialiasing)
#endif
|| q->state()->renderHints.testFlag(QPainter::Antialiasing)) {
+QT_WARNING_POP
ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
index 89c2e89f58..8768f9dd8c 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
@@ -59,6 +59,8 @@
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/private/qinputdevicemanager_p.h>
+#include <QtCore/qvector.h>
+
QT_BEGIN_NAMESPACE
class QOpenGLShaderProgram;
@@ -143,7 +145,7 @@ private:
int cursorsPerRow;
int width, height; // width and height of the atlas
int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
- QList<QPoint> hotSpots;
+ QVector<QPoint> hotSpots;
QImage image; // valid until it's uploaded
} m_cursorAtlas;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
index c96dd585d3..d47b579238 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
@@ -41,7 +41,7 @@
#define QEGLFSKMSGBMCURSOR_H
#include <qpa/qplatformcursor.h>
-#include <QtCore/QList>
+#include <QtCore/QVector>
#include <QtGui/QImage>
#include <QtGui/private/qinputdevicemanager_p.h>
@@ -110,7 +110,7 @@ private:
int cursorsPerRow;
int width, height; // width and height of the atlas
int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
- QList<QPoint> hotSpots;
+ QVector<QPoint> hotSpots;
QImage image;
} m_cursorAtlas;
};
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index 2034632fb3..16dbfe1522 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -155,20 +155,33 @@ gbm_surface *QEglFSKmsGbmScreen::createSurface(EGLConfig eglConfig)
qCDebug(qLcEglfsKmsDebug, "Creating gbm_surface for screen %s", qPrintable(name()));
const auto gbmDevice = static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice();
- EGLint native_format = -1;
- EGLBoolean success = eglGetConfigAttrib(display(), eglConfig, EGL_NATIVE_VISUAL_ID, &native_format);
- qCDebug(qLcEglfsKmsDebug) << "Got native format" << Qt::hex << native_format << Qt::dec << "from eglGetConfigAttrib() with return code" << bool(success);
-
- if (success)
- m_gbm_surface = gbm_surface_create(gbmDevice,
- rawGeometry().width(),
- rawGeometry().height(),
- native_format,
- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ // If there was no format override given in the config file,
+ // query the native (here, gbm) format from the EGL config.
+ const bool queryFromEgl = !m_output.drm_format_requested_by_user;
+ if (queryFromEgl) {
+ EGLint native_format = -1;
+ EGLBoolean success = eglGetConfigAttrib(display(), eglConfig, EGL_NATIVE_VISUAL_ID, &native_format);
+ qCDebug(qLcEglfsKmsDebug) << "Got native format" << Qt::hex << native_format << Qt::dec
+ << "from eglGetConfigAttrib() with return code" << bool(success);
+
+ if (success) {
+ m_gbm_surface = gbm_surface_create(gbmDevice,
+ rawGeometry().width(),
+ rawGeometry().height(),
+ native_format,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ if (m_gbm_surface)
+ m_output.drm_format = gbmFormatToDrmFormat(native_format);
+ }
+ }
- if (!m_gbm_surface) { // fallback for older drivers
+ // Fallback for older drivers, and when "format" is explicitly specified
+ // in the output config. (not guaranteed that the requested format works
+ // of course, but do what we are told to)
+ if (!m_gbm_surface) {
uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format);
- qCDebug(qLcEglfsKmsDebug, "Could not create surface with EGL_NATIVE_VISUAL_ID, falling back to format %x", gbmFormat);
+ if (queryFromEgl)
+ qCDebug(qLcEglfsKmsDebug, "Could not create surface with EGL_NATIVE_VISUAL_ID, falling back to format %x", gbmFormat);
m_gbm_surface = gbm_surface_create(gbmDevice,
rawGeometry().width(),
rawGeometry().height(),
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index 776343c5aa..c5856051de 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -211,6 +211,8 @@ namespace
} logActivity;
}
+using namespace QT_PREPEND_NAMESPACE(QtPrivate);
+
extern "C" int qt_main_wrapper(int argc, char *argv[])
{
@autoreleasepool {
diff --git a/src/plugins/platforms/ios/quiview_accessibility.mm b/src/plugins/platforms/ios/quiview_accessibility.mm
index 458ddcc9b8..6612dc131e 100644
--- a/src/plugins/platforms/ios/quiview_accessibility.mm
+++ b/src/plugins/platforms/ios/quiview_accessibility.mm
@@ -101,7 +101,7 @@
- (id)accessibilityElementAtIndex:(NSInteger)index
{
[self initAccessibility];
- if (index >= [m_accessibleElements count])
+ if (NSUInteger(index) >= [m_accessibleElements count])
return nil;
return m_accessibleElements[index];
}
diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp
index e8eda2605f..7e8a382512 100644
--- a/src/plugins/platforms/wasm/qwasmbackingstore.cpp
+++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp
@@ -81,6 +81,11 @@ void QWasmBackingStore::updateTexture()
if (m_dirty.isNull())
return;
+ if (m_recreateTexture && m_texture->isCreated()) {
+ m_recreateTexture = false;
+ m_texture->destroy();
+ }
+
if (!m_texture->isCreated()) {
m_texture->setMinificationFilter(QOpenGLTexture::Nearest);
m_texture->setMagnificationFilter(QOpenGLTexture::Nearest);
@@ -146,9 +151,7 @@ void QWasmBackingStore::resize(const QSize &size, const QRegion &staticContents)
m_image = QImage(size * window()->devicePixelRatio(), QImage::Format_RGB32);
m_image.setDevicePixelRatio(window()->devicePixelRatio());
-
- if (m_texture->isCreated())
- m_texture->destroy();
+ m_recreateTexture = true;
}
QImage QWasmBackingStore::toImage() const
diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.h b/src/plugins/platforms/wasm/qwasmbackingstore.h
index 4bca83c457..b93c96b483 100644
--- a/src/plugins/platforms/wasm/qwasmbackingstore.h
+++ b/src/plugins/platforms/wasm/qwasmbackingstore.h
@@ -64,6 +64,7 @@ private:
QImage m_image;
QScopedPointer<QOpenGLTexture> m_texture;
QRegion m_dirty;
+ bool m_recreateTexture = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index f2eabfa486..e536bc0ee3 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -139,6 +139,8 @@ QPlatformCursor *QWasmScreen::cursor() const
void QWasmScreen::resizeMaximizedWindows()
{
+ if (!screen())
+ return;
QPlatformScreen::resizeMaximizedWindows();
}
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index 3cfa7e3856..e37351f9e0 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -152,6 +152,18 @@
"features": [
"disable_program_cache"
]
- }
+ },
+ {
+ "id": 13,
+ "description": "Disable DesktopGL on Windows with Mobile Intel(R) 4 Series Express Chipset Family graphics card (QTBUG-58772)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x2A42" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ }
]
}
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index b87e43f3f7..4e6d3306e1 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -115,12 +115,21 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const
{
+ enum : int { attempts = 3 };
IDataObject * pDataObj = nullptr;
- if (OleGetClipboard(&pDataObj) == S_OK) {
- if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
- return pDataObj;
+ // QTBUG-53979, retry in case the other application has clipboard locked
+ for (int i = 1; i <= attempts; ++i) {
+ if (SUCCEEDED(OleGetClipboard(&pDataObj))) {
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
+ return pDataObj;
+ }
+ qCWarning(lcQpaMime, i == attempts
+ ? "Unable to obtain clipboard."
+ : "Retrying to obtain clipboard.");
+ QThread::msleep(50);
}
+
return nullptr;
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 101db75d0b..d9521e7e08 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -196,6 +196,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
wglShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolve("wglShareLists"));
wglSwapBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC)>(resolve("wglSwapBuffers"));
wglSetPixelFormat = reinterpret_cast<BOOL (WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)>(resolve("wglSetPixelFormat"));
+ wglDescribePixelFormat = reinterpret_cast<int (WINAPI *)(HDC, int, UINT, PIXELFORMATDESCRIPTOR *)>(resolve("wglDescribePixelFormat"));
glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError"));
glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv"));
@@ -214,6 +215,11 @@ BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRI
return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd);
}
+int QWindowsOpengl32DLL::describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd)
+{
+ return moduleIsNotOpengl32() ? wglDescribePixelFormat(dc, pf, size, pfd) : DescribePixelFormat(dc, pf, size, pfd);
+}
+
QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context)
{
return new QWindowsGLContext(this, context);
@@ -322,11 +328,11 @@ static inline bool
static void describeFormats(HDC hdc)
{
- const int pfiMax = DescribePixelFormat(hdc, 0, 0, nullptr);
- for (int i = 0; i < pfiMax; i++) {
+ const int pfiMax = QOpenGLStaticContext::opengl32.describePixelFormat(hdc, 0, 0, nullptr);
+ for (int i = 1; i <= pfiMax; i++) {
PIXELFORMATDESCRIPTOR pfd;
initPixelFormatDescriptor(&pfd);
- DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd;
}
}
@@ -617,7 +623,7 @@ static int choosePixelFormat(HDC hdc,
// Verify if format is acceptable. Note that the returned
// formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
initPixelFormatDescriptor(obtainedPfd);
- DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat
<< " not acceptable=" << *obtainedPfd;
@@ -885,13 +891,6 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
result.profile = QSurfaceFormat::CoreProfile;
else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
result.profile = QSurfaceFormat::CompatibilityProfile;
- if (result.version < 0x0400)
- return result;
- // v4.0 onwards
- value = 0;
- QOpenGLStaticContext::opengl32.glGetIntegerv(RESET_NOTIFICATION_STRATEGY_ARB, &value);
- if (value == LOSE_CONTEXT_ON_RESET_ARB)
- result.options |= QSurfaceFormat::ResetNotification;
return result;
}
@@ -969,6 +968,7 @@ QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
*/
#define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample"
+#define ROBUSTNESS_EXTENSION "GL_ARB_robustness"
QOpenGLStaticContext::QOpenGLStaticContext() :
vendor(QOpenGLStaticContext::getGlString(GL_VENDOR)),
@@ -989,9 +989,31 @@ QOpenGLStaticContext::QOpenGLStaticContext() :
wglGetExtensionsStringARB(reinterpret_cast<WglGetExtensionsStringARB>(
reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetExtensionsStringARB"))))
{
- if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ")
- || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1)
- extensions |= SampleBuffers;
+ if (defaultFormat.version < 0x0300) {
+ if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ")
+ || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1)
+ extensions |= SampleBuffers;
+ if (extensionNames.startsWith(ROBUSTNESS_EXTENSION " ")
+ || extensionNames.indexOf(" " ROBUSTNESS_EXTENSION " ") != -1)
+ extensions |= Robustness;
+ } else {
+ typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint);
+ auto glGetStringi = reinterpret_cast<glGetStringi_t>(
+ reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetStringi")));
+ if (glGetStringi) {
+ GLint n = 0;
+ QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+ for (GLint i = 0; i < n; ++i) {
+ const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
+ if (p) {
+ if (!strcmp(p, SAMPLE_BUFFER_EXTENSION))
+ extensions |= SampleBuffers;
+ else if (!strcmp(p, ROBUSTNESS_EXTENSION))
+ extensions |= Robustness;
+ }
+ }
+ }
+ }
}
QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
@@ -1230,27 +1252,11 @@ bool QWindowsGLContext::updateObtainedParams(HDC hdc, int *obtainedSwapInterval)
if (m_staticContext->wglGetSwapInternalExt && obtainedSwapInterval)
*obtainedSwapInterval = m_staticContext->wglGetSwapInternalExt();
- bool hasRobustness = false;
- if (m_obtainedFormat.majorVersion() < 3) {
- const char *exts = reinterpret_cast<const char *>(QOpenGLStaticContext::opengl32.glGetString(GL_EXTENSIONS));
- hasRobustness = exts && strstr(exts, "GL_ARB_robustness");
- } else {
- typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint);
- auto glGetStringi = reinterpret_cast<glGetStringi_t>(
- reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetStringi")));
- if (glGetStringi) {
- GLint n = 0;
- QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n);
- for (GLint i = 0; i < n; ++i) {
- const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
- if (p && !strcmp(p, "GL_ARB_robustness")) {
- hasRobustness = true;
- break;
- }
- }
- }
- }
- if (hasRobustness) {
+ if (testFlag(m_staticContext->extensions, QOpenGLStaticContext::Robustness)) {
+ GLint value = 0;
+ QOpenGLStaticContext::opengl32.glGetIntegerv(RESET_NOTIFICATION_STRATEGY_ARB, &value);
+ if (value == LOSE_CONTEXT_ON_RESET_ARB)
+ m_obtainedFormat.setOption(QSurfaceFormat::ResetNotification);
m_getGraphicsResetStatus = reinterpret_cast<GlGetGraphicsResetStatusArbType>(
reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetGraphicsResetStatusARB")));
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 1abe2eb390..e5f6fefd5a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -107,6 +107,7 @@ struct QWindowsOpengl32DLL
// Wrappers. Always use these instead of SwapBuffers/wglSwapBuffers/etc.
BOOL swapBuffers(HDC dc);
BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
// WGL
HGLRC (WINAPI * wglCreateContext)(HDC dc);
@@ -130,6 +131,7 @@ private:
// For Mesa llvmpipe shipped with a name other than opengl32.dll
BOOL (WINAPI * wglSwapBuffers)(HDC dc);
BOOL (WINAPI * wglSetPixelFormat)(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int (WINAPI * wglDescribePixelFormat)(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
};
class QOpenGLStaticContext : public QWindowsStaticOpenGLContext
@@ -140,7 +142,8 @@ public:
enum Extensions
{
SampleBuffers = 0x1,
- sRGBCapableFramebuffer = 0x2
+ sRGBCapableFramebuffer = 0x2,
+ Robustness = 0x4,
};
typedef bool
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 8cd09a34eb..df63adf558 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -42,6 +42,7 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowscursor.h"
+#include "qwindowstheme.h"
#include <QtCore/qt_windows.h>
@@ -543,10 +544,13 @@ bool QWindowsScreenManager::handleScreenChanges()
// Look for changed monitors, add new ones
const WindowsScreenDataList newDataList = monitorData();
const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
+ bool primaryScreenChanged = false;
for (const QWindowsScreenData &newData : newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
m_screens.at(existingIndex)->handleChanges(newData);
+ if (existingIndex == 0)
+ primaryScreenChanged = true;
} else {
auto *newScreen = new QWindowsScreen(newData);
m_screens.push_back(newScreen);
@@ -563,6 +567,8 @@ bool QWindowsScreenManager::handleScreenChanges()
removeScreen(i);
} // for existing screens
} // not lock screen
+ if (primaryScreenChanged)
+ QWindowsTheme::instance()->refreshFonts();
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 4e24308445..07120230ce 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -85,6 +85,8 @@ public:
static bool useNativeMenus();
+ void refreshFonts();
+
static const char *name;
private:
@@ -92,7 +94,6 @@ private:
void clearPalettes();
void refreshPalettes();
void clearFonts();
- void refreshFonts();
void refreshIconPixmapSizes();
static QWindowsTheme *m_instance;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 0a97305dd4..5c13bd9650 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1937,8 +1937,10 @@ void QWindowsWindow::handleGeometryChange()
{
const QRect previousGeometry = m_data.geometry;
m_data.geometry = geometry_sys();
- if (testFlag(WithinDpiChanged))
- return; // QGuiApplication will send resize
+ if (testFlag(WithinDpiChanged)
+ && QWindowsContext::instance()->screenManager().screenForHwnd(m_data.hwnd) != screen()) {
+ return; // QGuiApplication will send resize when screen actually changes
+ }
QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
// expose events when shrinking, synthesize.
@@ -2695,10 +2697,16 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
return true;
}
if (localPos.y() < 0) {
- const int topResizeBarPos = -frameMargins().top();
- if (localPos.y() >= topResizeBarPos)
+ // We want to return HTCAPTION/true only over the outer sizing frame, not the entire title bar,
+ // otherwise the title bar buttons (close, etc.) become unresponsive on Windows 7 (QTBUG-78262).
+ // However, neither frameMargins() nor GetSystemMetrics(SM_CYSIZEFRAME), etc., give the correct
+ // sizing frame height in all Windows versions/scales. This empirical constant seems to work, though.
+ const int sizingHeight = 9;
+ const int topResizeBarPos = sizingHeight - frameMargins().top();
+ if (localPos.y() < topResizeBarPos) {
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
- return true;
+ return true;
+ }
}
}
if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 943c1ff368..b2b401dd40 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -670,18 +670,26 @@ HRESULT QWindowsUiaMainProvider::ElementProviderFromPoint(double x, double y, IR
QPoint point;
nativeUiaPointToPoint(uiaPoint, window, &point);
- QAccessibleInterface *targetacc = accessible->childAt(point.x(), point.y());
-
- if (targetacc) {
- QAccessibleInterface *acc = targetacc;
- // Controls can be embedded within grouping elements. By default returns the innermost control.
- while (acc) {
- targetacc = acc;
- // For accessibility tools it may be better to return the text element instead of its subcomponents.
- if (targetacc->textInterface()) break;
- acc = acc->childAt(point.x(), point.y());
+ if (auto targetacc = accessible->childAt(point.x(), point.y())) {
+ auto acc = accessible->childAt(point.x(), point.y());
+ // Reject the cases where childAt() returns a different instance in each call for the same
+ // element (e.g., QAccessibleTree), as it causes an endless loop with Youdao Dictionary installed.
+ if (targetacc == acc) {
+ // Controls can be embedded within grouping elements. By default returns the innermost control.
+ while (acc) {
+ targetacc = acc;
+ // For accessibility tools it may be better to return the text element instead of its subcomponents.
+ if (targetacc->textInterface()) break;
+ acc = targetacc->childAt(point.x(), point.y());
+ if (acc != targetacc->childAt(point.x(), point.y())) {
+ qCDebug(lcQpaUiAutomation) << "Non-unique childAt() for" << targetacc;
+ break;
+ }
+ }
+ *pRetVal = providerForAccessible(targetacc);
+ } else {
+ qCDebug(lcQpaUiAutomation) << "Non-unique childAt() for" << accessible;
}
- *pRetVal = providerForAccessible(targetacc);
}
return S_OK;
}
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
index 8e395669f8..d8b8f7281d 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
@@ -48,6 +48,7 @@
#include <QtGui/qaccessible.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
QT_BEGIN_NAMESPACE
@@ -227,7 +228,7 @@ HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **pRetVal)
return UIA_E_ELEMENTNOTAVAILABLE;
int len = textInterface->characterCount();
- QList<QRect> rectList;
+ QVarLengthArray<QRect> rectList;
if ((m_startOffset >= 0) && (m_endOffset <= len) && (m_startOffset < m_endOffset)) {
int start, end;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
index 524000b618..355dbf7d20 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -105,19 +107,17 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawEle
*value = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
if (QAccessibleInterface *table = tableCellInterface->table()) {
- **ptrElementId = idForAccessible(table);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ *elementId = idForAccessible(table);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
index e469991de2..3bd90f6850 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -104,21 +106,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column
*returnValue = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
- **ptrElementId = idForAccessible(cell);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ *elementId = idForAccessible(cell);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
}
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
index 6f3ad6dcd2..0b1db306bd 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
@@ -64,6 +64,8 @@
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
using namespace QWinRTUiAutomation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -179,7 +181,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elemen
}
// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
-HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
+HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds,
UINT32 *returnValueSize,
IIRawElementProviderSimple ***returnValue)
{
@@ -190,7 +192,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<Q
QList<IIRawElementProviderSimple *> rawProviderList;
- for (auto elementId : qAsConst(elementIds)) {
+ for (auto elementId : elementIds) {
IIRawElementProviderSimple *rawProvider;
if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
rawProviderList.append(rawProvider);
@@ -515,10 +517,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
*returnValue = nullptr;
auto accid = id();
- auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
+ auto children = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, children]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
int childCount = accessible->childCount();
for (int i = 0; i < childCount; ++i) {
@@ -526,11 +527,10 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
QAccessible::Id childId = idForAccessible(childAcc);
QWinRTUiaMetadataCache::instance()->load(childId);
if (!childAcc->state().invisible)
- (*ptrChildren)->append(childId);
+ children->append(childId);
}
}
}
- delete ptrChildren;
return S_OK;
}))) {
return E_FAIL;
@@ -538,7 +538,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
- for (auto childId : qAsConst(*children)) {
+ for (auto childId : *children) {
if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
IAutomationPeer *peer;
if (SUCCEEDED(provider.CopyTo(&peer)))
@@ -750,10 +750,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
// Scale coordinates from High DPI screens?
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId, point]() {
// Controls can be embedded within grouping elements. By default returns the innermost control.
QAccessibleInterface *target = accessibleForId(accid);
while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
@@ -761,9 +760,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
// For accessibility tools it may be better to return the text element instead of its subcomponents.
if (target->textInterface()) break;
}
- **ptrElementId = idForAccessible(target);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
- delete ptrElementId;
+ *elementId = idForAccessible(target);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
index 384a166cf7..23a6e56ae7 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
@@ -69,7 +69,7 @@ public:
virtual ~QWinRTUiaMainProvider();
static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
- static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
+ static HRESULT rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
static void notifyFocusChange(QAccessibleEvent *event);
static void notifyVisibilityChange(QAccessibleEvent *event);
static void notifyStateChange(QAccessibleStateChangeEvent *event);
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
index 9bc88272ba..2cb5aa685c 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -94,21 +96,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer
*value = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
// Radio buttons do not require a container.
if (accessible->role() == QAccessible::ListItem) {
if (QAccessibleInterface *parent = accessible->parent()) {
if (parent->role() == QAccessible::List) {
- **ptrElementId = idForAccessible(parent);
+ *elementId = idForAccessible(parent);
}
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
index 9e61a8df61..4d825351c8 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -89,10 +91,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
*value = false;
auto accid = id();
- auto selectionRequired = QSharedPointer<bool>(new bool(false));
- auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
+ auto selectionRequired = std::make_shared<bool>(false);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selectionRequired]() {
// Initially returns false if none are selected. After the first selection, it may be required.
bool anySelected = false;
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
@@ -105,9 +106,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
}
}
}
- **ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
+ *selectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
}
- delete ptrSelectionRequired;
return S_OK;
}))) {
return E_FAIL;
@@ -128,10 +128,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
int childCount = accessible->childCount();
for (int i = 0; i < childCount; ++i) {
@@ -139,12 +138,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
if (childAcc->state().selected) {
QAccessible::Id childId = idForAccessible(childAcc);
QWinRTUiaMetadataCache::instance()->load(childId);
- (*ptrElementIds)->append(childId);
+ elementIds->append(childId);
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
index 1af74a8b72..7cd953de87 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -79,21 +81,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT3
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
@@ -113,21 +113,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
index e71ade3c1f..d763b320b1 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -91,10 +93,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
for (int i = 0; i < tableInterface->columnCount(); ++i) {
@@ -105,14 +106,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
@@ -132,10 +132,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
for (int i = 0; i < tableInterface->rowCount(); ++i) {
@@ -146,14 +145,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
index aa120377df..cd7420f360 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -104,26 +106,26 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
*returnValueSize = 0;
*returnValue = nullptr;
+ struct Selection { int startOffset, endOffset; };
+
auto accid = id();
- auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
- auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
+ auto selections = std::make_shared<QVarLengthArray<Selection>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selections]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
for (int i = 0; i < textInterface->selectionCount(); ++i) {
- QPair<int,int> sel;
- textInterface->selection(i, &sel.first, &sel.second);
- (*ptrSelections)->append(sel);
+ int startOffset, endOffset;
+ textInterface->selection(i, &startOffset, &endOffset);
+ selections->append({startOffset, endOffset});
}
- if ((*ptrSelections)->size() == 0) {
+ if (selections->size() == 0) {
// If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
- QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
- (*ptrSelections)->append(sel);
+ auto cur = textInterface->cursorPosition();
+ selections->append({cur, cur});
}
}
}
- delete ptrSelections;
return S_OK;
}))) {
return E_FAIL;
@@ -137,9 +139,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
if (!providerArray)
return E_OUTOFMEMORY;
- for (int i = 0; i < selCount; ++i) {
- ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
- textRangeProvider.CopyTo(&providerArray[i]);
+ auto dst = providerArray;
+ for (auto sel : *selections) {
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider
+ = Make<QWinRTUiaTextRangeProvider>(id(), sel.startOffset, sel.endOffset);
+ textRangeProvider.CopyTo(dst++);
}
*returnValueSize = selCount;
*returnValue = providerArray;
@@ -184,14 +188,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Fo
const QPoint pt(screenLocation.X, screenLocation.Y);
auto accid = id();
- auto offset = QSharedPointer<int>(new int);
- auto ptrOffset = new QSharedPointer<int>(offset);
+ auto offset = std::make_shared<int>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, offset]() {
if (QAccessibleInterface *accessible = accessibleForId(accid))
if (QAccessibleTextInterface *textInterface = accessible->textInterface())
- **ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
- delete ptrOffset;
+ *offset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
index fc3778d652..ca15feaff9 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -212,10 +214,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
auto accid = id();
auto startOffset = m_startOffset;
auto endOffset = m_endOffset;
- auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
- auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
+ auto rects = std::make_shared<QVarLengthArray<QRect>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, rects]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
int len = textInterface->characterCount();
@@ -233,7 +234,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
qMin(startRect.y(), endRect.y()),
qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
- (*ptrRects)->append(lineRect);
+ rects->append(lineRect);
}
if (end >= len) break;
textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
@@ -241,7 +242,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
}
}
}
- delete ptrRects;
return S_OK;
}))) {
return E_FAIL;
@@ -251,11 +251,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
if (!doubleArray)
return E_OUTOFMEMORY;
- for (int i = 0; i < rects->size(); ++i) {
- doubleArray[i*4] = (*rects)[i].left();
- doubleArray[i*4+1] = (*rects)[i].top();
- doubleArray[i*4+2] = (*rects)[i].width();
- doubleArray[i*4+3] = (*rects)[i].height();
+ DOUBLE *dst = doubleArray;
+ for (auto rect : *rects) {
+ *dst++ = rect.left();
+ *dst++ = rect.top();
+ *dst++ = rect.width();
+ *dst++ = rect.height();
}
*returnValue = doubleArray;
*returnValueSize = 4 * rects->size();
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
index 21389b74d2..255d8ee49e 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
@@ -96,24 +96,22 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value)
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
auto accid = id();
- auto tmpValue = QSharedPointer<QString>(new QString);
- auto ptrValue = new QSharedPointer<QString>(tmpValue);
- *tmpValue = hStrToQStr(value);
+ QString tmpValue = hStrToQStr(value);
- QEventDispatcherWinRT::runOnMainThread([accid, ptrValue]() {
+ QEventDispatcherWinRT::runOnMainThread([accid, tmpValue]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
// First sets the value as a text.
- accessible->setText(QAccessible::Value, **ptrValue);
+ accessible->setText(QAccessible::Value, tmpValue);
// Then, if the control supports the value interface (range value)
// and the supplied text can be converted to a number, and that number
// lies within the min/max limits, sets it as the control's current (numeric) value.
if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
bool ok = false;
- double numval = (*ptrValue)->toDouble(&ok);
+ double numval = tmpValue.toDouble(&ok);
if (ok) {
double minimum = valueInterface->minimumValue().toDouble();
double maximum = valueInterface->maximumValue().toDouble();
@@ -124,7 +122,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value)
}
}
QWinRTUiaMetadataCache::instance()->load(accid);
- delete ptrValue;
return S_OK;
}, 0);
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 5e5fefca90..2b77062b16 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -63,6 +63,7 @@
QT_BEGIN_NAMESPACE
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+typedef const GLubyte *(*glGetStringiProc)(GLenum, GLuint);
#ifndef GLX_CONTEXT_CORE_PROFILE_BIT_ARB
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
@@ -145,6 +146,27 @@ static inline QByteArray getGlString(GLenum param)
return QByteArray();
}
+static bool hasGlExtension(const QSurfaceFormat &format, const char *ext)
+{
+ if (format.majorVersion() < 3) {
+ auto exts = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ return exts && strstr(exts, ext);
+ } else {
+ auto glGetStringi = reinterpret_cast<glGetStringiProc>(
+ glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGetStringi")));
+ if (glGetStringi) {
+ GLint n = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+ for (GLint i = 0; i < n; ++i) {
+ const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
+ if (p && !strcmp(p, ext))
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
static void updateFormatFromContext(QSurfaceFormat &format)
{
// Update the version, profile, and context bit of the format
@@ -163,7 +185,7 @@ static void updateFormatFromContext(QSurfaceFormat &format)
format.setOption(QSurfaceFormat::StereoBuffers);
if (format.renderableType() == QSurfaceFormat::OpenGL) {
- if (format.version() >= qMakePair(4, 0)) {
+ if (hasGlExtension(format, "GL_ARB_robustness")) {
GLint value = 0;
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &value);
if (value == GL_LOSE_CONTEXT_ON_RESET_ARB)
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 0fe22bd318..8da299d491 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -773,7 +773,7 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
xcb_randr_mode_info_t *modeInfo = modesIter.data;
if (modeInfo->id == mode) {
const uint32_t dotCount = modeInfo->htotal * modeInfo->vtotal;
- m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / dotCount : 0;
+ m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / qreal(dotCount) : 0;
m_mode = mode;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 62931d2500..79698b4ef3 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -226,7 +226,7 @@ private:
QRect m_availableGeometry;
Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
QXcbCursor *m_cursor;
- int m_refreshRate = 60;
+ qreal m_refreshRate = 60.0;
QEdidParser m_edid;
};
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
index 90411f2a2c..8bfa239dbe 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.cpp
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -40,13 +40,11 @@
#include "qppdprintdevice.h"
#include "qcupsprintersupport_p.h"
+#include "private/qcups_p.h" // Only needed for PDPK_*
#if QT_CONFIG(mimetype)
#include <QtCore/QMimeDatabase>
#endif
-#include <qdebug.h>
-
-#include "private/qcups_p.h" // Only needed for PDPK_*
#ifndef QT_LINUXBASE // LSB merges everything into cups.h
#include <cups/language.h>
diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
index ead08dbce8..d0928fe6ab 100644
--- a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+++ b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
@@ -40,6 +40,7 @@
#include "qsql_ibase_p.h"
#include <qcoreapplication.h>
#include <qdatetime.h>
+#include <qdeadlinetimer.h>
#include <qvariant.h>
#include <qsqlerror.h>
#include <qsqlfield.h>
@@ -1570,10 +1571,9 @@ void QIBaseDriver::close()
d->eventBuffers.clear();
#if defined(FB_API_VER)
- // Workaround for Firebird crash
- QTime timer;
- timer.start();
- while (timer.elapsed() < 500)
+ // TODO check whether this workaround for Firebird crash is still needed
+ QDeadlineTimer timer(500);
+ while (!timer.hasExpired())
QCoreApplication::processEvents();
#endif
}
@@ -1914,7 +1914,12 @@ void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer)
if (counts[0]) {
if (eBuffer->subscriptionState == QIBaseEventBuffer::Subscribed) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit notification(i.key());
+QT_WARNING_POP
+#endif
emit notification(i.key(), QSqlDriver::UnknownSource, QVariant());
}
else if (eBuffer->subscriptionState == QIBaseEventBuffer::Starting)
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index febbe58506..0e195cfdb4 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -65,16 +65,7 @@
Q_DECLARE_METATYPE(MYSQL_RES*)
Q_DECLARE_METATYPE(MYSQL*)
-
-#if MYSQL_VERSION_ID >= 40108
Q_DECLARE_METATYPE(MYSQL_STMT*)
-#endif
-
-#if MYSQL_VERSION_ID >= 40100
-# define Q_CLIENT_MULTI_STATEMENTS CLIENT_MULTI_STATEMENTS
-#else
-# define Q_CLIENT_MULTI_STATEMENTS 0
-#endif
// MySQL above version 8 removed my_bool typedef while MariaDB kept it,
// by redefining it we can regain source compatibility.
@@ -199,10 +190,8 @@ protected:
bool nextResult() override;
void detachFromResultSet() override;
-#if MYSQL_VERSION_ID >= 40108
bool prepare(const QString &stmt) override;
bool exec() override;
-#endif
};
class QMYSQLResultPrivate: public QSqlResultPrivate
@@ -217,9 +206,7 @@ public:
result(0),
rowsAffected(0),
hasBlobs(false)
-#if MYSQL_VERSION_ID >= 40108
, stmt(0), meta(0), inBinds(0), outBinds(0)
-#endif
, preparedQuery(false)
{ }
@@ -247,13 +234,11 @@ public:
QVector<QMyField> fields;
-#if MYSQL_VERSION_ID >= 40108
MYSQL_STMT* stmt;
MYSQL_RES* meta;
MYSQL_BIND *inBinds;
MYSQL_BIND *outBinds;
-#endif
bool preparedQuery;
};
@@ -261,11 +246,9 @@ public:
#if QT_CONFIG(textcodec)
static QTextCodec* codec(MYSQL* mysql)
{
-#if MYSQL_VERSION_ID >= 32321
QTextCodec* heuristicCodec = QTextCodec::codecForName(mysql_character_set_name(mysql));
if (heuristicCodec)
return heuristicCodec;
-#endif
return QTextCodec::codecForLocale();
}
#endif // textcodec
@@ -350,8 +333,6 @@ static QSqlField qToField(MYSQL_FIELD *field, QTextCodec *tc)
return f;
}
-#if MYSQL_VERSION_ID >= 40108
-
static QSqlError qMakeStmtError(const QString& err, QSqlError::ErrorType type,
MYSQL_STMT* stmt)
{
@@ -445,7 +426,6 @@ bool QMYSQLResultPrivate::bindInValues()
}
return true;
}
-#endif
QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db)
: QSqlResult(*new QMYSQLResultPrivate(this, db))
@@ -460,11 +440,9 @@ QMYSQLResult::~QMYSQLResult()
QVariant QMYSQLResult::handle() const
{
Q_D(const QMYSQLResult);
-#if MYSQL_VERSION_ID >= 40108
if(d->preparedQuery)
return d->meta ? QVariant::fromValue(d->meta) : QVariant::fromValue(d->stmt);
else
-#endif
return QVariant::fromValue(d->result);
}
@@ -476,15 +454,12 @@ void QMYSQLResult::cleanup()
// must iterate trough leftover result sets from multi-selects or stored procedures
// if this isn't done subsequent queries will fail with "Commands out of sync"
-#if MYSQL_VERSION_ID >= 40100
while (driver() && d->drv_d_func()->mysql && mysql_next_result(d->drv_d_func()->mysql) == 0) {
MYSQL_RES *res = mysql_store_result(d->drv_d_func()->mysql);
if (res)
mysql_free_result(res);
}
-#endif
-#if MYSQL_VERSION_ID >= 40108
if (d->stmt) {
if (mysql_stmt_close(d->stmt))
qWarning("QMYSQLResult::cleanup: unable to free statement handle");
@@ -509,7 +484,6 @@ void QMYSQLResult::cleanup()
delete[] d->inBinds;
d->inBinds = 0;
}
-#endif
d->hasBlobs = false;
d->fields.clear();
@@ -536,7 +510,6 @@ bool QMYSQLResult::fetch(int i)
if (at() == i)
return true;
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
mysql_stmt_data_seek(d->stmt, i);
int nRC = mysql_stmt_fetch(d->stmt);
@@ -550,9 +523,6 @@ bool QMYSQLResult::fetch(int i)
"Unable to fetch data"), QSqlError::StatementError, d->stmt));
return false;
}
-#else
- return false;
-#endif
} else {
mysql_data_seek(d->result, i);
d->row = mysql_fetch_row(d->result);
@@ -570,7 +540,6 @@ bool QMYSQLResult::fetchNext()
if (!driver())
return false;
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
int nRC = mysql_stmt_fetch(d->stmt);
if (nRC) {
#ifdef MYSQL_DATA_TRUNCATED
@@ -582,9 +551,6 @@ bool QMYSQLResult::fetchNext()
"Unable to fetch data"), QSqlError::StatementError, d->stmt));
return false;
}
-#else
- return false;
-#endif
} else {
d->row = mysql_fetch_row(d->result);
if (!d->row)
@@ -607,11 +573,7 @@ bool QMYSQLResult::fetchLast()
my_ulonglong numRows;
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
numRows = mysql_stmt_num_rows(d->stmt);
-#else
- numRows = 0;
-#endif
} else {
numRows = mysql_num_rows(d->result);
}
@@ -788,11 +750,7 @@ int QMYSQLResult::size()
Q_D(const QMYSQLResult);
if (driver() && isSelect())
if (d->preparedQuery)
-#if MYSQL_VERSION_ID >= 40108
return mysql_stmt_num_rows(d->stmt);
-#else
- return -1;
-#endif
else
return int(mysql_num_rows(d->result));
else
@@ -821,11 +779,9 @@ QVariant QMYSQLResult::lastInsertId() const
return QVariant();
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
quint64 id = mysql_stmt_insert_id(d->stmt);
if (id)
return QVariant(id);
-#endif
} else {
quint64 id = mysql_insert_id(d->drv_d_func()->mysql);
if (id)
@@ -842,11 +798,7 @@ QSqlRecord QMYSQLResult::record() const
if (!isActive() || !isSelect() || !driver())
return info;
-#if MYSQL_VERSION_ID >= 40108
res = d->preparedQuery ? d->meta : d->result;
-#else
- res = d->result;
-#endif
if (!mysql_errno(d->drv_d_func()->mysql)) {
mysql_field_seek(res, 0);
@@ -865,7 +817,7 @@ bool QMYSQLResult::nextResult()
Q_D(QMYSQLResult);
if (!driver())
return false;
-#if MYSQL_VERSION_ID >= 40100
+
setAt(-1);
setActive(false);
@@ -908,9 +860,6 @@ bool QMYSQLResult::nextResult()
setActive(true);
return true;
-#else
- return false;
-#endif
}
void QMYSQLResult::virtual_hook(int id, void *data)
@@ -918,9 +867,6 @@ void QMYSQLResult::virtual_hook(int id, void *data)
QSqlResult::virtual_hook(id, data);
}
-
-#if MYSQL_VERSION_ID >= 40108
-
static MYSQL_TIME *toMySqlDate(QDate date, QTime time, QVariant::Type type)
{
Q_ASSERT(type == QVariant::Time || type == QVariant::Date
@@ -949,7 +895,7 @@ bool QMYSQLResult::prepare(const QString& query)
Q_D(QMYSQLResult);
if (!driver())
return false;
-#if MYSQL_VERSION_ID >= 40108
+
cleanup();
if (!d->drv_d_func()->preparedQuerysEnabled)
return QSqlResult::prepare(query);
@@ -983,9 +929,6 @@ bool QMYSQLResult::prepare(const QString& query)
setSelect(d->bindInValues());
d->preparedQuery = true;
return true;
-#else
- return false;
-#endif
}
bool QMYSQLResult::exec()
@@ -1155,7 +1098,7 @@ bool QMYSQLResult::exec()
setActive(true);
return true;
}
-#endif
+
/////////////////////////////////////////////////////////
static int qMySqlConnectionCount = 0;
@@ -1164,18 +1107,16 @@ static bool qMySqlInitHandledByUser = false;
static void qLibraryInit()
{
#ifndef Q_NO_MYSQL_EMBEDDED
-# if MYSQL_VERSION_ID >= 40000
if (qMySqlInitHandledByUser || qMySqlConnectionCount > 1)
return;
-# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
+# if MYSQL_VERSION_ID >= 50003
if (mysql_library_init(0, 0, 0)) {
# else
if (mysql_server_init(0, 0, 0)) {
# endif
qWarning("QMYSQLDriver::qServerInit: unable to start server.");
}
-# endif // MYSQL_VERSION_ID
#endif // Q_NO_MYSQL_EMBEDDED
#if defined(MARIADB_BASE_VERSION) || defined(MARIADB_VERSION_ID)
@@ -1187,12 +1128,10 @@ static void qLibraryEnd()
{
#if !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID)
# if !defined(Q_NO_MYSQL_EMBEDDED)
-# if MYSQL_VERSION_ID > 40000
-# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
- mysql_library_end();
-# else
- mysql_server_end();
-# endif
+# if MYSQL_VERSION_ID >= 50003
+ mysql_library_end();
+# else
+ mysql_server_end();
# endif
# endif
#endif
@@ -1271,17 +1210,9 @@ bool QMYSQLDriver::hasFeature(DriverFeature f) const
return true;
case PreparedQueries:
case PositionalPlaceholders:
-#if MYSQL_VERSION_ID >= 40108
return d->preparedQuerysEnabled;
-#else
- return false;
-#endif
case MultipleResultSets:
-#if MYSQL_VERSION_ID >= 40100
return true;
-#else
- return false;
-#endif
}
return false;
}
@@ -1322,7 +1253,7 @@ bool QMYSQLDriver::open(const QString& db,
we have to enable CLIEN_MULTI_STATEMENTS here, otherwise _any_
stored procedure call will fail.
*/
- unsigned int optionFlags = Q_CLIENT_MULTI_STATEMENTS;
+ unsigned int optionFlags = CLIENT_MULTI_STATEMENTS;
const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
QString unixSocket;
QString sslCert;
@@ -1330,12 +1261,10 @@ bool QMYSQLDriver::open(const QString& db,
QString sslKey;
QString sslCAPath;
QString sslCipher;
-#if MYSQL_VERSION_ID >= 50000
my_bool reconnect=false;
uint connectTimeout = 0;
uint readTimeout = 0;
uint writeTimeout = 0;
-#endif
// extract the real options from the string
for (int i = 0; i < opts.count(); ++i) {
@@ -1346,18 +1275,15 @@ bool QMYSQLDriver::open(const QString& db,
QString opt = tmp.left(idx).simplified();
if (opt == QLatin1String("UNIX_SOCKET"))
unixSocket = val;
-#if MYSQL_VERSION_ID >= 50000
else if (opt == QLatin1String("MYSQL_OPT_RECONNECT")) {
if (val == QLatin1String("TRUE") || val == QLatin1String("1") || val.isEmpty())
reconnect = true;
- } else if (opt == QLatin1String("MYSQL_OPT_CONNECT_TIMEOUT")) {
+ } else if (opt == QLatin1String("MYSQL_OPT_CONNECT_TIMEOUT"))
connectTimeout = val.toInt();
- } else if (opt == QLatin1String("MYSQL_OPT_READ_TIMEOUT")) {
+ else if (opt == QLatin1String("MYSQL_OPT_READ_TIMEOUT"))
readTimeout = val.toInt();
- } else if (opt == QLatin1String("MYSQL_OPT_WRITE_TIMEOUT")) {
+ else if (opt == QLatin1String("MYSQL_OPT_WRITE_TIMEOUT"))
writeTimeout = val.toInt();
- }
-#endif
else if (opt == QLatin1String("SSL_KEY"))
sslKey = val;
else if (opt == QLatin1String("SSL_CERT"))
@@ -1442,7 +1368,7 @@ bool QMYSQLDriver::open(const QString& db,
return false;
}
-#if (MYSQL_VERSION_ID >= 40113 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50007
+#if MYSQL_VERSION_ID >= 50007
if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
// force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
mysql_set_character_set(d->mysql, "utf8mb4");
@@ -1457,20 +1383,15 @@ bool QMYSQLDriver::open(const QString& db,
d->tc = codec(d->mysql);
#endif
}
-#endif
+#endif // MYSQL_VERSION_ID >= 50007
-#if MYSQL_VERSION_ID >= 40108
d->preparedQuerysEnabled = mysql_get_client_version() >= 40108
&& mysql_get_server_version(d->mysql) >= 40100;
-#else
- d->preparedQuerysEnabled = false;
-#endif
#if QT_CONFIG(thread)
mysql_thread_init();
#endif
-
setOpen(true);
setOpenError(false);
return true;
@@ -1499,46 +1420,21 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const
{
Q_D(const QMYSQLDriver);
QStringList tl;
-#if MYSQL_VERSION_ID >= 40100
- if( mysql_get_server_version(d->mysql) < 50000)
- {
-#endif
- if (!isOpen())
- return tl;
- if (!(type & QSql::Tables))
- return tl;
-
- MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL);
- MYSQL_ROW row;
- int i = 0;
- while (tableRes) {
- mysql_data_seek(tableRes, i);
- row = mysql_fetch_row(tableRes);
- if (!row)
- break;
- tl.append(toUnicode(d->tc, row[0]));
- i++;
- }
- mysql_free_result(tableRes);
-#if MYSQL_VERSION_ID >= 40100
- } else {
- QSqlQuery q(createResult());
- if(type & QSql::Tables) {
- QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'");
- q.exec(sql);
+ QSqlQuery q(createResult());
+ if (type & QSql::Tables) {
+ QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'");
+ q.exec(sql);
- while(q.next())
- tl.append(q.value(0).toString());
- }
- if(type & QSql::Views) {
- QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'");
- q.exec(sql);
+ while (q.next())
+ tl.append(q.value(0).toString());
+ }
+ if (type & QSql::Views) {
+ QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'");
+ q.exec(sql);
- while(q.next())
- tl.append(q.value(0).toString());
- }
+ while (q.next())
+ tl.append(q.value(0).toString());
}
-#endif
return tl;
}
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 0bae45382d..b85a1ac4c7 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -428,12 +428,14 @@ static QVariant::Type qDecodePSQLType(int t)
void QPSQLResultPrivate::deallocatePreparedStmt()
{
- const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId;
- PGresult *result = drv_d_func()->exec(stmt);
+ if (drv_d_func()) {
+ const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId;
+ PGresult *result = drv_d_func()->exec(stmt);
- if (PQresultStatus(result) != PGRES_COMMAND_OK)
- qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection));
- PQclear(result);
+ if (PQresultStatus(result) != PGRES_COMMAND_OK)
+ qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection));
+ PQclear(result);
+ }
preparedStmtId.clear();
}
@@ -810,8 +812,8 @@ QSqlRecord QPSQLResult::record() const
return info;
int count = PQnfields(d->result);
+ QSqlField f;
for (int i = 0; i < count; ++i) {
- QSqlField f;
if (d->drv_d_func()->isUtf8)
f.setName(QString::fromUtf8(PQfname(d->result, i)));
else
@@ -831,6 +833,8 @@ QSqlRecord QPSQLResult::record() const
}
}
f.setTableName(tableName);
+ } else {
+ f.setTableName(QString());
}
int ptype = PQftype(d->result, i);
f.setType(qDecodePSQLType(ptype));
@@ -1690,7 +1694,12 @@ void QPSQLDriver::_q_handleNotification(int)
if (notify->extra)
payload = d->isUtf8 ? QString::fromUtf8(notify->extra) : QString::fromLatin1(notify->extra);
#endif
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit notification(name);
+QT_WARNING_POP
+#endif
QSqlDriver::NotificationSource source = (notify->be_pid == PQbackendPID(d->connection)) ? QSqlDriver::SelfSource : QSqlDriver::OtherSource;
emit notification(name, source, payload);
}
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index 001bd673fc..65d3f0a580 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -1044,7 +1044,12 @@ void QSQLiteDriver::handleNotification(const QString &tableName, qint64 rowid)
{
Q_D(const QSQLiteDriver);
if (d->notificationid.contains(tableName)) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit notification(tableName);
+QT_WARNING_POP
+#endif
emit notification(tableName, QSqlDriver::UnknownSource, QVariant(rowid));
}
}
diff --git a/src/plugins/styles/android/qandroidstyle.cpp b/src/plugins/styles/android/qandroidstyle.cpp
index 086df92322..1d0838daec 100644
--- a/src/plugins/styles/android/qandroidstyle.cpp
+++ b/src/plugins/styles/android/qandroidstyle.cpp
@@ -248,7 +248,7 @@ QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::PrimitiveElement primit
case QStyle::PE_FrameLineEdit:
return QC_EditText;
- case QStyle::PE_IndicatorViewItemCheck:
+ case QStyle::PE_IndicatorItemViewItemCheck:
case QStyle::PE_IndicatorCheckBox:
return QC_Checkbox;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index ec3bb91ebf..7fa330beab 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -328,6 +328,20 @@ static const int closeButtonSize = 14;
static const qreal closeButtonCornerRadius = 2.0;
#endif // QT_CONFIG(tabbar)
+#ifndef QT_NO_ACCESSIBILITY // This ifdef to avoid "unused function" warning.
+QBrush brushForToolButton(bool isOnKeyWindow)
+{
+ // When a toolbutton in a toolbar is in the 'ON' state, we draw a
+ // partially transparent background. The colors must be different
+ // for 'Aqua' and 'DarkAqua' appearances though.
+ if (isDarkMode())
+ return isOnKeyWindow ? QColor(73, 73, 73, 100) : QColor(56, 56, 56, 100);
+
+ return isOnKeyWindow ? QColor(0, 0, 0, 28) : QColor(0, 0, 0, 21);
+}
+#endif // QT_NO_ACCESSIBILITY
+
+
static const int headerSectionArrowHeight = 6;
static const int headerSectionSeparatorInset = 2;
@@ -555,10 +569,10 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
newRot = -90;
}
tabRect.setRect(0, 0, tabRect.height(), tabRect.width());
- QMatrix m;
- m.translate(newX, newY);
- m.rotate(newRot);
- p->setMatrix(m, true);
+ QTransform transform;
+ transform.translate(newX, newY);
+ transform.rotate(newRot);
+ p->setTransform(transform, true);
}
return tabRect;
}
@@ -2951,24 +2965,24 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
}
#endif
- QMatrix matrix;
- matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
+ QTransform transform;
+ transform.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
QPainterPath path;
switch(pe) {
default:
case PE_IndicatorArrowDown:
break;
case PE_IndicatorArrowUp:
- matrix.rotate(180);
+ transform.rotate(180);
break;
case PE_IndicatorArrowLeft:
- matrix.rotate(90);
+ transform.rotate(90);
break;
case PE_IndicatorArrowRight:
- matrix.rotate(-90);
+ transform.rotate(-90);
break;
}
- p->setMatrix(matrix);
+ p->setTransform(transform);
path.moveTo(-halfSize, -halfSize * 0.5);
path.lineTo(0.0, halfSize * 0.5);
@@ -3211,7 +3225,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
CGContextRestoreGState(cg);
break; }
- case PE_IndicatorViewItemCheck:
+ case PE_IndicatorItemViewItemCheck:
case PE_IndicatorRadioButton:
case PE_IndicatorCheckBox: {
const bool isEnabled = opt->state & State_Enabled;
@@ -3462,6 +3476,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
{
Q_D(const QMacStyle);
const AppearanceSync sync;
+ const QMacAutoReleasePool pool;
QMacCGContext cg(p);
QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr;
d->resolveCurrentNSView(window);
@@ -4326,7 +4341,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
break;
case CE_ProgressBarContents:
if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- QMacAutoReleasePool pool;
const bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0);
const bool vertical = pb->orientation == Qt::Vertical;
const bool inverted = pb->invertedAppearance;
@@ -5603,8 +5617,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
if (view)
isKey = [view.window isKeyWindow];
- QBrush brush(isKey ? QColor(0, 0, 0, 28)
- : QColor(0, 0, 0, 21));
+ QBrush brush(brushForToolButton(isKey));
QPainterPath path;
path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4);
p->setRenderHint(QPainter::Antialiasing);
diff --git a/src/plugins/styles/windowsvista/main.cpp b/src/plugins/styles/windowsvista/main.cpp
index d5048e45b7..5e7bcf5e6e 100644
--- a/src/plugins/styles/windowsvista/main.cpp
+++ b/src/plugins/styles/windowsvista/main.cpp
@@ -48,7 +48,7 @@ class QWindowsVistaStylePlugin : public QStylePlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "windowsvistastyle.json")
public:
- QStyle *create(const QString &key);
+ QStyle *create(const QString &key) override;
};
QStyle *QWindowsVistaStylePlugin::create(const QString &key)
@@ -56,7 +56,7 @@ QStyle *QWindowsVistaStylePlugin::create(const QString &key)
if (key.compare(QLatin1String("windowsvista"), Qt::CaseInsensitive) == 0)
return new QWindowsVistaStyle();
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
index c4ada66ca9..e213d65946 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
@@ -44,7 +44,6 @@
#include <qwindow.h>
#include <private/qstyleanimation_p.h>
#include <private/qstylehelper_p.h>
-#include <private/qapplication_p.h>
#include <qpa/qplatformnativeinterface.h>
QT_BEGIN_NAMESPACE
@@ -84,15 +83,14 @@ static const int windowsRightBorder = 15; // right border on windows
*/
bool QWindowsVistaStylePrivate::useVista()
{
- return QOperatingSystemVersion::current() >= QOperatingSystemVersion::WindowsVista
- && QWindowsVistaStylePrivate::useXP();
+ return QWindowsVistaStylePrivate::useXP();
}
/* \internal
Checks and returns the style object
*/
inline QObject *styleObject(const QStyleOption *option) {
- return option ? option->styleObject : 0;
+ return option ? option->styleObject : nullptr;
}
/* \internal
@@ -117,7 +115,7 @@ static inline QImage createAnimationBuffer(const QStyleOption *option, const QWi
Used by animations to clone a styleoption and shift its offset
*/
QStyleOption *clonedAnimationStyleOption(const QStyleOption*option) {
- QStyleOption *styleOption = 0;
+ QStyleOption *styleOption = nullptr;
if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option))
styleOption = new QStyleOptionSlider(*slider);
else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option))
@@ -298,7 +296,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
int oldState = styleObject->property("_q_stylestate").toInt();
oldRect = styleObject->property("_q_stylerect").toRect();
newRect = option->rect;
- styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylestate", int(option->state));
styleObject->setProperty("_q_stylerect", option->rect);
bool doTransition = oldState &&
@@ -316,7 +314,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
if (doTransition) {
QStyleOption *styleOption = clonedAnimationStyleOption(option);
- styleOption->state = (QStyle::State)oldState;
+ styleOption->state = QStyle::State(oldState);
QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
@@ -341,7 +339,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
// The end state of the transition is simply the result we would have painted
// if the style was not animated.
- styleOption->styleObject = 0;
+ styleOption->styleObject = nullptr;
styleOption->state = option->state;
proxy()->drawPrimitive(element, styleOption, &endPainter, widget);
@@ -356,7 +354,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
//translate state flags to UXTHEME states :
if (element == PE_FrameLineEdit) {
- theme = OpenThemeData(0, L"Edit");
+ theme = OpenThemeData(nullptr, L"Edit");
partId = EP_EDITBORDER_NOSCROLL;
if (oldState & State_MouseOver)
@@ -374,7 +372,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
toState = ETS_NORMAL;
} else {
- theme = OpenThemeData(0, L"Button");
+ theme = OpenThemeData(nullptr, L"Button");
if (element == PE_IndicatorRadioButton)
partId = BP_RADIOBUTTON;
else if (element == PE_IndicatorCheckBox)
@@ -390,7 +388,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
if (theme
&& SUCCEEDED(GetThemeTransitionDuration(theme, partId, fromState, toState,
TMT_TRANSITIONDURATIONS, &duration))) {
- t->setDuration(duration);
+ t->setDuration(int(duration));
}
t->setStartTime(QTime::currentTime());
@@ -535,7 +533,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
else if (state & State_MouseOver)
stateId = EBS_HOT;
- XPThemeData theme(0, painter, QWindowsXPStylePrivate::EditTheme,
+ XPThemeData theme(nullptr, painter, QWindowsXPStylePrivate::EditTheme,
partId, stateId, rect);
if (!theme.isValid()) {
QWindowsStyle::drawPrimitive(element, option, painter, widget);
@@ -582,27 +580,26 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
p->drawRect(option->rect.adjusted(0, 0, -1, -1));
p->setPen(oldPen);
return;
- } else {
- int stateId = ETS_NORMAL;
- if (!(state & State_Enabled))
- stateId = ETS_DISABLED;
- else if (state & State_ReadOnly)
- stateId = ETS_READONLY;
- else if (state & State_MouseOver)
- stateId = ETS_HOT;
- else if (state & State_HasFocus)
- stateId = ETS_SELECTED;
- XPThemeData theme(widget, painter,
- QWindowsXPStylePrivate::EditTheme,
- EP_EDITBORDER_NOSCROLL, stateId, option->rect);
- theme.noContent = true;
- painter->save();
- QRegion clipRegion = option->rect;
- clipRegion -= option->rect.adjusted(2, 2, -2, -2);
- painter->setClipRegion(clipRegion);
- d->drawBackground(theme);
- painter->restore();
}
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = ETS_READONLY;
+ else if (state & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter,
+ QWindowsXPStylePrivate::EditTheme,
+ EP_EDITBORDER_NOSCROLL, stateId, option->rect);
+ theme.noContent = true;
+ painter->save();
+ QRegion clipRegion = option->rect;
+ clipRegion -= option->rect.adjusted(2, 2, -2, -2);
+ painter->setClipRegion(clipRegion);
+ d->drawBackground(theme);
+ painter->restore();
}
break;
@@ -725,7 +722,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
d->drawBackground(theme);
} else {
QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
- break;;
+ break;
}
QPixmapCache::insert(key, pixmap);
}
@@ -771,7 +768,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
case PE_Widget:
{
#if QT_CONFIG(dialogbuttonbox)
- const QDialogButtonBox *buttonBox = 0;
+ const QDialogButtonBox *buttonBox = nullptr;
if (qobject_cast<const QMessageBox *> (widget))
buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
@@ -845,7 +842,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int oldState = styleObject->property("_q_stylestate").toInt();
oldRect = styleObject->property("_q_stylerect").toRect();
newRect = option->rect;
- styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylestate", int(option->state));
styleObject->setProperty("_q_stylerect", option->rect);
bool wasDefault = false;
@@ -871,7 +868,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
QStyleOption *styleOption = clonedAnimationStyleOption(option);
- styleOption->state = (QStyle::State)oldState;
+ styleOption->state = QStyle::State(oldState);
QImage startImage = createAnimationBuffer(option, widget);
QPainter startPainter(&startImage);
@@ -893,12 +890,12 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
DWORD duration = 0;
- const HTHEME theme = OpenThemeData(0, L"Button");
+ const HTHEME theme = OpenThemeData(nullptr, L"Button");
int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
int toState = buttonStateId(option->state, BP_PUSHBUTTON);
if (GetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
- t->setDuration(duration);
+ t->setDuration(int(duration));
else
t->setDuration(0);
t->setStartTime(QTime::currentTime());
@@ -984,7 +981,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (btn->features & QStyleOptionButton::HasMenu) {
int mbiw = 0, mbih = 0;
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ToolBarTheme,
TP_DROPDOWNBUTTON);
if (theme.isValid()) {
const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1, option);
@@ -993,7 +990,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
mbih = qRound(size.height());
}
}
- QRect ir = subElementRect(SE_PushButtonContents, option, 0);
+ QRect ir = subElementRect(SE_PushButtonContents, option, nullptr);
QStyleOptionButton newBtn = *btn;
newBtn.rect = QStyle::visualRect(option->direction, option->rect,
QRect(ir.right() - mbiw - 2,
@@ -1138,7 +1135,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
- uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
alignment |= Qt::TextHideMnemonic;
@@ -1178,7 +1175,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int checkcol = qRound(qreal(25) * factor);
const int gutterWidth = qRound(qreal(3) * factor);
{
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme,
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::MenuTheme,
MENU_POPUPCHECKBACKGROUND, MBI_HOT);
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
@@ -1395,7 +1392,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
- bool isFloating = dw != 0 && dw->isFloating();
+ bool isFloating = dw && dw->isFloating();
QRect r = option->rect.adjusted(0, 2, -1, -3);
QRect titleRect = r;
@@ -1412,7 +1409,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (isFloating) {
titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ if (widget && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
} else {
titleRect.adjust(mw, 0, 0, 0);
@@ -1518,8 +1515,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
int oldActiveControls = styleObject->property("_q_stylecontrols").toInt();
QRect oldRect = styleObject->property("_q_stylerect").toRect();
- styleObject->setProperty("_q_stylestate", (int)option->state);
- styleObject->setProperty("_q_stylecontrols", (int)option->activeSubControls);
+ styleObject->setProperty("_q_stylestate", int(option->state));
+ styleObject->setProperty("_q_stylecontrols", int(option->activeSubControls));
styleObject->setProperty("_q_stylerect", option->rect);
bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
@@ -1563,8 +1560,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
// Draw transition source
if (!anim) {
- styleOption->state = (QStyle::State)oldState;
- styleOption->activeSubControls = (QStyle::SubControl)oldActiveControls;
+ styleOption->state = QStyle::State(oldState);
+ styleOption->activeSubControls = QStyle::SubControl(oldActiveControls);
proxy()->drawComplexControl(control, styleOption, &startPainter, widget);
} else {
anim->paint(&startPainter, option);
@@ -1815,7 +1812,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
// That however breaks with QtQuickControls where this results in transparent
// spinbox background, so if there's no "widget" passed (QtQuickControls case),
// let ftheme.noContent be false, which fixes the spinbox rendering in QQC
- ftheme.noContent = (widget != NULL);
+ ftheme.noContent = (widget != nullptr);
d->drawBackground(ftheme);
}
if (sub & SC_SpinBoxUp) {
@@ -1872,7 +1869,7 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption
sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
int minimumHeight;
{
- XPThemeData theme(widget, 0,
+ XPThemeData theme(widget, nullptr,
QWindowsXPStylePrivate::MenuTheme,
MENU_POPUPCHECKBACKGROUND, MBI_HOT);
XPThemeData themeSize = theme;
@@ -1940,7 +1937,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
case SE_PushButtonContents:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
MARGINS borderSize;
- const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
+ const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"Button");
if (theme) {
int stateId = PBS_NORMAL;
if (!(option->state & State_Enabled))
@@ -1955,7 +1952,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
rect = option->rect.adjusted(border, border, -border, -border);
- if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) {
+ if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) {
rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
-borderSize.cxRightWidth, -borderSize.cyBottomHeight);
rect = visualRect(option->direction, option->rect, rect);
@@ -1973,7 +1970,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
int y = option->rect.y();
int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
- XPThemeData theme(widget, 0,
+ XPThemeData theme(widget, nullptr,
QWindowsXPStylePrivate::HeaderTheme,
HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
@@ -2046,7 +2043,7 @@ static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBa
bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
- const uint flags = tb->titleBarFlags;
+ const auto flags = tb->titleBarFlags;
bool retVal = false;
switch (sc) {
case QStyle::SC_TitleBarContextHelpButton:
@@ -2104,7 +2101,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
if (option) {
if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
ret = true;
- XPThemeData themeData(widget, 0,
+ XPThemeData themeData(widget, nullptr,
QWindowsXPStylePrivate::ToolTipTheme,
TTP_STANDARD, TTSS_NORMAL, option->rect);
mask->region = d->region(themeData);
@@ -2113,7 +2110,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
break;
case SH_Table_GridLineColor:
if (option)
- ret = option->palette.color(QPalette::Base).darker(118).rgb();
+ ret = int(option->palette.color(QPalette::Base).darker(118).rgb());
else
ret = -1;
break;
@@ -2324,7 +2321,7 @@ void QWindowsVistaStyle::polish(QWidget *widget)
//we do not have to care about unpolishing
widget->setContentsMargins(3, 0, 4, 0);
COLORREF bgRef;
- HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
+ HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"TOOLTIP");
if (theme && SUCCEEDED(GetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef))) {
QColor textColor = QColor::fromRgb(bgRef);
QPalette pal;
@@ -2464,7 +2461,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon,
switch(standardIcon) {
case SP_CommandLink:
{
- XPThemeData theme(0, 0,
+ XPThemeData theme(nullptr, nullptr,
QWindowsXPStylePrivate::ButtonTheme,
BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
if (theme.isValid()) {
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
index d66b17e9f8..8fef9f9927 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
@@ -162,7 +162,7 @@ class QWindowsVistaAnimation : public QBlendStyleAnimation
public:
QWindowsVistaAnimation(Type type, QObject *target) : QBlendStyleAnimation(type, target) { }
- virtual bool isUpdateNeeded() const;
+ bool isUpdateNeeded() const override;
void paint(QPainter *painter, const QStyleOption *option);
};
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index e2c5bdc924..bf80138b32 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -117,7 +117,7 @@ static inline QBackingStore *backingStoreForWidget(const QWidget *widget)
if (const QWidget *topLevel = widget->nativeParentWidget())
if (QBackingStore *topLevelBackingStore = topLevel->backingStore())
return topLevelBackingStore;
- return 0;
+ return nullptr;
}
static inline HDC hdcForWidgetBackingStore(const QWidget *widget)
@@ -127,7 +127,7 @@ static inline HDC hdcForWidgetBackingStore(const QWidget *widget)
if (nativeInterface)
return static_cast<HDC>(nativeInterface->nativeResourceForBackingStore(QByteArrayLiteral("getDC"), backingStore));
}
- return 0;
+ return nullptr;
}
// Theme data helper ------------------------------------------------------------------------------
@@ -148,7 +148,7 @@ bool XPThemeData::isValid()
HTHEME XPThemeData::handle()
{
if (!QWindowsXPStylePrivate::useXP())
- return 0;
+ return nullptr;
if (!htheme)
htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(widget));
@@ -175,10 +175,10 @@ RECT XPThemeData::toRECT(const QRect &qr)
HRGN XPThemeData::mask(QWidget *widget)
{
if (!IsThemeBackgroundPartiallyTransparent(handle(), partId, stateId))
- return 0;
+ return nullptr;
HRGN hrgn;
- HDC dc = 0;
+ HDC dc = nullptr;
if (widget)
dc = hdcForWidgetBackingStore(widget);
RECT nativeRect = toRECT(rect);
@@ -188,7 +188,7 @@ HRGN XPThemeData::mask(QWidget *widget)
// QWindowsXPStylePrivate -------------------------------------------------------------------------
// Static initializations
-HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = 0;
+HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = nullptr;
HTHEME QWindowsXPStylePrivate::m_themes[NThemes];
bool QWindowsXPStylePrivate::use_xp = false;
QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
@@ -227,7 +227,7 @@ bool QWindowsXPStylePrivate::useXP(bool update)
{
if (!update)
return use_xp;
- return use_xp = IsThemeActive() && (IsAppThemed() || !QApplication::instance());
+ return use_xp = IsThemeActive() && (IsAppThemed() || !QCoreApplication::instance());
}
/* \internal
@@ -241,7 +241,7 @@ void QWindowsXPStylePrivate::init(bool force)
ref.ref();
useXP(true);
- std::fill(m_themes, m_themes + NThemes, HTHEME(0));
+ std::fill(m_themes, m_themes + NThemes, nullptr);
}
/* \internal
@@ -253,12 +253,12 @@ void QWindowsXPStylePrivate::cleanup(bool force)
if (bufferDC && nullBitmap)
SelectObject(bufferDC, nullBitmap);
DeleteObject(bufferBitmap);
- bufferBitmap = 0;
+ bufferBitmap = nullptr;
}
if(bufferDC)
DeleteDC(bufferDC);
- bufferDC = 0;
+ bufferDC = nullptr;
if (ref.deref() && !force)
return;
@@ -282,7 +282,7 @@ void QWindowsXPStylePrivate::cleanup(bool force)
static inline HWND createTreeViewHelperWindow()
{
if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) {
- void *hwnd = 0;
+ void *hwnd = nullptr;
void *wndProc = reinterpret_cast<void *>(DefWindowProc);
if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection,
Q_RETURN_ARG(void*, hwnd),
@@ -292,7 +292,7 @@ static inline HWND createTreeViewHelperWindow()
return reinterpret_cast<HWND>(hwnd);
}
}
- return 0;
+ return nullptr;
}
bool QWindowsXPStylePrivate::initVistaTreeViewTheming()
@@ -305,7 +305,7 @@ bool QWindowsXPStylePrivate::initVistaTreeViewTheming()
qWarning("Unable to create the treeview helper window.");
return false;
}
- if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", NULL))) {
+ if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", nullptr))) {
qErrnoWarning("SetWindowTheme() failed.");
cleanupVistaTreeViewTheming();
return false;
@@ -317,7 +317,7 @@ void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming()
{
if (m_vistaTreeViewHelper) {
DestroyWindow(m_vistaTreeViewHelper);
- m_vistaTreeViewHelper = 0;
+ m_vistaTreeViewHelper = nullptr;
}
}
@@ -328,11 +328,12 @@ void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming()
*/
void QWindowsXPStylePrivate::cleanupHandleMap()
{
- for (int i = 0; i < NThemes; ++i)
- if (m_themes[i]) {
- CloseThemeData(m_themes[i]);
- m_themes[i] = 0;
+ for (auto &theme : m_themes) {
+ if (theme) {
+ CloseThemeData(theme);
+ theme = nullptr;
}
+ }
QWindowsXPStylePrivate::cleanupVistaTreeViewTheming();
}
@@ -340,7 +341,7 @@ HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd)
{
if (Q_UNLIKELY(theme < 0 || theme >= NThemes || !hwnd)) {
qWarning("Invalid parameters #%d, %p", theme, hwnd);
- return 0;
+ return nullptr;
}
if (!m_themes[theme]) {
const wchar_t *name = themeNames[theme];
@@ -427,16 +428,16 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
if (bufferDC && nullBitmap)
SelectObject(bufferDC, nullBitmap);
DeleteObject(bufferBitmap);
- bufferBitmap = 0;
+ bufferBitmap = nullptr;
}
w = qMax(bufferW, w);
h = qMax(bufferH, h);
if (!bufferDC) {
- HDC displayDC = GetDC(0);
+ HDC displayDC = GetDC(nullptr);
bufferDC = CreateCompatibleDC(displayDC);
- ReleaseDC(0, displayDC);
+ ReleaseDC(nullptr, displayDC);
}
// Define the header
@@ -450,22 +451,22 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
bmi.bmiHeader.biCompression = BI_RGB;
// Create the pixmap
- bufferPixels = 0;
- bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
+ bufferPixels = nullptr;
+ bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&bufferPixels), nullptr, 0);
GdiFlush();
- nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
+ nullBitmap = static_cast<HBITMAP>(SelectObject(bufferDC, bufferBitmap));
if (Q_UNLIKELY(!bufferBitmap)) {
qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h);
bufferW = 0;
bufferH = 0;
- return 0;
+ return nullptr;
}
if (Q_UNLIKELY(!bufferPixels)) {
qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h);
bufferW = 0;
bufferH = 0;
- return 0;
+ return nullptr;
}
bufferW = w;
bufferH = h;
@@ -493,7 +494,7 @@ bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
*/
QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
{
- HRGN hRgn = 0;
+ HRGN hRgn = nullptr;
const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(themeData.widget);
RECT rect = themeData.toRECT(QRect(themeData.rect.topLeft() / factor, themeData.rect.size() / factor));
if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
@@ -502,12 +503,12 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
}
HRGN dest = CreateRectRgn(0, 0, 0, 0);
- const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
+ const bool success = CombineRgn(dest, hRgn, nullptr, RGN_COPY) != ERROR;
QRegion region;
if (success) {
- int numBytes = GetRegionData(dest, 0, 0);
+ const auto numBytes = GetRegionData(dest, 0, nullptr);
if (numBytes == 0)
return QRegion();
@@ -551,7 +552,7 @@ bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect)
int firstAlpha = -1;
for (int y = startY; y < h/2; ++y) {
- DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ auto buffer = reinterpret_cast<const DWORD *>(bufferPixels) + (y * bufferW);
for (int x = startX; x < w; ++x, ++buffer) {
int alpha = (*buffer) >> 24;
if (firstAlpha == -1)
@@ -580,7 +581,7 @@ bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect)
bool hasFixedAlphaValue = false;
for (int y = startY; y < h; ++y) {
- DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW);
for (int x = startX; x < w; ++x, ++buffer) {
uint pixel = *buffer;
int alpha = qAlpha(pixel);
@@ -612,7 +613,7 @@ bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
// Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
for (int y = startY; y < h; ++y) {
- DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW);
for (int x = startX; x < w; ++x, ++buffer) {
if (allPixels) {
*buffer |= 0xFF000000;
@@ -668,7 +669,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
return true;
QPainter *painter = themeData.painter;
- Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
+ Q_ASSERT_X(painter != nullptr, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
if (!painter || !painter->isActive())
return false;
@@ -706,7 +707,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
}
}
- const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0);
+ const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : nullptr;
const bool result = dc
? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio)
: drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio);
@@ -740,7 +741,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
{
QPainter *painter = themeData.painter;
- const auto deviceTransform = painter->deviceTransform();
+ const auto &deviceTransform = painter->deviceTransform();
const QPointF redirectionDelta(deviceTransform.dx(), deviceTransform.dy());
const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect();
@@ -771,7 +772,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
| (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
const HRESULT result = DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
- SelectClipRgn(dc, 0);
+ SelectClipRgn(dc, nullptr);
DeleteObject(hrgn);
return SUCCEEDED(result);
}
@@ -1099,9 +1100,7 @@ QWindowsXPStyle::QWindowsXPStyle()
/*!
Destroys the style.
*/
-QWindowsXPStyle::~QWindowsXPStyle()
-{
-}
+QWindowsXPStyle::~QWindowsXPStyle() = default;
/*! \reimp */
void QWindowsXPStyle::unpolish(QApplication *app)
@@ -1157,7 +1156,7 @@ void QWindowsXPStyle::polish(QWidget *widget)
if (!d->hasInitColors) {
// Get text color for group box labels
COLORREF cref;
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0);
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, 0, 0);
GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
@@ -1270,7 +1269,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option,
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
MARGINS borderSize;
if (widget) {
- XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme);
+ XPThemeData buttontheme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme);
HTHEME theme = buttontheme.handle();
if (theme) {
int stateId;
@@ -1288,7 +1287,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option,
int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
rect = option->rect.adjusted(border, border, -border, -border);
- if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) {
+ if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) {
rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
-borderSize.cxRightWidth, -borderSize.cyBottomHeight);
rect = visualRect(option->direction, option->rect, rect);
@@ -1468,7 +1467,7 @@ case PE_Frame:
return;
themeNumber = QWindowsXPStylePrivate::ListViewTheme;
partId = LVP_LISTGROUP;
- XPThemeData theme(widget, 0, themeNumber, partId, 0);
+ XPThemeData theme(widget, nullptr, themeNumber, partId);
if (!(flags & State_Enabled))
stateId = ETS_DISABLED;
@@ -1496,9 +1495,9 @@ case PE_Frame:
p->drawRect(QRectF(option->rect).adjusted(0, 0, -topLevelAdjustment, -topLevelAdjustment));
p->setPen(oldPen);
return;
- } else if (fillType == BT_NONE) {
- return;
}
+ if (fillType == BT_NONE)
+ return;
}
break;
}
@@ -1514,7 +1513,8 @@ case PE_Frame:
p->drawRect(option->rect.adjusted(0, 0, -1, -1));
p->setPen(oldPen);
return;
- } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ }
+ if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
themeNumber = QWindowsXPStylePrivate::EditTheme;
partId = EP_EDITTEXT;
noContent = true;
@@ -1538,7 +1538,7 @@ case PE_Frame:
if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) {
p->fillRect(panel->rect, panel->palette.brush(QPalette::Base));
} else {
- XPThemeData theme(0, p, themeNumber, partId, stateId, rect);
+ XPThemeData theme(nullptr, p, themeNumber, partId, stateId, rect);
if (!theme.isValid()) {
QWindowsStyle::drawPrimitive(pe, option, p, widget);
return;
@@ -1587,9 +1587,9 @@ case PE_Frame:
wchar_t themeFileName[maxlength];
wchar_t themeColor[maxlength];
// Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
- if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
- wchar_t *offset = 0;
- if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
+ if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, nullptr, 0) == S_OK) {
+ wchar_t *offset = nullptr;
+ if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != nullptr) {
offset++;
if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
useGradient = false;
@@ -1820,7 +1820,7 @@ case PE_Frame:
bef_v -= delta;
aft_h += delta;
aft_v += delta;
- XPThemeData theme(0, p, QWindowsXPStylePrivate::XpTreeViewTheme);
+ XPThemeData theme(nullptr, p, QWindowsXPStylePrivate::XpTreeViewTheme);
theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
theme.partId = TVP_GLYPH;
theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
@@ -1912,7 +1912,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
{
themeNumber = QWindowsXPStylePrivate::StatusTheme;
partId = SP_GRIPPER;
- XPThemeData theme(0, p, themeNumber, partId, 0);
+ XPThemeData theme(nullptr, p, themeNumber, partId);
QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
size.rheight()--;
if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
@@ -1980,7 +1980,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
if (btn->features & QStyleOptionButton::HasMenu) {
int mbiw = 0, mbih = 0;
- XPThemeData theme(widget, 0,
+ XPThemeData theme(widget, nullptr,
QWindowsXPStylePrivate::ToolBarTheme,
TP_SPLITBUTTONDROPDOWN);
if (theme.isValid()) {
@@ -2309,7 +2309,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
if (isFloating) {
titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ if (widget != nullptr && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
} else {
titleRect.adjust(mw, 0, 0, 0);
@@ -2775,7 +2775,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
break;
v = nextInterval;
}
- if (lines.size() > 0) {
+ if (!lines.isEmpty()) {
p->save();
p->translate(slrect.topLeft());
p->drawLines(lines.constData(), lines.size());
@@ -2923,7 +2923,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
p->save();
p->setClipRect(menuarea);
tool.rect = option->rect;
- proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0);
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, nullptr);
p->restore();
}
// Draw arrow
@@ -3223,7 +3223,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
}
}
-static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = 0)
+static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = nullptr)
{
if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option))
return pb->orientation;
@@ -3234,27 +3234,27 @@ int QWindowsXPStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, cons
{
switch (pm) {
case QStyle::PM_IndicatorWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width();
case QStyle::PM_IndicatorHeight:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height();
case QStyle::PM_ExclusiveIndicatorWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width();
case QStyle::PM_ExclusiveIndicatorHeight:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height();
case QStyle::PM_ProgressBarChunkWidth:
return progressBarOrientation(option) == Qt::Horizontal
- ? XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width()
- : XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height();
+ ? XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width()
+ : XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height();
case QStyle::PM_SliderThickness:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height();
case QStyle::PM_TitleBarHeight:
return widget && (widget->windowType() == Qt::Tool)
? GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME)
: GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
case QStyle::PM_MdiSubWindowFrameWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width();
case QStyle::PM_DockWidgetFrameWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width();
default:
break;
}
@@ -3620,7 +3620,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
case CT_LineEdit:
case CT_ComboBox:
{
- XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL);
+ XPThemeData buttontheme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL);
if (buttontheme.isValid()) {
const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget);
const QMarginsF borderSize = buttontheme.margins() * factor;
@@ -3741,11 +3741,11 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
titleBarRect.setHeight(tbHeight);
XPThemeData themeData;
if (titlebar->titleBarState & Qt::WindowMinimized) {
- themeData = XPThemeData(widget, 0,
+ themeData = XPThemeData(widget, nullptr,
QWindowsXPStylePrivate::WindowTheme,
WP_MINCAPTION, CS_ACTIVE, titleBarRect);
} else
- themeData = XPThemeData(widget, 0,
+ themeData = XPThemeData(widget, nullptr,
QWindowsXPStylePrivate::WindowTheme,
WP_CAPTION, CS_ACTIVE, titleBarRect);
mask->region = d->region(themeData) +
@@ -3774,10 +3774,8 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
/*! \reimp */
QPalette QWindowsXPStyle::standardPalette() const
{
- if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal)
- return *QApplicationPrivate::sys_pal;
- else
- return QWindowsStyle::standardPalette();
+ return QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal
+ ? *QApplicationPrivate::sys_pal : QWindowsStyle::standardPalette();
}
/*!
@@ -3795,7 +3793,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (widget && widget->isWindow()) {
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size);
@@ -3826,9 +3824,9 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (d->dockFloat.isNull()) {
- XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_MAXBUTTON, MAXBS_NORMAL);
if (theme.isValid()) {
const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
@@ -3862,7 +3860,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (d->dockClose.isNull()) {
- XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
@@ -3896,9 +3894,9 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (d->dockFloat.isNull()) {
- XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_RESTOREBUTTON, RBS_NORMAL);
if (theme.isValid()) {
const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
index 60f9d7e9b7..ad7754e3d4 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
@@ -100,11 +100,11 @@ class QDebug;
class XPThemeData
{
public:
- explicit XPThemeData(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ explicit XPThemeData(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1,
int part = 0, int state = 0, const QRect &r = QRect())
- : widget(w), painter(p), theme(themeIn), htheme(0), partId(part), stateId(state),
+ : widget(w), painter(p), theme(themeIn), partId(part), stateId(state),
mirrorHorizontally(false), mirrorVertically(false), noBorder(false),
- noContent(false), rotate(0), rect(r)
+ noContent(false), rect(r)
{}
HRGN mask(QWidget *widget);
@@ -117,17 +117,17 @@ public:
QMarginsF margins(const QRect &rect, int propId = TMT_CONTENTMARGINS);
QMarginsF margins(int propId = TMT_CONTENTMARGINS);
- static QSizeF themeSize(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0);
- static QMarginsF themeMargins(const QRect &rect, const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ static QSizeF themeSize(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0);
+ static QMarginsF themeMargins(const QRect &rect, const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1,
int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
- static QMarginsF themeMargins(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ static QMarginsF themeMargins(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1,
int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
const QWidget *widget;
QPainter *painter;
int theme;
- HTHEME htheme;
+ HTHEME htheme = nullptr;
int partId;
int stateId;
@@ -135,18 +135,18 @@ public:
uint mirrorVertically : 1;
uint noBorder : 1;
uint noContent : 1;
- uint rotate;
+ uint rotate = 0;
QRect rect;
};
struct ThemeMapKey {
- int theme;
- int partId;
- int stateId;
- bool noBorder;
- bool noContent;
+ int theme = 0;
+ int partId = -1;
+ int stateId = -1;
+ bool noBorder = false;
+ bool noContent = false;
- ThemeMapKey() : partId(-1), stateId(-1) {}
+ ThemeMapKey() = default;
ThemeMapKey(const XPThemeData &data)
: theme(data.theme), partId(data.partId), stateId(data.stateId),
noBorder(data.noBorder), noContent(data.noContent) {}
@@ -171,7 +171,7 @@ enum AlphaChannelType {
};
struct ThemeMapData {
- AlphaChannelType alphaType; // Which type of alpha on part & state
+ AlphaChannelType alphaType = UnknownAlpha; // Which type of alpha on part & state
bool dataValid : 1; // Only used to detect if hash value is ok
bool partIsTransparent : 1;
@@ -217,15 +217,13 @@ public:
};
QWindowsXPStylePrivate()
- : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
- bufferPixels(0), bufferW(0), bufferH(0)
{ init(); }
~QWindowsXPStylePrivate()
{ cleanup(); }
- static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0);
- static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0);
+ static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr);
+ static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr);
static HWND winId(const QWidget *widget);
@@ -251,10 +249,10 @@ public:
bool fixAlphaChannel(const QRect &rect);
bool swapAlphaChannel(const QRect &rect, bool allPixels = false);
- QRgb groupBoxTextColor;
- QRgb groupBoxTextColorDisabled;
- QRgb sliderTickColor;
- bool hasInitColors;
+ QRgb groupBoxTextColor = 0;
+ QRgb groupBoxTextColorDisabled = 0;
+ QRgb sliderTickColor = 0;
+ bool hasInitColors = false;
static HTHEME createTheme(int theme, HWND hwnd);
static QString themeName(int theme);
@@ -277,11 +275,12 @@ private:
static bool use_xp;
QHash<ThemeMapKey, ThemeMapData> alphaCache;
- HDC bufferDC;
- HBITMAP bufferBitmap;
- HBITMAP nullBitmap;
- uchar *bufferPixels;
- int bufferW, bufferH;
+ HDC bufferDC = nullptr;
+ HBITMAP bufferBitmap = nullptr;
+ HBITMAP nullBitmap = nullptr;
+ uchar *bufferPixels = nullptr;
+ int bufferW = 0;
+ int bufferH = 0;
static HWND m_vistaTreeViewHelper;
static HTHEME m_themes[NThemes];
@@ -292,7 +291,7 @@ inline QSizeF XPThemeData::size()
QSizeF result(0, 0);
if (isValid()) {
SIZE size;
- if (SUCCEEDED(GetThemePartSize(handle(), 0, partId, stateId, 0, TS_TRUE, &size)))
+ if (SUCCEEDED(GetThemePartSize(handle(), nullptr, partId, stateId, nullptr, TS_TRUE, &size)))
result = QSize(size.cx, size.cy);
}
return result;
@@ -304,7 +303,7 @@ inline QMarginsF XPThemeData::margins(const QRect &qRect, int propId)
if (isValid()) {
MARGINS margins;
RECT rect = XPThemeData::toRECT(qRect);
- if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, &rect, &margins)))
+ if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, &rect, &margins)))
result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight);
}
return result;
@@ -315,7 +314,7 @@ inline QMarginsF XPThemeData::margins(int propId)
QMarginsF result(0, 0, 0 ,0);
if (isValid()) {
MARGINS margins;
- if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, NULL, &margins)))
+ if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, nullptr, &margins)))
result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight);
}
return result;
diff --git a/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp b/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp
index b3112e76ff..f09315435e 100644
--- a/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp
+++ b/src/sql/doc/snippets/code/src_sql_kernel_qsqldatabase.cpp
@@ -79,7 +79,7 @@ QSqlDatabase db = QSqlDatabase::addDatabase("MYDRIVER");
//! [3]
...
db = QSqlDatabase::addDatabase("QODBC");
-db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=myaccessfile.mdb");
+db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};DBQ=myaccessfile.mdb");
if (db.open()) {
// success!
}
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 99aa3e96c4..01726d79ef 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -881,6 +881,14 @@ bool QSqlDatabase::rollback()
connection name must be passed to addDatabase() at connection
object create time.
+ For the QSQLITE driver, if the database name specified does not
+ exist, then it will create the file for you unless the
+ QSQLITE_OPEN_READONLY option is set.
+
+ Additionally, \a name can be set to \c ":memory:" which will
+ create a temporary database which is only available for the
+ lifetime of the application.
+
For the QOCI (Oracle) driver, the database name is the TNS
Service Name.
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 7f7b81b05b..e0ddc4ca84 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -110,6 +110,9 @@ QSqlDriver::~QSqlDriver()
that the driver subscribes to. \a name identifies the event notification.
\sa subscribeToNotification()
+
+ \obsolete use QSqlDriver::notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload)
+ instead
*/
/*!
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 1e03be48d3..ca9f7dc51e 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -135,7 +135,10 @@ public Q_SLOTS:
virtual bool cancelQuery();
Q_SIGNALS:
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use the 3-args version of notification() instead.")
void notification(const QString &name);
+#endif
void notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload);
protected:
diff --git a/src/src.pro b/src/src.pro
index 832a3b6d82..8ff3ec4c1f 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -70,7 +70,7 @@ src_winmain.depends = sub-corelib # just for the module .pri file
src_corelib.subdir = $$PWD/corelib
src_corelib.target = sub-corelib
-src_corelib.depends = src_tools_moc src_tools_rcc
+src_corelib.depends = src_tools_moc src_tools_rcc src_tools_tracegen
src_xml.subdir = $$PWD/xml
src_xml.target = sub-xml
@@ -157,17 +157,12 @@ src_android.subdir = $$PWD/android
src_3rdparty_freetype.depends += src_corelib
}
}
-SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc
+SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_tracegen
qtConfig(regularexpression):pcre2 {
SUBDIRS += src_3rdparty_pcre2
src_corelib.depends += src_3rdparty_pcre2
}
-TOOLS = src_tools_moc src_tools_rcc src_tools_qlalr
-!force_bootstrap:if(qtConfig(lttng)|qtConfig(etw)) {
- SUBDIRS += src_tools_tracegen
- src_corelib.depends += src_tools_tracegen
- TOOLS += src_tools_tracegen
-}
+TOOLS = src_tools_moc src_tools_rcc src_tools_tracegen src_tools_qlalr
SUBDIRS += src_corelib src_tools_qlalr
win32:SUBDIRS += src_winmain
qtConfig(network) {
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 839f556430..7f5725a60c 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -58,8 +58,8 @@
#include <QtCore/qdiriterator.h>
#include <QtCore/qtemporarydir.h>
#include <QtCore/qthread.h>
-#include <QtCore/qwaitcondition.h>
-#include <QtCore/qmutex.h>
+#include <QtCore/private/qlocking_p.h>
+#include <QtCore/private/qwaitcondition_p.h>
#include <QtCore/qtestsupport_core.h>
@@ -85,6 +85,9 @@
#include <cmath>
#include <numeric>
#include <algorithm>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
#include <stdarg.h>
#include <stdio.h>
@@ -406,7 +409,7 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
#if QT_CONFIG(thread)
-static int defaultTimeout()
+static std::chrono::milliseconds defaultTimeout()
{
if (timeout == -1) {
bool ok = false;
@@ -415,7 +418,7 @@ static int defaultTimeout()
if (!ok || timeout <= 0)
timeout = 5*60*1000;
}
- return timeout;
+ return std::chrono::milliseconds{timeout};
}
#endif
@@ -1008,53 +1011,81 @@ void TestMethods::invokeTestOnData(int index) const
class WatchDog : public QThread
{
+ enum Expectation {
+ ThreadStart,
+ TestFunctionStart,
+ TestFunctionEnd,
+ ThreadEnd,
+ };
+
+ bool waitFor(std::unique_lock<QtPrivate::mutex> &m, Expectation e) {
+ auto expectationChanged = [this, e] { return expecting != e; };
+ switch (e) {
+ case TestFunctionEnd:
+ return waitCondition.wait_for(m, defaultTimeout(), expectationChanged);
+ case ThreadStart:
+ case ThreadEnd:
+ case TestFunctionStart:
+ waitCondition.wait(m, expectationChanged);
+ return true;
+ }
+ Q_UNREACHABLE();
+ return false;
+ }
+
public:
WatchDog()
{
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(-1);
+ auto locker = qt_unique_lock(mutex);
+ expecting = ThreadStart;
start();
- waitCondition.wait(&mutex);
+ waitFor(locker, ThreadStart);
}
~WatchDog() {
{
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(0);
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = ThreadEnd;
+ waitCondition.notify_all();
}
wait();
}
void beginTest() {
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(defaultTimeout());
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = TestFunctionEnd;
+ waitCondition.notify_all();
}
void testFinished() {
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(-1);
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = TestFunctionStart;
+ waitCondition.notify_all();
}
void run() override {
- QMutexLocker locker(&mutex);
- waitCondition.wakeAll();
+ auto locker = qt_unique_lock(mutex);
+ expecting = TestFunctionStart;
+ waitCondition.notify_all();
while (true) {
- int t = timeout.loadRelaxed();
- if (!t)
- break;
- if (Q_UNLIKELY(!waitCondition.wait(&mutex, t))) {
- stackTrace();
- qFatal("Test function timed out");
+ switch (expecting) {
+ case ThreadEnd:
+ return;
+ case ThreadStart:
+ Q_UNREACHABLE();
+ case TestFunctionStart:
+ case TestFunctionEnd:
+ if (Q_UNLIKELY(!waitFor(locker, expecting))) {
+ stackTrace();
+ qFatal("Test function timed out");
+ }
}
}
}
private:
- QBasicAtomicInt timeout;
- QMutex mutex;
- QWaitCondition waitCondition;
+ QtPrivate::mutex mutex;
+ QtPrivate::condition_variable waitCondition;
+ Expectation expecting;
};
#else // !QT_CONFIG(thread)
@@ -2790,8 +2821,11 @@ template <> Q_TESTLIB_EXPORT char *QTest::toString<char>(const char &t)
*/
char *QTest::toString(const char *str)
{
- if (!str)
- return nullptr;
+ if (!str) {
+ char *msg = new char[1];
+ *msg = '\0';
+ return msg;
+ }
char *msg = new char[strlen(str) + 1];
return qstrcpy(msg, str);
}
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 6cc9f6102c..5ede55ecf2 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -116,7 +116,6 @@ struct Options
: helpRequested(false)
, verbose(false)
, timing(false)
- , generateAssetsFileList(true)
, build(true)
, auxMode(false)
, deploymentMechanism(Bundled)
@@ -147,7 +146,6 @@ struct Options
bool helpRequested;
bool verbose;
bool timing;
- bool generateAssetsFileList;
bool build;
bool auxMode;
ActionTimer timer;
@@ -318,7 +316,7 @@ static QString shellQuote(const QString &arg)
QString architecureFromName(const QString &name)
{
- QRegExp architecture(QStringLiteral(".*_(.*)\\.so"));
+ QRegExp architecture(QStringLiteral(".*_(armeabi-v7a|arm64-v8a|x86|x86_64).so"));
if (!architecture.exactMatch(name))
return {};
return architecture.capturedTexts().last();
@@ -525,8 +523,6 @@ Options parseOptions()
options.protectedAuthenticationPath = true;
} else if (argument.compare(QLatin1String("--jarsigner"), Qt::CaseInsensitive) == 0) {
options.jarSigner = true;
- } else if (argument.compare(QLatin1String("--no-generated-assets-cache"), Qt::CaseInsensitive) == 0) {
- options.generateAssetsFileList = false;
} else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) {
options.auxMode = true;
} else if (argument.compare(QLatin1String("--qml-importscanner-binary"), Qt::CaseInsensitive) == 0) {
@@ -1191,7 +1187,7 @@ bool copyAndroidExtraResources(Options *options)
} else {
if (!checkArchitecture(*options, originFile))
continue;
- destinationFile = libsDir + QLatin1String("/lib") + QString(resourceDir.dirName() + QLatin1Char('/') + resourceFile).replace(QLatin1Char('/'), QLatin1Char('_'));
+ destinationFile = libsDir + resourceFile;
options->archExtraPlugins[options->currentArchitecture] += resourceFile;
}
if (!copyFileIfNewer(originFile, destinationFile, *options))
@@ -1258,8 +1254,6 @@ bool updateLibsXml(Options *options)
}
QString qtLibs;
- QString bundledInLibs;
- QString bundledInAssets;
QString allLocalLibs;
QString extraLibs;
@@ -1272,33 +1266,6 @@ bool updateLibsXml(Options *options)
QString s = bundledFile.second.mid(sizeof("lib/lib") - 1);
s.chop(sizeof(".so") - 1);
qtLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), s);
- } else if (bundledFile.first.startsWith(libsPath)) {
- QString s = bundledFile.first.mid(libsPath.length());
- bundledInLibs += QString::fromLatin1(" <item>%1;%2:%3</item>\n")
- .arg(it.key(), s, bundledFile.second);
- } else if (bundledFile.first.startsWith(QLatin1String("assets/"))) {
- QString s = bundledFile.first.mid(sizeof("assets/") - 1);
- bundledInAssets += QString::fromLatin1(" <item>%1:%2</item>\n")
- .arg(s, bundledFile.second);
- }
- }
-
- if (!options->archExtraPlugins[it.key()].isEmpty()) {
- for (const QString &extraRes : options->archExtraPlugins[it.key()]) {
- QDir resourceDir(extraRes);
- const QStringList files = allFilesInside(resourceDir, resourceDir);
- for (const QString &file : files) {
- QString destinationPath = resourceDir.dirName() + QLatin1Char('/') + file;
- if (!file.endsWith(QLatin1String(".so"))) {
- bundledInAssets += QLatin1String(" <item>%1:%1</item>\n")
- .arg(destinationPath);
- } else {
- bundledInLibs += QLatin1String(" <item>%1;lib%2:%3</item>\n")
- .arg(it.key(),
- QString(destinationPath).replace(QLatin1Char('/'), QLatin1Char('_')),
- destinationPath);
- }
- }
}
}
@@ -1344,9 +1311,13 @@ bool updateLibsXml(Options *options)
if (options->verbose)
fprintf(stdout, " -- Using platform plugin %s\n", qPrintable(plugin));
}
- allLocalLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), localLibs.join(QLatin1Char(':'))
- .replace(QLatin1String("lib/"), QString{})
- .replace(QLatin1Char('/'), QLatin1Char('_')));
+
+ // remove all paths
+ for (auto &lib : localLibs) {
+ if (lib.endsWith(QLatin1String(".so")))
+ lib = lib.mid(lib.lastIndexOf(QLatin1Char('/')) + 1);
+ }
+ allLocalLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), localLibs.join(QLatin1Char(':')));
}
QHash<QString, QString> replacements;
@@ -1354,11 +1325,6 @@ bool updateLibsXml(Options *options)
replacements[QStringLiteral("<!-- %%INSERT_LOCAL_LIBS%% -->")] = allLocalLibs.trimmed();
replacements[QStringLiteral("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs.trimmed();
- if (options->deploymentMechanism == Options::Bundled) {
- replacements[QStringLiteral("<!-- %%INSERT_BUNDLED_IN_LIB%% -->")] += bundledInLibs.trimmed();
- replacements[QStringLiteral("<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->")] += bundledInAssets.trimmed();
- }
-
if (!updateFile(fileName, replacements))
return false;
@@ -1888,6 +1854,70 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
return true;
}
+bool runCommand(const Options &options, const QString &command)
+{
+ if (options.verbose)
+ fprintf(stdout, "Running command '%s'\n", qPrintable(command));
+
+ FILE *runCommand = openProcess(command);
+ if (runCommand == nullptr) {
+ fprintf(stderr, "Cannot run command '%s'\n", qPrintable(command));
+ return false;
+ }
+ char buffer[4096];
+ while (fgets(buffer, sizeof(buffer), runCommand) != nullptr) {
+ if (options.verbose)
+ fprintf(stdout, "%s", buffer);
+ }
+ pclose(runCommand);
+ fflush(stdout);
+ fflush(stderr);
+ return true;
+}
+
+bool createRcc(const Options &options)
+{
+ auto assetsDir = QLatin1String("%1/assets").arg(options.outputDirectory);
+ if (!QDir{QLatin1String("%1/android_rcc_bundle").arg(assetsDir)}.exists()) {
+ fprintf(stdout, "Skipping createRCC\n");
+ return true;
+ }
+
+ if (options.verbose)
+ fprintf(stdout, "Create rcc bundle.\n");
+
+ QString rcc = options.qtInstallDirectory + QLatin1String("/bin/rcc");
+#if defined(Q_OS_WIN32)
+ rcc += QLatin1String(".exe");
+#endif
+
+ if (!QFile::exists(rcc)) {
+ fprintf(stderr, "rcc not found: %s\n", qPrintable(rcc));
+ return false;
+ }
+ auto currentDir = QDir::currentPath();
+ if (!QDir::setCurrent(QLatin1String("%1/android_rcc_bundle").arg(assetsDir))) {
+ fprintf(stderr, "Cannot set current dir to: %s\n", qPrintable(QLatin1String("%1/android_rcc_bundle").arg(assetsDir)));
+ return false;
+ }
+
+ bool res = runCommand(options, QLatin1String("%1 --project -o %2").arg(rcc, shellQuote(QLatin1String("%1/android_rcc_bundle.qrc").arg(assetsDir))));
+ if (!res)
+ return false;
+
+ QFile::rename(QLatin1String("%1/android_rcc_bundle.qrc").arg(assetsDir), QLatin1String("%1/android_rcc_bundle/android_rcc_bundle.qrc").arg(assetsDir));
+
+ res = runCommand(options, QLatin1String("%1 %2 --binary -o %3 android_rcc_bundle.qrc").arg(rcc, shellQuote(QLatin1String("--root=/android_rcc_bundle/")),
+ shellQuote(QLatin1String("%1/android_rcc_bundle.rcc").arg(assetsDir))));
+ if (!QDir::setCurrent(currentDir)) {
+ fprintf(stderr, "Cannot set current dir to: %s\n", qPrintable(currentDir));
+ return false;
+ }
+ QFile::remove(QLatin1String("%1/android_rcc_bundle.qrc").arg(assetsDir));
+ QDir{QLatin1String("%1/android_rcc_bundle").arg(assetsDir)}.removeRecursively();
+ return res;
+}
+
bool readDependencies(Options *options)
{
if (options->verbose)
@@ -2042,7 +2072,7 @@ bool copyQtFiles(Options *options)
QString libsDirectory = QLatin1String("libs/");
// Copy other Qt dependencies
- auto assetsDestinationDirectory = QLatin1String("assets/--Added-by-androiddeployqt--/");
+ auto assetsDestinationDirectory = QLatin1String("assets/android_rcc_bundle/");
for (const QtDependency &qtDependency : qAsConst(options->qtDependencies[options->currentArchitecture])) {
QString sourceFileName = qtDependency.absolutePath;
QString destinationFileName;
@@ -2052,7 +2082,7 @@ bool copyQtFiles(Options *options)
if (qtDependency.relativePath.startsWith(QLatin1String("lib/"))) {
garbledFileName = qtDependency.relativePath.mid(sizeof("lib/") - 1);
} else {
- garbledFileName = QString(qtDependency.relativePath).replace(QLatin1Char('/'), QLatin1Char('_'));
+ garbledFileName = qtDependency.relativePath.mid(qtDependency.relativePath.lastIndexOf(QLatin1Char('/')) + 1);
}
destinationFileName = libsDirectory + options->currentArchitecture + QLatin1Char('/') + garbledFileName;
} else if (qtDependency.relativePath.startsWith(QLatin1String("jar/"))) {
@@ -2698,57 +2728,6 @@ bool signPackage(const Options &options)
return apkSignerRunner() && QFile::remove(packagePath(options, UnsignedAPK));
}
-bool generateAssetsFileList(const Options &options)
-{
- if (options.verbose)
- fprintf(stdout, "Pregenerating entry list for assets file engine.\n");
-
- QString assetsPath = options.outputDirectory + QLatin1String("/assets/");
- QString addedByAndroidDeployQtPath = assetsPath + QLatin1String("--Added-by-androiddeployqt--/");
- if (!QDir().mkpath(addedByAndroidDeployQtPath)) {
- fprintf(stderr, "Failed to create directory '%s'", qPrintable(addedByAndroidDeployQtPath));
- return false;
- }
-
- QFile file(addedByAndroidDeployQtPath + QLatin1String("/qt_cache_pregenerated_file_list"));
- if (file.open(QIODevice::WriteOnly)) {
- QDirIterator dirIterator(assetsPath,
- QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot,
- QDirIterator::Subdirectories);
-
- QHash<QString, QStringList> directoryContents;
- while (dirIterator.hasNext()) {
- const QString name = dirIterator.next().mid(assetsPath.length());
-
- int slashIndex = name.lastIndexOf(QLatin1Char('/'));
- QString pathName = slashIndex >= 0 ? name.left(slashIndex) : QStringLiteral("/");
- QString fileName = slashIndex >= 0 ? name.mid(pathName.length() + 1) : name;
-
- if (!fileName.isEmpty() && dirIterator.fileInfo().isDir() && !fileName.endsWith(QLatin1Char('/')))
- fileName += QLatin1Char('/');
-
- if (fileName.isEmpty() && !directoryContents.contains(pathName))
- directoryContents[pathName] = QStringList();
- else if (!fileName.isEmpty())
- directoryContents[pathName].append(fileName);
- }
-
- QDataStream stream(&file);
- stream.setVersion(QDataStream::Qt_5_3);
- for (auto it = directoryContents.cbegin(), end = directoryContents.cend(); it != end; ++it) {
- const QStringList &entryList = it.value();
- stream << it.key() << entryList.size();
- for (const QString &entry : entryList)
- stream << entry;
- }
- } else {
- fprintf(stderr, "Pregenerating entry list for assets file engine failed!\n");
- return false;
- }
-
- return true;
-}
-
enum ErrorCode
{
Success,
@@ -2766,9 +2745,9 @@ enum ErrorCode
CannotBuildAndroidProject = 14,
CannotSignPackage = 15,
CannotInstallApk = 16,
- CannotGenerateAssetsFileList = 18,
CannotCopyAndroidExtraResources = 19,
- CannotCopyApk = 20
+ CannotCopyApk = 20,
+ CannotCreateRcc = 21
};
int main(int argc, char *argv[])
@@ -2865,14 +2844,16 @@ int main(int argc, char *argv[])
}
}
+ if (!createRcc(options))
+ return CannotCreateRcc;
+
if (options.auxMode) {
if (!updateAndroidFiles(options))
return CannotUpdateAndroidFiles;
- if (options.generateAssetsFileList && !generateAssetsFileList(options))
- return CannotGenerateAssetsFileList;
return 0;
}
+
if (options.build) {
if (!copyAndroidSources(options))
return CannotCopyAndroidSources;
@@ -2883,9 +2864,6 @@ int main(int argc, char *argv[])
if (!updateAndroidFiles(options))
return CannotUpdateAndroidFiles;
- if (options.generateAssetsFileList && !generateAssetsFileList(options))
- return CannotGenerateAssetsFileList;
-
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Updated files\n", options.timer.elapsed());
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index f9ffd1bbea..09a1c68001 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -75,6 +75,7 @@ SOURCES += \
../../corelib/serialization/qxmlutils.cpp \
../../corelib/serialization/qxmlstream.cpp \
../../corelib/text/qbytearray.cpp \
+ ../../corelib/text/qbytearraylist.cpp \
../../corelib/text/qbytearraymatcher.cpp \
../../corelib/text/qlocale.cpp \
../../corelib/text/qlocale_tools.cpp \
diff --git a/src/tools/moc/collectjson.cpp b/src/tools/moc/collectjson.cpp
new file mode 100644
index 0000000000..4029bca5e9
--- /dev/null
+++ b/src/tools/moc/collectjson.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qfile.h>
+#include <qjsonarray.h>
+#include <qjsondocument.h>
+#include <qjsonobject.h>
+#include <qhashfunctions.h>
+#include <qstringlist.h>
+#include <cstdlib>
+
+static bool readFromDevice(QIODevice *device, QJsonArray *allMetaObjects)
+{
+ const QByteArray contents = device->readAll();
+ if (contents.isEmpty())
+ return true;
+
+ QJsonParseError error {};
+ QJsonDocument metaObjects = QJsonDocument::fromJson(contents, &error);
+ if (error.error != QJsonParseError::NoError) {
+ fprintf(stderr, "%s at %d\n", error.errorString().toUtf8().constData(), error.offset);
+ return false;
+ }
+
+ allMetaObjects->append(metaObjects.object());
+ return true;
+}
+
+int collectJson(const QStringList &jsonFiles, const QString &outputFile)
+{
+ qSetGlobalQHashSeed(0);
+
+ QFile output;
+ if (outputFile.isEmpty()) {
+ if (!output.open(stdout, QIODevice::WriteOnly)) {
+ fprintf(stderr, "Error opening stdout for writing\n");
+ return EXIT_FAILURE;
+ }
+ } else {
+ output.setFileName(outputFile);
+ if (!output.open(QIODevice::WriteOnly)) {
+ fprintf(stderr, "Error opening %s for writing\n", qPrintable(outputFile));
+ return EXIT_FAILURE;
+ }
+ }
+
+ QJsonArray allMetaObjects;
+ if (jsonFiles.isEmpty()) {
+ QFile f;
+ if (!f.open(stdin, QIODevice::ReadOnly)) {
+ fprintf(stderr, "Error opening stdin for reading\n");
+ return EXIT_FAILURE;
+ }
+
+ if (!readFromDevice(&f, &allMetaObjects)) {
+ fprintf(stderr, "Error parsing data from stdin\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ for (const QString &jsonFile: jsonFiles) {
+ QFile f(jsonFile);
+ if (!f.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Error opening %s for reading\n", qPrintable(jsonFile));
+ return EXIT_FAILURE;
+ }
+
+ if (!readFromDevice(&f, &allMetaObjects)) {
+ fprintf(stderr, "Error parsing %s\n", qPrintable(jsonFile));
+ return EXIT_FAILURE;
+ }
+ }
+
+ QJsonDocument doc(allMetaObjects);
+ output.write(doc.toJson());
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/tools/moc/collectjson.h b/src/tools/moc/collectjson.h
new file mode 100644
index 0000000000..9d329c96ca
--- /dev/null
+++ b/src/tools/moc/collectjson.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COLLECTJSON_H
+#define COLLECTJSON_H
+
+#include <qglobal.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+int collectJson(const QStringList &jsonFiles, const QString &outputFile);
+
+QT_END_NAMESPACE
+
+#endif // COLLECTOJSON_H
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 6a74e739e6..ace3a4c9f3 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -1217,18 +1217,22 @@ void Generator::generateStaticMetacall()
fprintf(out, "%s(", f.name.constData());
int offset = 1;
- int argsCount = f.arguments.count();
- for (int j = 0; j < argsCount; ++j) {
- const ArgumentDef &a = f.arguments.at(j);
- if (j)
- fprintf(out, ",");
- fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
- isUsed_a = true;
- }
- if (f.isPrivateSignal) {
- if (argsCount > 0)
- fprintf(out, ", ");
- fprintf(out, "%s", "QPrivateSignal()");
+ if (f.isRawSlot) {
+ fprintf(out, "QMethodRawArguments{ _a }");
+ } else {
+ int argsCount = f.arguments.count();
+ for (int j = 0; j < argsCount; ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
+ isUsed_a = true;
+ }
+ if (f.isPrivateSignal) {
+ if (argsCount > 0)
+ fprintf(out, ", ");
+ fprintf(out, "%s", "QPrivateSignal()");
+ }
}
fprintf(out, ");");
if (f.normalizedType != "void") {
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index ba559b572f..4aa040a9bb 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -30,6 +30,7 @@
#include "preprocessor.h"
#include "moc.h"
#include "outputrevision.h"
+#include "collectjson.h"
#include <qfile.h>
#include <qfileinfo.h>
@@ -37,10 +38,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
+#include <errno.h>
#include <qcoreapplication.h>
#include <qcommandlineoption.h>
#include <qcommandlineparser.h>
+#include <qscopedpointer.h>
QT_BEGIN_NAMESPACE
@@ -77,6 +80,10 @@ void error(const char *msg = "Invalid argument")
fprintf(stderr, "moc: %s\n", msg);
}
+struct ScopedPointerFileCloser
+{
+ static inline void cleanup(FILE *handle) { if (handle) fclose(handle); }
+};
static inline bool hasNext(const Symbols &symbols, int i)
{ return (i < symbols.size()); }
@@ -293,10 +300,20 @@ int runMoc(int argc, char **argv)
ignoreConflictsOption.setDescription(QStringLiteral("Ignore all options that conflict with compilers, like -pthread conflicting with moc's -p option."));
parser.addOption(ignoreConflictsOption);
+ QCommandLineOption jsonOption(QStringLiteral("output-json"));
+ jsonOption.setDescription(QStringLiteral("In addition to generating C++ code, create a machine-readable JSON file in a file that matches the output file and an extra .json extension."));
+ parser.addOption(jsonOption);
+
+ QCommandLineOption collectOption(QStringLiteral("collect-json"));
+ collectOption.setDescription(QStringLiteral("Instead of processing C++ code, collect previously generated JSON output into a single file."));
+ parser.addOption(collectOption);
+
parser.addPositionalArgument(QStringLiteral("[header-file]"),
QStringLiteral("Header file to read from, otherwise stdin."));
parser.addPositionalArgument(QStringLiteral("[@option-file]"),
QStringLiteral("Read additional options from option-file."));
+ parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"),
+ QStringLiteral("MOC generated json output"));
const QStringList arguments = argumentsFromCommandLineAndFile(app.arguments());
if (arguments.isEmpty())
@@ -305,6 +322,10 @@ int runMoc(int argc, char **argv)
parser.process(arguments);
const QStringList files = parser.positionalArguments();
+ output = parser.value(outputOption);
+ if (parser.isSet(collectOption))
+ return collectJson(files, output);
+
if (files.count() > 1) {
error(qPrintable(QLatin1String("Too many input files specified: '") + files.join(QLatin1String("' '")) + QLatin1Char('\'')));
parser.showHelp(1);
@@ -313,7 +334,6 @@ int runMoc(int argc, char **argv)
}
const bool ignoreConflictingOptions = parser.isSet(ignoreConflictsOption);
- output = parser.value(outputOption);
pp.preprocessOnly = parser.isSet(preprocessOption);
if (parser.isSet(noIncludeOption)) {
moc.noInclude = true;
@@ -485,6 +505,8 @@ int runMoc(int argc, char **argv)
// 3. and output meta object code
+ QScopedPointer<FILE, ScopedPointerFileCloser> jsonOutput;
+
if (output.size()) { // output file specified
#if defined(_MSC_VER)
if (_wfopen_s(&out, reinterpret_cast<const wchar_t *>(output.utf16()), L"w") != 0)
@@ -496,6 +518,21 @@ int runMoc(int argc, char **argv)
fprintf(stderr, "moc: Cannot create %s\n", QFile::encodeName(output).constData());
return 1;
}
+
+ if (parser.isSet(jsonOption)) {
+ const QString jsonOutputFileName = output + QLatin1String(".json");
+ FILE *f;
+#if defined(_MSC_VER)
+ if (_wfopen_s(&f, reinterpret_cast<const wchar_t *>(jsonOutputFileName.utf16()), L"w") != 0)
+#else
+ f = fopen(QFile::encodeName(jsonOutputFileName).constData(), "w");
+ if (!f)
+#endif
+ fprintf(stderr, "moc: Cannot create JSON output file %s. %s\n",
+ QFile::encodeName(jsonOutputFileName).constData(),
+ strerror(errno));
+ jsonOutput.reset(f);
+ }
} else { // use stdout
out = stdout;
}
@@ -506,7 +543,7 @@ int runMoc(int argc, char **argv)
if (moc.classList.isEmpty())
moc.note("No relevant classes found. No output generated.");
else
- moc.generate(out);
+ moc.generate(out, jsonOutput.data());
}
if (output.size())
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 50946443be..b98198d1d5 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -35,6 +35,7 @@
#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
+#include <QtCore/qjsondocument.h>
// for normalizeTypeInternal
#include <private/qmetaobject_moc_p.h>
@@ -327,6 +328,11 @@ void Moc::parseFunctionArguments(FunctionDef *def)
def->arguments.removeLast();
def->isPrivateSignal = true;
}
+ if (def->arguments.size() == 1
+ && def->arguments.constLast().normalizedType == "QMethodRawArguments") {
+ def->arguments.removeLast();
+ def->isRawSlot = true;
+ }
}
bool Moc::testFunctionAttribute(FunctionDef *def)
@@ -999,7 +1005,7 @@ static QByteArrayList requiredQtContainers(const QVector<ClassDef> &classes)
return required;
}
-void Moc::generate(FILE *out)
+void Moc::generate(FILE *out, FILE *jsonOutput)
{
QByteArray fn = filename;
int i = filename.length()-1;
@@ -1062,6 +1068,23 @@ void Moc::generate(FILE *out)
fprintf(out, "QT_WARNING_POP\n");
fprintf(out, "QT_END_MOC_NAMESPACE\n");
+
+ if (jsonOutput) {
+ QJsonObject mocData;
+ mocData[QLatin1String("outputRevision")] = mocOutputRevision;
+ mocData[QLatin1String("inputFile")] = QLatin1String(fn.constData());
+
+ QJsonArray classesJsonFormatted;
+
+ for (const ClassDef &cdef: qAsConst(classList))
+ classesJsonFormatted.append(cdef.toJson());
+
+ if (!classesJsonFormatted.isEmpty())
+ mocData[QLatin1String("classes")] = classesJsonFormatted;
+
+ QJsonDocument jsonDoc(mocData);
+ fputs(jsonDoc.toJson().constData(), jsonOutput);
+ }
}
void Moc::parseSlots(ClassDef *def, FunctionDef::Access access)
@@ -1784,6 +1807,186 @@ void Moc::checkProperties(ClassDef *cdef)
}
}
+QJsonObject ClassDef::toJson() const
+{
+ QJsonObject cls;
+ cls[QLatin1String("className")] = QString::fromUtf8(classname.constData());
+ cls[QLatin1String("qualifiedClassName")] = QString::fromUtf8(qualified.constData());
+
+ QJsonArray classInfos;
+ for (const auto &info: qAsConst(classInfoList)) {
+ QJsonObject infoJson;
+ infoJson[QLatin1String("name")] = QString::fromUtf8(info.name);
+ infoJson[QLatin1String("value")] = QString::fromUtf8(info.value);
+ classInfos.append(infoJson);
+ }
+
+ if (classInfos.size())
+ cls[QLatin1String("classInfos")] = classInfos;
+
+ const auto appendFunctions = [&cls](const QString &type, const QVector<FunctionDef> &funcs) {
+ QJsonArray jsonFuncs;
+
+ for (const FunctionDef &fdef: funcs)
+ jsonFuncs.append(fdef.toJson());
+
+ if (!jsonFuncs.isEmpty())
+ cls[type] = jsonFuncs;
+ };
+ appendFunctions(QLatin1String("signals"), signalList);
+ appendFunctions(QLatin1String("slots"), slotList);
+ appendFunctions(QLatin1String("constructors"), constructorList);
+ appendFunctions(QLatin1String("methods"), methodList);
+
+ QJsonArray props;
+
+ for (const PropertyDef &propDef: qAsConst(propertyList))
+ props.append(propDef.toJson());
+
+ if (!props.isEmpty())
+ cls[QLatin1String("properties")] = props;
+
+ if (hasQGadget)
+ cls[QLatin1String("gadget")] = true;
+
+ QJsonArray superClasses;
+
+ for (const auto &super: qAsConst(superclassList)) {
+ const auto name = super.first;
+ const auto access = super.second;
+ QJsonObject superCls;
+ superCls[QLatin1String("name")] = QString::fromUtf8(name);
+ FunctionDef::accessToJson(&superCls, access);
+ superClasses.append(superCls);
+ }
+
+ if (!superClasses.isEmpty())
+ cls[QLatin1String("superClasses")] = superClasses;
+
+ QJsonArray enums;
+ for (const EnumDef &enumDef: qAsConst(enumList))
+ enums.append(enumDef.toJson(*this));
+ if (!enums.isEmpty())
+ cls[QLatin1String("enums")] = enums;
+
+ QJsonArray ifaces;
+ for (const QVector<Interface> &ifaceList: interfaceList) {
+ QJsonArray jsonList;
+ for (const Interface &iface: ifaceList) {
+ QJsonObject ifaceJson;
+ ifaceJson[QLatin1String("id")] = QString::fromUtf8(iface.interfaceId);
+ ifaceJson[QLatin1String("className")] = QString::fromUtf8(iface.className);
+ jsonList.append(ifaceJson);
+ }
+ ifaces.append(jsonList);
+ }
+ if (!ifaces.isEmpty())
+ cls[QLatin1String("interfaces")] = ifaces;
+
+ return cls;
+}
+
+QJsonObject FunctionDef::toJson() const
+{
+ QJsonObject fdef;
+ fdef[QLatin1String("name")] = QString::fromUtf8(name);
+ if (!tag.isEmpty())
+ fdef[QLatin1String("tag")] = QString::fromUtf8(tag);
+ fdef[QLatin1String("returnType")] = QString::fromUtf8(normalizedType);
+
+ QJsonArray args;
+ for (const ArgumentDef &arg: arguments)
+ args.append(arg.toJson());
+
+ if (!args.isEmpty())
+ fdef[QLatin1String("arguments")] = args;
+
+ accessToJson(&fdef, access);
+
+ if (revision > 0)
+ fdef[QLatin1String("revision")] = revision;
+
+ return fdef;
+}
+
+void FunctionDef::accessToJson(QJsonObject *obj, FunctionDef::Access acs)
+{
+ switch (acs) {
+ case Private: (*obj)[QLatin1String("access")] = QLatin1String("private"); break;
+ case Public: (*obj)[QLatin1String("access")] = QLatin1String("public"); break;
+ case Protected: (*obj)[QLatin1String("access")] = QLatin1String("protected"); break;
+ }
+}
+
+QJsonObject ArgumentDef::toJson() const
+{
+ QJsonObject arg;
+ arg[QLatin1String("type")] = QString::fromUtf8(normalizedType);
+ if (!name.isEmpty())
+ arg[QLatin1String("name")] = QString::fromUtf8(name);
+ return arg;
+}
+
+QJsonObject PropertyDef::toJson() const
+{
+ QJsonObject prop;
+ prop[QLatin1String("name")] = QString::fromUtf8(name);
+ prop[QLatin1String("type")] = QString::fromUtf8(type);
+
+ const auto jsonify = [&prop](const char *str, const QByteArray &member) {
+ if (!member.isEmpty())
+ prop[QLatin1String(str)] = QString::fromUtf8(member);
+ };
+
+ jsonify("member", member);
+ jsonify("read", read);
+ jsonify("write", write);
+ jsonify("reset", reset);
+ jsonify("notify", notify);
+ jsonify("privateClass", inPrivateClass);
+
+ const auto jsonifyBoolOrString = [&prop](const char *str, const QByteArray &boolOrString) {
+ QJsonValue value;
+ if (boolOrString == "true")
+ value = true;
+ else if (boolOrString == "false")
+ value = false;
+ else
+ value = QString::fromUtf8(boolOrString); // function name to query at run-time
+ prop[QLatin1String(str)] = value;
+ };
+
+ jsonifyBoolOrString("designable", designable);
+ jsonifyBoolOrString("scriptable", scriptable);
+ jsonifyBoolOrString("stored", stored);
+ jsonifyBoolOrString("user", user);
+
+ prop[QLatin1String("constant")] = constant;
+ prop[QLatin1String("final")] = final;
+
+ if (revision > 0)
+ prop[QLatin1String("revision")] = revision;
+
+ return prop;
+}
+
+QJsonObject EnumDef::toJson(const ClassDef &cdef) const
+{
+ QJsonObject def;
+ def[QLatin1String("name")] = QString::fromUtf8(name);
+ if (!enumName.isEmpty())
+ def[QLatin1String("alias")] = QString::fromUtf8(enumName);
+ def[QLatin1String("isFlag")] = cdef.enumDeclarations.value(name);
+ def[QLatin1String("isClass")] = isEnumClass;
+
+ QJsonArray valueArr;
+ for (const QByteArray &value: values)
+ valueArr.append(QString::fromUtf8(value));
+ if (!valueArr.isEmpty())
+ def[QLatin1String("values")] = valueArr;
+
+ return def;
+}
QT_END_NAMESPACE
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index bb1c9501fe..6785b7f9e8 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -61,6 +61,7 @@ struct Type
};
Q_DECLARE_TYPEINFO(Type, Q_MOVABLE_TYPE);
+struct ClassDef;
struct EnumDef
{
QByteArray name;
@@ -68,6 +69,7 @@ struct EnumDef
QVector<QByteArray> values;
bool isEnumClass; // c++11 enum class
EnumDef() : isEnumClass(false) {}
+ QJsonObject toJson(const ClassDef &cdef) const;
};
Q_DECLARE_TYPEINFO(EnumDef, Q_MOVABLE_TYPE);
@@ -78,6 +80,8 @@ struct ArgumentDef
QByteArray rightType, normalizedType, name;
QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
bool isDefault;
+
+ QJsonObject toJson() const;
};
Q_DECLARE_TYPEINFO(ArgumentDef, Q_MOVABLE_TYPE);
@@ -111,6 +115,10 @@ struct FunctionDef
bool isConstructor = false;
bool isDestructor = false;
bool isAbstract = false;
+ bool isRawSlot = false;
+
+ QJsonObject toJson() const;
+ static void accessToJson(QJsonObject *obj, Access acs);
};
Q_DECLARE_TYPEINFO(FunctionDef, Q_MOVABLE_TYPE);
@@ -130,6 +138,8 @@ struct PropertyDef
int revision = 0;
bool constant = false;
bool final = false;
+
+ QJsonObject toJson() const;
};
Q_DECLARE_TYPEINFO(PropertyDef, Q_MOVABLE_TYPE);
@@ -183,6 +193,7 @@ struct ClassDef : BaseDef {
bool hasQObject = false;
bool hasQGadget = false;
+ QJsonObject toJson() const;
};
Q_DECLARE_TYPEINFO(ClassDef, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE);
@@ -215,7 +226,7 @@ public:
QMap<QString, QJsonArray> metaArgs;
void parse();
- void generate(FILE *out);
+ void generate(FILE *out, FILE *jsonOutput);
bool parseClassHead(ClassDef *def);
inline bool inClass(const ClassDef *def) const {
diff --git a/src/tools/moc/moc.pri b/src/tools/moc/moc.pri
index 90839a445b..278d5607cd 100644
--- a/src/tools/moc/moc.pri
+++ b/src/tools/moc/moc.pri
@@ -10,9 +10,12 @@ HEADERS = $$PWD/moc.h \
$$PWD/utils.h \
$$PWD/generator.h \
$$PWD/outputrevision.h \
- $$PWD/cbordevice.h
+ $$PWD/cbordevice.h \
+ $$PWD/collectjson.h
+
SOURCES = $$PWD/moc.cpp \
$$PWD/preprocessor.cpp \
$$PWD/generator.cpp \
$$PWD/parser.cpp \
- $$PWD/token.cpp
+ $$PWD/token.cpp \
+ $$PWD/collectjson.cpp
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index e9e49e0c33..a04189513a 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -57,6 +57,9 @@
#ifdef Q_OS_WIN
# include <QtCore/QVarLengthArray>
# include <qt_windows.h>
+# ifndef Q_OS_WINRT
+# include <shlobj.h>
+# endif
#endif
QT_BEGIN_NAMESPACE
@@ -837,8 +840,8 @@ QString QFileSystemModelPrivate::displayName(const QModelIndex &index) const
{
#if defined(Q_OS_WIN)
QFileSystemNode *dirNode = node(index);
- if (!dirNode->volumeName.isNull())
- return dirNode->volumeName + QLatin1String(" (") + name(index) + QLatin1Char(')');
+ if (!dirNode->volumeName.isEmpty())
+ return dirNode->volumeName;
#endif
return name(index);
}
@@ -1773,6 +1776,27 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
removeNode(parentNode, toRemove[i]);
}
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+static QString volumeName(const QString &path)
+{
+ IShellItem *item = nullptr;
+ const QString native = QDir::toNativeSeparators(path);
+ HRESULT hr = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
+ nullptr, IID_IShellItem,
+ reinterpret_cast<void **>(&item));
+ if (FAILED(hr))
+ return QString();
+ LPWSTR name = nullptr;
+ hr = item->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
+ if (FAILED(hr))
+ return QString();
+ QString result = QString::fromWCharArray(name);
+ CoTaskMemFree(name);
+ item->Release();
+ return result;
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
/*!
\internal
@@ -1791,15 +1815,8 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
//The parentNode is "" so we are listing the drives
- if (parentNode->fileName.isEmpty()) {
- wchar_t name[MAX_PATH + 1];
- //GetVolumeInformation requires to add trailing backslash
- const QString nodeName = fileName + QLatin1String("\\");
- BOOL success = ::GetVolumeInformation((wchar_t *)(nodeName.utf16()),
- name, MAX_PATH + 1, NULL, 0, NULL, NULL, 0);
- if (success && name[0])
- node->volumeName = QString::fromWCharArray(name);
- }
+ if (parentNode->fileName.isEmpty())
+ node->volumeName = volumeName(fileName);
#endif
Q_ASSERT(!parentNode->children.contains(fileName));
parentNode->children.insert(fileName, node);
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 7558054da5..0295241a74 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -55,10 +55,14 @@
#if QT_CONFIG(lineedit)
#include "qlineedit.h"
#endif
+#include <qpointer.h>
#include "qpainter.h"
#include "qwindow.h"
#include "qpushbutton.h"
#include "qset.h"
+#if QT_CONFIG(shortcut)
+# include "qshortcut.h"
+#endif
#include "qstyle.h"
#include "qvarlengtharray.h"
#if defined(Q_OS_MACX)
@@ -232,31 +236,24 @@ void QWizardField::findProperty(const QWizardDefaultProperty *properties, int pr
class QWizardLayoutInfo
{
public:
- inline QWizardLayoutInfo()
- : topLevelMarginLeft(-1), topLevelMarginRight(-1), topLevelMarginTop(-1),
- topLevelMarginBottom(-1), childMarginLeft(-1), childMarginRight(-1),
- childMarginTop(-1), childMarginBottom(-1), hspacing(-1), vspacing(-1),
- wizStyle(QWizard::ClassicStyle), header(false), watermark(false), title(false),
- subTitle(false), extension(false), sideWidget(false) {}
-
- int topLevelMarginLeft;
- int topLevelMarginRight;
- int topLevelMarginTop;
- int topLevelMarginBottom;
- int childMarginLeft;
- int childMarginRight;
- int childMarginTop;
- int childMarginBottom;
- int hspacing;
- int vspacing;
- int buttonSpacing;
- QWizard::WizardStyle wizStyle;
- bool header;
- bool watermark;
- bool title;
- bool subTitle;
- bool extension;
- bool sideWidget;
+ int topLevelMarginLeft = -1;
+ int topLevelMarginRight = -1;
+ int topLevelMarginTop = -1;
+ int topLevelMarginBottom = -1;
+ int childMarginLeft = -1;
+ int childMarginRight = -1;
+ int childMarginTop = -1;
+ int childMarginBottom = -1;
+ int hspacing = -1;
+ int vspacing = -1;
+ int buttonSpacing = -1;
+ QWizard::WizardStyle wizStyle = QWizard::ClassicStyle;
+ bool header = false;
+ bool watermark = false;
+ bool title = false;
+ bool subTitle = false;
+ bool extension = false;
+ bool sideWidget = false;
bool operator==(const QWizardLayoutInfo &other);
inline bool operator!=(const QWizardLayoutInfo &other) { return !operator==(other); }
@@ -486,21 +483,18 @@ class QWizardPagePrivate : public QWidgetPrivate
public:
enum TriState { Tri_Unknown = -1, Tri_False, Tri_True };
- inline QWizardPagePrivate()
- : wizard(0), completeState(Tri_Unknown), explicitlyFinal(false), commit(false) {}
-
bool cachedIsComplete() const;
void _q_maybeEmitCompleteChanged();
void _q_updateCachedCompleteState();
- QWizard *wizard;
+ QWizard *wizard = nullptr;
QString title;
QString subTitle;
QPixmap pixmaps[QWizard::NPixmaps];
QVector<QWizardField> pendingFields;
- mutable TriState completeState;
- bool explicitlyFinal;
- bool commit;
+ mutable TriState completeState = Tri_Unknown;
+ bool explicitlyFinal = false;
+ bool commit = false;
bool initialized = false;
QMap<int, QString> buttonCustomTexts;
};
@@ -556,42 +550,6 @@ public:
Forward
};
- inline QWizardPrivate()
- : start(-1)
- , startSetByUser(false)
- , current(-1)
- , canContinue(false)
- , canFinish(false)
- , disableUpdatesCount(0)
- , wizStyle(QWizard::ClassicStyle)
- , opts(0)
- , buttonsHaveCustomLayout(false)
- , titleFmt(Qt::AutoText)
- , subTitleFmt(Qt::AutoText)
- , placeholderWidget1(0)
- , placeholderWidget2(0)
- , headerWidget(0)
- , watermarkLabel(0)
- , sideWidget(0)
- , pageFrame(0)
- , titleLabel(0)
- , subTitleLabel(0)
- , bottomRuler(0)
-#if QT_CONFIG(style_windowsvista)
- , vistaHelper(0)
- , vistaInitPending(true)
- , vistaState(QVistaHelper::Dirty)
- , vistaStateChanged(false)
- , inHandleAeroStyleChange(false)
-#endif
- , minimumWidth(0)
- , minimumHeight(0)
- , maximumWidth(QWIDGETSIZE_MAX)
- , maximumHeight(QWIDGETSIZE_MAX)
- {
- std::fill(btns, btns + QWizard::NButtons, static_cast<QAbstractButton *>(0));
- }
-
void init();
void reset();
void cleanupPagesNotInHistory();
@@ -631,21 +589,21 @@ public:
QMap<QString, int> fieldIndexMap;
QVector<QWizardDefaultProperty> defaultPropertyTable;
QList<int> history;
- int start;
- bool startSetByUser;
- int current;
- bool canContinue;
- bool canFinish;
+ int start = -1;
+ bool startSetByUser = false;
+ int current = -1;
+ bool canContinue = false;
+ bool canFinish = false;
QWizardLayoutInfo layoutInfo;
- int disableUpdatesCount;
+ int disableUpdatesCount = 0;
- QWizard::WizardStyle wizStyle;
+ QWizard::WizardStyle wizStyle = QWizard::ClassicStyle;
QWizard::WizardOptions opts;
QMap<int, QString> buttonCustomTexts;
- bool buttonsHaveCustomLayout;
+ bool buttonsHaveCustomLayout = false;
QList<QWizard::WizardButton> buttonsCustomLayout;
- Qt::TextFormat titleFmt;
- Qt::TextFormat subTitleFmt;
+ Qt::TextFormat titleFmt = Qt::AutoText;
+ Qt::TextFormat subTitleFmt = Qt::AutoText;
mutable QPixmap defaultPixmaps[QWizard::NPixmaps];
union {
@@ -660,32 +618,35 @@ public:
} btn;
mutable QAbstractButton *btns[QWizard::NButtons];
};
- QWizardAntiFlickerWidget *antiFlickerWidget;
- QWidget *placeholderWidget1;
- QWidget *placeholderWidget2;
- QWizardHeader *headerWidget;
- QWatermarkLabel *watermarkLabel;
- QWidget *sideWidget;
- QFrame *pageFrame;
- QLabel *titleLabel;
- QLabel *subTitleLabel;
- QWizardRuler *bottomRuler;
-
- QVBoxLayout *pageVBoxLayout;
- QHBoxLayout *buttonLayout;
- QGridLayout *mainLayout;
+ QWizardAntiFlickerWidget *antiFlickerWidget = nullptr;
+ QWidget *placeholderWidget1 = nullptr;
+ QWidget *placeholderWidget2 = nullptr;
+ QWizardHeader *headerWidget = nullptr;
+ QWatermarkLabel *watermarkLabel = nullptr;
+ QWidget *sideWidget = nullptr;
+ QFrame *pageFrame = nullptr;
+ QLabel *titleLabel = nullptr;
+ QLabel *subTitleLabel = nullptr;
+ QWizardRuler *bottomRuler = nullptr;
+
+ QVBoxLayout *pageVBoxLayout = nullptr;
+ QHBoxLayout *buttonLayout = nullptr;
+ QGridLayout *mainLayout = nullptr;
#if QT_CONFIG(style_windowsvista)
- QVistaHelper *vistaHelper;
- bool vistaInitPending;
- QVistaHelper::VistaState vistaState;
- bool vistaStateChanged;
- bool inHandleAeroStyleChange;
+ QVistaHelper *vistaHelper = nullptr;
+# if QT_CONFIG(shortcut)
+ QPointer<QShortcut> vistaNextShortcut;
+# endif
+ bool vistaInitPending = true;
+ QVistaHelper::VistaState vistaState = QVistaHelper::Dirty;
+ bool vistaStateChanged = false;
+ bool inHandleAeroStyleChange = false;
#endif
- int minimumWidth;
- int minimumHeight;
- int maximumWidth;
- int maximumHeight;
+ int minimumWidth = 0;
+ int minimumHeight = 0;
+ int maximumWidth = QWIDGETSIZE_MAX;
+ int maximumHeight = QWIDGETSIZE_MAX;
};
static QString buttonDefaultText(int wstyle, int which, const QWizardPrivate *wizardPrivate)
@@ -720,6 +681,8 @@ void QWizardPrivate::init()
{
Q_Q(QWizard);
+ std::fill(btns, btns + QWizard::NButtons, nullptr);
+
antiFlickerWidget = new QWizardAntiFlickerWidget(q, this);
wizStyle = QWizard::WizardStyle(q->style()->styleHint(QStyle::SH_WizardStyle, 0, q));
if (wizStyle == QWizard::MacStyle) {
@@ -1461,10 +1424,17 @@ void QWizardPrivate::updateButtonTexts()
// Vista: Add shortcut for 'next'. Note: native dialogs use ALT-Right
// even in RTL mode, so do the same, even if it might be counter-intuitive.
// The shortcut for 'back' is set in class QVistaBackButton.
-#if QT_CONFIG(shortcut)
- if (btns[QWizard::NextButton] && isVistaThemeEnabled())
- btns[QWizard::NextButton]->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Right));
-#endif
+#if QT_CONFIG(shortcut) && QT_CONFIG(style_windowsvista)
+ if (btns[QWizard::NextButton] && isVistaThemeEnabled()) {
+ if (vistaNextShortcut.isNull()) {
+ vistaNextShortcut =
+ new QShortcut(QKeySequence(Qt::ALT | Qt::Key_Right),
+ btns[QWizard::NextButton], SLOT(animateClick()));
+ }
+ } else {
+ delete vistaNextShortcut;
+ }
+#endif // shortcut && style_windowsvista
}
void QWizardPrivate::updateButtonLayout()
@@ -3271,9 +3241,13 @@ bool QWizard::nativeEvent(const QByteArray &eventType, void *message, long *resu
MSG *windowsMessage = static_cast<MSG *>(message);
const bool winEventResult = d->vistaHelper->handleWinEvent(windowsMessage, result);
if (QVistaHelper::vistaState() != d->vistaState) {
- d->vistaState = QVistaHelper::vistaState();
- d->vistaStateChanged = true;
- setWizardStyle(AeroStyle);
+ // QTBUG-78300: When Qt::AA_NativeWindows is set, delay further
+ // window creation until after the platform window creation events.
+ if (windowsMessage->message == WM_GETICON) {
+ d->vistaStateChanged = true;
+ d->vistaState = QVistaHelper::vistaState();
+ setWizardStyle(AeroStyle);
+ }
}
return winEventResult;
} else {
diff --git a/src/widgets/doc/snippets/javastyle.cpp b/src/widgets/doc/snippets/javastyle.cpp
index 8657d5ed29..de3143f753 100644
--- a/src/widgets/doc/snippets/javastyle.cpp
+++ b/src/widgets/doc/snippets/javastyle.cpp
@@ -2130,7 +2130,7 @@ void JavaStyle::drawPrimitive(PrimitiveElement element,
painter->restore();
break;
}
- case PE_IndicatorViewItemCheck: {
+ case PE_IndicatorItemViewItemCheck: {
break;
}
case PE_FrameWindow: {
diff --git a/src/widgets/doc/snippets/qsplashscreen/main.cpp b/src/widgets/doc/snippets/qsplashscreen/main.cpp
index 843932ca83..2512035879 100644
--- a/src/widgets/doc/snippets/qsplashscreen/main.cpp
+++ b/src/widgets/doc/snippets/qsplashscreen/main.cpp
@@ -71,3 +71,10 @@ int main(int argc, char *argv[])
return app.exec();
}
//! [1]
+
+//! [2]
+QScreen *screen = QGuiApplication::screens().at(1);
+QPixmap pixmap(":/splash.png");
+QSplashScreen splash(screen, pixmap);
+splash.show();
+//! [2]
diff --git a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc
index 645da5bca2..faaf4e5479 100644
--- a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc
@@ -1837,7 +1837,7 @@
item views keep the dimensions on individual sections. Also
note that the delegates may use the style to paint decorations
and frames around items. QItemDelegate, for instance, draws
- \c PE_FrameFocusRect and \c PE_IndicatorViewItemCheck.
+ \c PE_FrameFocusRect and \c PE_IndicatorItemViewItemCheck.
\image javastyle/header.png
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index bb00db4c01..88baf8015a 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -1580,13 +1580,8 @@ QGraphicsItem::~QGraphicsItem()
p->wasDeleted = true;
if (p->declarativeData) {
p->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
- if (static_cast<QAbstractDeclarativeDataImpl*>(p->declarativeData)->ownedByQml1) {
- if (QAbstractDeclarativeData::destroyed_qml1)
- QAbstractDeclarativeData::destroyed_qml1(p->declarativeData, o);
- } else {
- if (QAbstractDeclarativeData::destroyed)
- QAbstractDeclarativeData::destroyed(p->declarativeData, o);
- }
+ if (QAbstractDeclarativeData::destroyed)
+ QAbstractDeclarativeData::destroyed(p->declarativeData, o);
p->declarativeData = 0;
p->wasDeleted = false;
}
diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h
index 3cc00ead08..e72ed99a7b 100644
--- a/src/widgets/graphicsview/qgraphicsscene.h
+++ b/src/widgets/graphicsview/qgraphicsscene.h
@@ -54,7 +54,6 @@ QT_REQUIRE_CONFIG(graphicsview);
QT_BEGIN_NAMESPACE
-template<typename T> class QList;
class QFocusEvent;
class QFont;
class QFontMetrics;
@@ -115,7 +114,7 @@ public:
BspTreeIndex,
NoIndex = -1
};
-
+ Q_ENUM(ItemIndexMethod)
enum SceneLayer {
ItemLayer = 0x1,
BackgroundLayer = 0x2,
diff --git a/src/widgets/graphicsview/qgraphicssceneindex_p.h b/src/widgets/graphicsview/qgraphicssceneindex_p.h
index b494c52671..e13c2a3cd3 100644
--- a/src/widgets/graphicsview/qgraphicssceneindex_p.h
+++ b/src/widgets/graphicsview/qgraphicssceneindex_p.h
@@ -67,7 +67,6 @@ QT_BEGIN_NAMESPACE
class QGraphicsSceneIndexPrivate;
class QPointF;
class QRectF;
-template<typename T> class QList;
typedef bool (*QGraphicsSceneIndexIntersector)(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
const QTransform &deviceTransform, const void *data);
diff --git a/src/widgets/graphicsview/qgraphicsview.h b/src/widgets/graphicsview/qgraphicsview.h
index e02fba69c9..1389796c3f 100644
--- a/src/widgets/graphicsview/qgraphicsview.h
+++ b/src/widgets/graphicsview/qgraphicsview.h
@@ -107,7 +107,9 @@ public:
Q_ENUM(ViewportUpdateMode)
enum OptimizationFlag {
- DontClipPainter = 0x1, // obsolete
+#if QT_DEPRECATED_SINCE(5, 14)
+ DontClipPainter Q_DECL_ENUMERATOR_DEPRECATED_X("This flag is unused") = 0x1, // obsolete
+#endif
DontSavePainterState = 0x2,
DontAdjustForAntialiasing = 0x4,
IndirectPainting = 0x8
diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index 31dde8832b..eecc18e5c7 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
@@ -387,44 +387,46 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
- Q_D(QAbstractItemDelegate);
- Q_UNUSED(d);
- Q_UNUSED(index);
- Q_UNUSED(option);
-
if (!event || !view)
return false;
+ Q_D(QAbstractItemDelegate);
switch (event->type()) {
#ifndef QT_NO_TOOLTIP
case QEvent::ToolTip: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
- const QString tooltip = d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision);
- if (!tooltip.isEmpty()) {
- QToolTip::showText(he->globalPos(), tooltip, view);
- return true;
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+ QRect rect;
+ if (index.isValid()) {
+ const QRect r = view->visualRect(index);
+ rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+ }
+ QToolTip::showText(he->globalPos(), tooltip, view, rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
}
- break;}
#endif
#if QT_CONFIG(whatsthis)
- case QEvent::QueryWhatsThis: {
- if (index.data(Qt::WhatsThisRole).isValid())
- return true;
- break; }
+ case QEvent::QueryWhatsThis:
+ event->setAccepted(index.data(Qt::WhatsThisRole).isValid());
+ break;
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp
- const QString whatsthis = d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision);
- if (!whatsthis.isEmpty()) {
- QWhatsThis::showText(he->globalPos(), whatsthis, view);
- return true;
+ const QString whatsthis = index.isValid() ?
+ d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision) :
+ QString();
+ QWhatsThis::showText(he->globalPos(), whatsthis, view);
+ event->setAccepted(!whatsthis.isEmpty());
+ break;
}
- break ; }
#endif
default:
break;
}
- return false;
+ return event->isAccepted();
}
/*!
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 089f398e71..c2afed775c 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1776,8 +1776,8 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
QPoint offset = d->offset();
+ d->pressedPosition = pos + offset;
if ((command & QItemSelectionModel::Current) == 0) {
- d->pressedPosition = pos + offset;
d->currentSelectionStartIndex = index;
}
else if (!d->currentSelectionStartIndex.isValid())
diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp
index 13a1bbd8eb..ba7ee15314 100644
--- a/src/widgets/itemviews/qdirmodel.cpp
+++ b/src/widgets/itemviews/qdirmodel.cpp
@@ -39,6 +39,8 @@
#include "qdirmodel.h"
+#if QT_DEPRECATED_SINCE(5, 15)
+
#include <qfile.h>
#include <qfilesystemmodel.h>
#include <qurl.h>
@@ -1372,3 +1374,5 @@ QFileInfo QDirModelPrivate::resolvedInfo(QFileInfo info)
QT_END_NAMESPACE
#include "moc_qdirmodel.cpp"
+
+#endif // QT_DEPRECATED_SINCE(5, 15)
diff --git a/src/widgets/itemviews/qdirmodel.h b/src/widgets/itemviews/qdirmodel.h
index ab91bbd763..665a622dbe 100644
--- a/src/widgets/itemviews/qdirmodel.h
+++ b/src/widgets/itemviews/qdirmodel.h
@@ -45,6 +45,8 @@
#include <QtCore/qdir.h>
#include <QtWidgets/qfileiconprovider.h>
+#if QT_DEPRECATED_SINCE(5, 15)
+
QT_REQUIRE_CONFIG(dirmodel);
QT_BEGIN_NAMESPACE
@@ -65,9 +67,10 @@ public:
FileNameRole
};
- QDirModel(const QStringList &nameFilters, QDir::Filters filters,
- QDir::SortFlags sort, QObject *parent = nullptr);
- explicit QDirModel(QObject *parent = nullptr);
+ QT_DEPRECATED_VERSION_X_5_15("Use QFileSystemModel") QDirModel(const QStringList &nameFilters,
+ QDir::Filters filters, QDir::SortFlags sort,
+ QObject *parent = nullptr);
+ QT_DEPRECATED_VERSION_X_5_15("Use QFileSystemModel") explicit QDirModel(QObject *parent = nullptr);
~QDirModel();
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
@@ -144,4 +147,6 @@ private:
QT_END_NAMESPACE
+#endif // QT_DEPRECATED_SINCE(5, 15)
+
#endif // QDIRMODEL_H
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index a25a582881..b1dbafa997 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -923,10 +923,8 @@ QTableWidgetSelectionRange::QTableWidgetSelectionRange(int top, int left, int bo
Constructs a the table selection range by copying the given \a
other table selection range.
*/
-QTableWidgetSelectionRange::QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other)
- : top(other.top), left(other.left), bottom(other.bottom), right(other.right)
-{
-}
+QTableWidgetSelectionRange::QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other) = default;
+QTableWidgetSelectionRange &QTableWidgetSelectionRange::operator=(const QTableWidgetSelectionRange &other) = default;
/*!
Destroys the table selection range.
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
index d93032f3f0..0d93a0a075 100644
--- a/src/widgets/itemviews/qtablewidget.h
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -49,14 +49,17 @@ QT_REQUIRE_CONFIG(tablewidget);
QT_BEGIN_NAMESPACE
+// ### Qt6 unexport the class, remove the user-defined special 3 and make it a literal type.
class Q_WIDGETS_EXPORT QTableWidgetSelectionRange
{
public:
QTableWidgetSelectionRange();
QTableWidgetSelectionRange(int top, int left, int bottom, int right);
- QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other);
~QTableWidgetSelectionRange();
+ QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other);
+ QTableWidgetSelectionRange &operator=(const QTableWidgetSelectionRange &other);
+
inline int topRow() const { return top; }
inline int bottomRow() const { return bottom; }
inline int leftColumn() const { return left; }
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index d285ad6d28..a2d6e7798d 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -748,11 +748,14 @@ QMimeData *QTreeModel::internalMimeData() const
QMimeData *QTreeModel::mimeData(const QModelIndexList &indexes) const
{
- QList<QTreeWidgetItem*> items;
- for (const auto &index : indexes) {
- if (index.column() == 0) // only one item per row
- items << item(index);
- }
+ QList<QTreeWidgetItem *> items;
+ std::transform(indexes.begin(), indexes.end(), std::back_inserter(items),
+ [this](const QModelIndex &idx) -> QTreeWidgetItem * { return item(idx); });
+
+ // Ensure we only have one item as an item may have more than
+ // one index selected if there is more than one column
+ std::sort(items.begin(), items.end());
+ items.erase(std::unique(items.begin(), items.end()), items.end());
// cachedIndexes is a little hack to avoid copying from QModelIndexList to
// QList<QTreeWidgetItem*> and back again in the view
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 629c696544..3223781b63 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -3224,8 +3224,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos);
#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
wheel->modifiers(), phase, wheel->source(), wheel->inverted());
+QT_WARNING_POP
#else
QWheelEvent we(relpos, wheel->globalPosition(), wheel->pixelDelta(), wheel->angleDelta(), wheel->buttons(),
wheel->modifiers(), phase, wheel->inverted(), wheel->source());
@@ -3266,8 +3269,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// the end of the natural scrolling sequence.
const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPosition().toPoint());
#if QT_DEPRECATED_SINCE(5, 0)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
wheel->modifiers(), wheel->phase(), wheel->source());
+QT_WARNING_POP
#else
QWheelEvent we(relpos, wheel->globalPosition(), wheel->pixelDelta(), wheel->angleDelta(), wheel->buttons(),
wheel->modifiers(), wheel->phase(), wheel->inverted(), wheel->source());
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
index 27e743a28d..d7cc4489c4 100644
--- a/src/widgets/kernel/qapplication.h
+++ b/src/widgets/kernel/qapplication.h
@@ -58,7 +58,6 @@ class QDesktopWidget;
class QStyle;
class QEventLoop;
class QIcon;
-template <typename T> class QList;
class QLocale;
class QPlatformNativeInterface;
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index d9d071a31a..d0c6b882b5 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -133,6 +133,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
{
QList<QGestureRecognizer *> list = m_recognizers.values(type);
+ m_recognizers.remove(type);
foreach (QGesture *g, m_gestureToRecognizer.keys()) {
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
if (list.contains(recognizer)) {
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 451b18d8d3..bc5ca21b97 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -788,10 +788,12 @@ void QOpenGLWidgetPrivate::initialize()
if (initialized)
return;
- // Get our toplevel's context with which we will share in order to make the
- // texture usable by the underlying window's backingstore.
+ // If no global shared context get our toplevel's context with which we
+ // will share in order to make the texture usable by the underlying window's backingstore.
QWidget *tlw = q->window();
- QOpenGLContext *shareContext = get(tlw)->shareContext();
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = get(tlw)->shareContext();
// If shareContext is null, showing content on-screen will not work.
// However, offscreen rendering and grabFramebuffer() will stay fully functional.
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index 39b08dbc1e..eec65c8625 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -659,24 +659,22 @@ int QShortcut::id() const
bool QShortcut::event(QEvent *e)
{
Q_D(QShortcut);
- bool handled = false;
if (d->sc_enabled && e->type() == QEvent::Shortcut) {
auto se = static_cast<QShortcutEvent *>(e);
if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
#if QT_CONFIG(whatsthis)
if (QWhatsThis::inWhatsThisMode()) {
QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
- handled = true;
} else
#endif
if (se->isAmbiguous())
emit activatedAmbiguously();
else
emit activated();
- handled = true;
+ return true;
}
}
- return handled;
+ return QObject::event(e);
}
#endif // QT_NO_SHORTCUT
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index cf5a81c204..65b3326387 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1513,13 +1513,8 @@ QWidget::~QWidget()
if (d->declarativeData) {
d->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
- if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
- if (QAbstractDeclarativeData::destroyed_qml1)
- QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
- } else {
- if (QAbstractDeclarativeData::destroyed)
- QAbstractDeclarativeData::destroyed(d->declarativeData, this);
- }
+ if (QAbstractDeclarativeData::destroyed)
+ QAbstractDeclarativeData::destroyed(d->declarativeData, this);
d->declarativeData = 0; // don't activate again in ~QObject
d->wasDeleted = false;
}
@@ -6204,7 +6199,7 @@ void QWidget::setFocusProxy(QWidget * w)
if (changingAppFocusWidget) {
QWidget *newDeepestFocusProxy = d_func()->deepestFocusProxy();
- QApplicationPrivate::focus_widget = newDeepestFocusProxy ? newDeepestFocusProxy : this;
+ QApplicationPrivate::setFocusWidget(newDeepestFocusProxy ? newDeepestFocusProxy : this, Qt::NoFocusReason);
}
}
@@ -7669,7 +7664,7 @@ void QWidget::show()
else if (defaultState == Qt::WindowMaximized)
showMaximized();
else
- setVisible(true); // FIXME: Why not showNormal(), like QWindow::show()?
+ setVisible(true); // Don't call showNormal() as not to clobber Qt::Window(Max/Min)imized
}
/*! \internal
@@ -9218,9 +9213,11 @@ void QWidget::mouseReleaseEvent(QMouseEvent *event)
The default implementation calls mousePressEvent().
\note The widget will also receive mouse press and mouse release
- events in addition to the double click event. It is up to the
- developer to ensure that the application interprets these events
- correctly.
+ events in addition to the double click event. And if another widget
+ that overlaps this widget disappears in response to press or
+ release events, then this widget will only receive the double click
+ event. It is up to the developer to ensure that the application
+ interprets these events correctly.
\sa mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(),
event(), QMouseEvent
diff --git a/src/widgets/kernel/qwidgetrepaintmanager.cpp b/src/widgets/kernel/qwidgetrepaintmanager.cpp
index 4eb298e108..c3211e275f 100644
--- a/src/widgets/kernel/qwidgetrepaintmanager.cpp
+++ b/src/widgets/kernel/qwidgetrepaintmanager.cpp
@@ -147,6 +147,7 @@ QWidgetRepaintManager::~QWidgetRepaintManager()
}
/*!
+ \internal
Invalidates the \a r (in widget's coordinates) of the backing store, i.e.
all widgets intersecting with the region will be repainted when the backing
store is synced.
@@ -193,6 +194,7 @@ static inline QRect widgetRectFor(QWidget *, const QRect &r) { return r; }
static inline QRect widgetRectFor(QWidget *widget, const QRegion &) { return widget->rect(); }
/*!
+ \internal
Marks the region of the widget as dirty (if not already marked as dirty) and
posts an UpdateRequest event to the top-level widget (if not already posted).
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 3db85ca07a..271b43fe89 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -5967,6 +5967,7 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
case SP_ArrowLeft:
icon = QIcon::fromTheme(QLatin1String("go-previous"));
break;
+ case SP_DialogNoButton:
case SP_DialogCancelButton:
icon = QIcon::fromTheme(QLatin1String("dialog-cancel"),
QIcon::fromTheme(QLatin1String("process-stop")));
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index ba2b6b0ed9..54bf1d0691 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -88,6 +88,7 @@
#include <private/qstylehelper_p.h>
#include <private/qdrawhelper_p.h>
#include <private/qapplication_p.h>
+#include <private/qwidget_p.h>
QT_BEGIN_NAMESPACE
@@ -364,6 +365,11 @@ static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleB
painter->drawPoint(tmp.right() , tmp.bottom() - 1);
}
+static QWindow *qt_getWindow(const QWidget *widget)
+{
+ return widget ? QWidgetPrivate::get(widget)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest) : nullptr;
+}
+
/*
\internal
*/
@@ -995,7 +1001,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
d->tabBarcloseButtonIcon = proxy()->standardIcon(SP_DialogCloseButton, option, widget);
if ((option->state & State_Enabled) && (option->state & State_MouseOver))
proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
- QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(QSize(16, 16), QIcon::Normal, QIcon::On);
+ QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(qt_getWindow(widget), QSize(16, 16), QIcon::Normal, QIcon::On);
proxy()->drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap);
}
break;
@@ -1035,7 +1041,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (!cb->currentIcon.isNull()) {
QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
: QIcon::Disabled;
- QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QPixmap pixmap = cb->currentIcon.pixmap(qt_getWindow(widget), cb->iconSize, mode);
QRect iconRect(editRect);
iconRect.setWidth(cb->iconSize.width() + 4);
iconRect = alignedRect(cb->direction,
@@ -1647,9 +1653,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
iconSize = combo->iconSize();
#endif
if (checked)
- pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
+ pixmap = menuItem->icon.pixmap(qt_getWindow(widget), iconSize, mode, QIcon::On);
else
- pixmap = menuItem->icon.pixmap(iconSize, mode);
+ pixmap = menuItem->icon.pixmap(qt_getWindow(widget), iconSize, mode);
const int pixw = pixmap.width() / pixmap.devicePixelRatio();
const int pixh = pixmap.height() / pixmap.devicePixelRatio();
@@ -1783,7 +1789,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (button->state & State_On)
state = QIcon::On;
- QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
int w = pixmap.width() / pixmap.devicePixelRatio();
int h = pixmap.height() / pixmap.devicePixelRatio();
@@ -3232,7 +3238,7 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
break;
case CT_MenuItem:
if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- int w = newSize.width();
+ int w = size.width(); // Don't rely of QCommonStyle's width calculation here
int maxpmw = menuItem->maxIconWidth;
int tabSpacing = 20;
if (menuItem->text.contains(QLatin1Char('\t')))
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 6cbed34c3a..ca81be1b2b 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -638,7 +638,6 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
indicator or button bevel.
\omitvalue PE_IndicatorViewItemCheck
- \value PE_FrameStatusBar Obsolete. Use PE_FrameStatusBarItem instead.
\value PE_PanelButtonCommand Button used to initiate an action, for
example, a QPushButton.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index ee234457f5..b51bcbe8d6 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -142,9 +142,6 @@ public:
PE_FrameLineEdit,
PE_FrameMenu,
PE_FrameStatusBarItem,
-#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
- PE_FrameStatusBar Q_DECL_ENUMERATOR_DEPRECATED = PE_FrameStatusBarItem,
-#endif
PE_FrameTabWidget,
PE_FrameWindow,
PE_FrameButtonBevel,
@@ -165,9 +162,6 @@ public:
PE_IndicatorBranch,
PE_IndicatorButtonDropDown,
PE_IndicatorItemViewItemCheck,
-#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
- PE_IndicatorViewItemCheck Q_DECL_ENUMERATOR_DEPRECATED = PE_IndicatorItemViewItemCheck,
-#endif
PE_IndicatorCheckBox,
PE_IndicatorDockWidgetResizeHandle,
PE_IndicatorHeaderArrow,
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 5b3efd598f..01cadd9a86 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1760,7 +1760,7 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
\value Exclusive The item is an exclusive check item (like a radio button).
\value NonExclusive The item is a non-exclusive check item (like a check box).
- \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusive
+ \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusionPolicy
*/
/*!
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index dd225fbec3..88c6c288e8 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -615,7 +615,7 @@ public:
public:
int features;
QBrush defaultBackground;
- QFont font;
+ QFont font; // Be careful using this font directly. Prefer using font.resolve( )
bool hasFont;
QHash<QString, QVariant> styleHints;
@@ -2735,6 +2735,11 @@ static void updateObjects(const QList<const QObject *>& objects)
if (auto widget = qobject_cast<QWidget*>(const_cast<QObject*>(object))) {
widget->style()->polish(widget);
QCoreApplication::sendEvent(widget, &event);
+ QList<const QObject *> children;
+ children.reserve(widget->children().size() + 1);
+ for (auto child: qAsConst(widget->children()))
+ children.append(child);
+ updateObjects(children);
}
}
}
@@ -3211,7 +3216,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
rule.drawRule(p, opt->rect);
toolOpt.rect = rule.contentsRect(opt->rect);
if (rule.hasFont)
- toolOpt.font = rule.font;
+ toolOpt.font = rule.font.resolve(toolOpt.font);
drawControl(CE_ToolButtonLabel, &toolOpt, p, w);
}
@@ -3514,7 +3519,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
const QFont oldFont = p->font();
if (rule.hasFont)
- p->setFont(rule.font);
+ p->setFont(rule.font.resolve(p->font()));
if (rule.hasPosition() && rule.position()->textAlignment != 0) {
Qt::Alignment textAlignment = rule.position()->textAlignment;
@@ -3678,7 +3683,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
subRule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
QFont oldFont = p->font();
if (subRule.hasFont)
- p->setFont(subRule.font.resolve(p->font()));
+ p->setFont(subRule.font.resolve(mi.font));
else
p->setFont(mi.font);
@@ -4084,7 +4089,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
subRule.configurePalette(&boxCopy.palette, QPalette::ButtonText, QPalette::Button);
QFont oldFont = p->font();
if (subRule.hasFont)
- p->setFont(subRule.font);
+ p->setFont(subRule.font.resolve(p->font()));
boxCopy.rect = subRule.contentsRect(opt->rect);
if (subRule.hasImage()) {
// the image is already drawn with CE_ToolBoxTabShape, adjust rect here
@@ -4171,7 +4176,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Base);
QFont oldFont = p->font();
if (subRule.hasFont)
- p->setFont(subRule.font);
+ p->setFont(subRule.font.resolve(p->font()));
if (subRule.hasBox() || !subRule.hasNativeBorder()) {
tabCopy.rect = ce == CE_TabBarTabShape ? subRule.borderRect(r)
: subRule.contentsRect(r);
@@ -5035,8 +5040,12 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
bool nullIcon = hdr->icon.isNull();
const int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
int iconSize = nullIcon ? 0 : pixelMetric(QStyle::PM_SmallIconSize, hdr, w);
- const QSize txt = subRule.hasFont ? QFontMetrics(subRule.font).size(0, hdr->text)
- : hdr->fontMetrics.size(0, hdr->text);
+ QFontMetrics fm = hdr->fontMetrics;
+ if (subRule.hasFont) {
+ QFont styleFont = w ? subRule.font.resolve(w->font()) : subRule.font;
+ fm = QFontMetrics(styleFont);
+ }
+ const QSize txt = fm.size(0, hdr->text);
nativeContentsSize.setHeight(margin + qMax(iconSize, txt.height()) + margin);
nativeContentsSize.setWidth((nullIcon ? 0 : margin) + iconSize
+ (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 72c803cb99..8496a2c223 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -120,10 +120,7 @@ enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
\internal
*/
-QWindowsStylePrivate::QWindowsStylePrivate()
- : alt_down(false), menuBarTimer(0)
-{
-}
+QWindowsStylePrivate::QWindowsStylePrivate() = default;
qreal QWindowsStylePrivate::appDevicePixelRatio()
{
@@ -157,7 +154,7 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
QList<QWidget *> l = widget->findChildren<QWidget *>();
auto ignorable = [](QWidget *w) {
return w->isWindow() || !w->isVisible()
- || w->style()->styleHint(SH_UnderlineShortcut, 0, w);
+ || w->style()->styleHint(SH_UnderlineShortcut, nullptr, w);
};
l.erase(std::remove_if(l.begin(), l.end(), ignorable), l.end());
// Update states before repainting
@@ -242,7 +239,7 @@ void QWindowsStyle::polish(QApplication *app)
QCommonStyle::polish(app);
QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
// We only need the overhead when shortcuts are sometimes hidden
- if (!proxy()->styleHint(SH_UnderlineShortcut, 0) && app)
+ if (!proxy()->styleHint(SH_UnderlineShortcut, nullptr) && app)
app->installEventFilter(this);
const auto &palette = QGuiApplication::palette();
@@ -343,7 +340,6 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
case QStyle::PM_MenuVMargin:
case QStyle::PM_ToolBarItemMargin:
return 1;
- break;
case QStyle::PM_DockWidgetSeparatorExtent:
return 4;
#if QT_CONFIG(tabbar)
@@ -396,8 +392,6 @@ static QScreen *screenOf(const QWidget *w)
// and account for secondary screens with differing logical DPI.
qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget)
{
- if (!QHighDpiScaling::isActive())
- return 1;
qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget);
if (QGuiApplicationPrivate::screen_list.size() > 1) {
const QScreen *primaryScreen = QGuiApplication::primaryScreen();
@@ -698,17 +692,17 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
x -= 2;
if (opt->rect.height() > 4) {
qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
}
} else {
if (opt->rect.width() > 4) {
int y = opt->rect.height() / 2 - 4;
qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
}
}
p->restore();
@@ -759,7 +753,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
}
} else {
qDrawWinButton(p, opt->rect, opt->palette,
- opt->state & (State_Sunken | State_On), panel ? &fill : 0);
+ opt->state & (State_Sunken | State_On), panel ? &fill : nullptr);
}
} else {
p->fillRect(opt->rect, fill);
@@ -980,7 +974,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
if (opt->state & (State_Raised | State_On | State_Sunken)) {
qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
- panel ? &fill : 0);
+ panel ? &fill : nullptr);
} else {
if (panel)
p->fillRect(opt->rect, fill);
@@ -1005,7 +999,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
#endif // QT_CONFIG(dockwidget)
case PE_FrameStatusBarItem:
- qDrawShadePanel(p, opt->rect, opt->palette, true, 1, 0);
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 1, nullptr);
break;
case PE_IndicatorProgressChunk:
@@ -1043,7 +1037,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
break;
case PE_FrameTabWidget: {
- qDrawWinButton(p, opt->rect, opt->palette, false, 0);
+ qDrawWinButton(p, opt->rect, opt->palette, false, nullptr);
break;
}
default:
@@ -1585,6 +1579,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
case QStyleOptionToolBar::Beginning:
case QStyleOptionToolBar::OnlyOne:
paintBottomBorder = false;
+ break;
default:
break;
}
@@ -1600,6 +1595,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
case QStyleOptionToolBar::OnlyOne:
paintRightBorder = false;
paintLeftBorder = false;
+ break;
default:
break;
}
diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h
index e6ea809f11..4f6ffcefc2 100644
--- a/src/widgets/styles/qwindowsstyle_p_p.h
+++ b/src/widgets/styles/qwindowsstyle_p_p.h
@@ -77,9 +77,9 @@ public:
bool hasSeenAlt(const QWidget *widget) const;
bool altDown() const { return alt_down; }
- bool alt_down;
+ bool alt_down = false;
QList<const QWidget *> seenAlt;
- int menuBarTimer;
+ int menuBarTimer = 0;
QColor inactiveCaptionText;
QColor activeCaptionColor;
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 7b69eff30c..3c0271e7c2 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -473,7 +473,7 @@ QMatchData QCompletionEngine::filterHistory()
if (curParts.count() <= 1 || c->proxy->showAll || !source)
return QMatchData();
-#if QT_CONFIG(dirmodel)
+#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15)
const bool isDirModel = (qobject_cast<QDirModel *>(source) != nullptr);
#else
const bool isDirModel = false;
@@ -903,7 +903,7 @@ void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted)
QModelIndex si = proxy->mapToSource(index);
si = si.sibling(si.row(), column); // for clicked()
completion = q->pathFromIndex(si);
-#if QT_CONFIG(dirmodel)
+#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15)
// add a trailing separator in inline
if (mode == QCompleter::InlineCompletion) {
if (qobject_cast<QDirModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
@@ -1125,7 +1125,7 @@ void QCompleter::setModel(QAbstractItemModel *model)
setPopup(d->popup); // set the model and make new connections
if (oldModel && oldModel->QObject::parent() == this)
delete oldModel;
-#if QT_CONFIG(dirmodel)
+#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15)
if (qobject_cast<QDirModel *>(model)) {
#if defined(Q_OS_WIN)
setCaseSensitivity(Qt::CaseInsensitive);
@@ -1846,7 +1846,7 @@ QString QCompleter::pathFromIndex(const QModelIndex& index) const
return QString();
bool isDirModel = false;
bool isFsModel = false;
-#if QT_CONFIG(dirmodel)
+#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15)
isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != nullptr;
#endif
#if QT_CONFIG(filesystemmodel)
@@ -1895,7 +1895,7 @@ QStringList QCompleter::splitPath(const QString& path) const
{
bool isDirModel = false;
bool isFsModel = false;
-#if QT_CONFIG(dirmodel)
+#if QT_CONFIG(dirmodel) && QT_DEPRECATED_SINCE(5, 15)
Q_D(const QCompleter);
isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != nullptr;
#endif
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index fd18888870..ae81cc5661 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -367,8 +367,6 @@ bool QSystemTrayIcon::event(QEvent *e)
This signal is emitted when the message displayed using showMessage()
was clicked by the user.
- Currently this signal is not sent on \macos.
-
\note We follow Microsoft Windows behavior, so the
signal is also emitted when the user clicks on a tray icon with
a balloon message displayed.
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index b295e66574..d2372a7be9 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -1144,11 +1144,14 @@ void QAbstractScrollArea::paintEvent(QPaintEvent*)
mouse press events for the viewport() widget. The event is passed
in \a e.
+ The default implementation calls QWidget::mousePressEvent() for
+ default popup handling.
+
\sa QWidget::mousePressEvent()
*/
void QAbstractScrollArea::mousePressEvent(QMouseEvent *e)
{
- e->ignore();
+ QWidget::mousePressEvent(e);
}
/*!
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index d49d9dbd66..fc19e0793e 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -1726,7 +1726,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
option->activeSubControls = d->hoverControl;
}
- option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds)
+ option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds, nullptr, this)
? stepEnabled()
: (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled);
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index ec19b64d4a..cc0c51b237 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -2413,7 +2413,7 @@ void QCalendarWidget::showNextMonth()
Q_D(const QCalendarWidget);
int year = yearShown();
int month = monthShown();
- if (month == d->m_model->m_calendar.maxMonthsInYear()) {
+ if (month == d->m_model->m_calendar.maximumMonthsInYear()) {
++year;
month = 1;
} else {
@@ -2437,7 +2437,7 @@ void QCalendarWidget::showPreviousMonth()
int month = monthShown();
if (month == 1) {
--year;
- month = d->m_model->m_calendar.maxMonthsInYear();
+ month = d->m_model->m_calendar.maximumMonthsInYear();
} else {
--month;
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e73c63f657..9a0e969e1c 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -862,6 +862,16 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
when the choice is not changed. If you need to know when the
choice actually changes, use signal currentIndexChanged().
+ \obsolete Use QComboBox::textActivated() instead
+*/
+/*!
+ \fn void QComboBox::textActivated(const QString &text)
+ \since 5.14
+
+ This signal is sent when the user chooses an item in the combobox.
+ The item's \a text is passed. Note that this signal is sent even
+ when the choice is not changed. If you need to know when the
+ choice actually changes, use signal currentIndexChanged().
*/
/*!
@@ -876,6 +886,15 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
This signal is sent when an item in the combobox popup list is
highlighted by the user. The item's \a text is passed.
+
+ \obsolete Use textHighlighted() instead
+*/
+/*!
+ \fn void QComboBox::textHighlighted(const QString &text)
+ \since 5.14
+
+ This signal is sent when an item in the combobox popup list is
+ highlighted by the user. The item's \a text is passed.
*/
/*!
@@ -888,7 +907,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
currentIndex was reset.
*/
-#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QComboBox::currentIndexChanged(const QString &text)
\since 4.1
@@ -897,7 +915,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
changes either through user interaction or programmatically. The
item's \a text is passed.
*/
-#endif
/*!
\fn void QComboBox::currentTextChanged(const QString &text)
@@ -2522,21 +2539,6 @@ QSize QComboBox::sizeHint() const
}
#ifdef Q_OS_MAC
-
-namespace {
-struct IndexSetter {
- int index;
- QComboBox *cb;
-
- void operator()(void)
- {
- cb->setCurrentIndex(index);
- emit cb->activated(index);
- emit cb->activated(cb->itemText(index));
- }
-};
-}
-
void QComboBoxPrivate::cleanupNativePopup()
{
if (!m_platformMenu)
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index eadb21628f..5967776a61 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -390,6 +390,16 @@ public:
#ifdef Q_OS_MAC
void cleanupNativePopup();
bool showNativePopup();
+ struct IndexSetter {
+ int index;
+ QComboBox *cb;
+
+ void operator()(void)
+ {
+ cb->setCurrentIndex(index);
+ cb->d_func()->emitActivated(cb->d_func()->currentIndex);
+ }
+ };
#endif
QAbstractItemModel *model;
diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 69eac1ebf7..eec794562a 100644
--- a/src/widgets/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
@@ -389,9 +389,13 @@ bool QGroupBox::event(QEvent *e)
void QGroupBox::childEvent(QChildEvent *c)
{
Q_D(QGroupBox);
- if (c->type() != QEvent::ChildAdded || !c->child()->isWidgetType())
+ /*
+ Children might have been enabled after being added to the group box, in which case
+ the childEvent handler ran too early, and we need to disabled children again.
+ */
+ if (!(c->added() || c->polished()) || !c->child()->isWidgetType())
return;
- QWidget *w = (QWidget*)c->child();
+ QWidget *w = static_cast<QWidget*>(c->child());
if (w->isWindow())
return;
if (d->checkable) {
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index e38490dabd..51b458f03a 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2332,14 +2332,17 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
// However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
// then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
// Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
- const int screenIndex = d->topData()->initialScreenIndex;
- if (screenIndex >= 0)
- d->popupScreen = screenIndex;
- if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
- if (d->setScreen(s))
+ // However if eventLoop exists, then exec() already did this by calling createWinId(); so leave it alone. (QTBUG-76162)
+ if (!d->eventLoop) {
+ const int screenIndex = d->topData()->initialScreenIndex;
+ if (screenIndex >= 0)
+ d->popupScreen = screenIndex;
+ if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
+ if (d->setScreen(s))
+ d->itemsDirty = true;
+ } else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
- } else if (d->setScreenForPoint(p)) {
- d->itemsDirty = true;
+ }
}
const bool contextMenu = d->isContextMenu();
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 3d31a3b73a..69b1c5896f 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -324,15 +324,10 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
QSize popup_size = activeMenu->sizeHint();
//we put the popup menu on the screen containing the bottom-center of the action rect
- QScreen *popupScreen = q->window()->windowHandle()->screen();
- QPoint bottomMiddlePos = pos + QPoint(adjustedActionRect.width() / 2, 0);
- const auto &siblings = popupScreen->virtualSiblings();
- for (QScreen *sibling : siblings) {
- if (sibling->geometry().contains(bottomMiddlePos)) {
- popupScreen = sibling;
- break;
- }
- }
+ QScreen *menubarScreen = q->window()->windowHandle()->screen();
+ QScreen *popupScreen = menubarScreen->virtualSiblingAt(pos + QPoint(adjustedActionRect.width() / 2, 0));
+ if (!popupScreen)
+ popupScreen = menubarScreen;
QRect screenRect = popupScreen->geometry();
pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index e39ef6d1cd..b7c3426e08 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -123,6 +123,11 @@ public:
wish to do your own drawing you can get a pointer to the pixmap
used in the splash screen with pixmap(). Alternatively, you can
subclass QSplashScreen and reimplement drawContents().
+
+ In case of having multiple screens, it is also possible to show the
+ splash screen on a different screen than the primary one. For example:
+
+ \snippet qsplashscreen/main.cpp 2
*/
/*!
@@ -139,6 +144,23 @@ QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f)
/*!
\overload
+ \since 5.15
+
+ This function allows you to specify the screen for your splashscreen. The
+ typical use for this constructor is if you have multiple screens and
+ prefer to have the splash screen on a different screen than your primary
+ one. In that case pass the proper \a screen.
+*/
+QSplashScreen::QSplashScreen(QScreen *screen, const QPixmap &pixmap, Qt::WindowFlags f)
+ : QWidget(*(new QSplashScreenPrivate()), nullptr, Qt::SplashScreen | Qt::FramelessWindowHint | f)
+{
+ d_func()->setPixmap(pixmap, screen);
+}
+
+#if QT_DEPRECATED_SINCE(5, 15)
+/*!
+ \overload
+ \obsolete
This function allows you to specify a parent for your splashscreen. The
typical use for this constructor is if you have a multiple screens and
@@ -152,6 +174,7 @@ QSplashScreen::QSplashScreen(QWidget *parent, const QPixmap &pixmap, Qt::WindowF
// is still 0 here due to QWidget's special handling.
d_func()->setPixmap(pixmap, QSplashScreenPrivate::screenFor(parent));
}
+#endif
/*!
Destructor.
@@ -286,26 +309,35 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap)
}
// In setPixmap(), resize and try to position on a screen according to:
-// 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on
+// 1) If the screen for the given widget is available, use that
+// 2) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on
// QSplashScreen(QWidget *, QPixmap).
-// 2) If a widget with associated QWindow is found, use that
-// 3) When nothing can be found, try to center it over the cursor
+// 3) If a widget with associated QWindow is found, use that
+// 4) When nothing can be found, try to center it over the cursor
+#if QT_DEPRECATED_SINCE(5, 15)
static inline int screenNumberOf(const QDesktopScreenWidget *dsw)
{
auto desktopWidgetPrivate =
static_cast<QDesktopWidgetPrivate *>(qt_widget_private(QApplication::desktop()));
return desktopWidgetPrivate->screens.indexOf(const_cast<QDesktopScreenWidget *>(dsw));
}
+#endif
const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w)
{
+ if (w && w->screen())
+ return w->screen();
+
for (const QWidget *p = w; p !=nullptr ; p = p->parentWidget()) {
+#if QT_DEPRECATED_SINCE(5, 15)
if (auto dsw = qobject_cast<const QDesktopScreenWidget *>(p))
return QGuiApplication::screens().value(screenNumberOf(dsw));
+#endif
if (QWindow *window = p->windowHandle())
return window->screen();
}
+
#if QT_CONFIG(cursor)
// Note: We could rely on QPlatformWindow::initialGeometry() to center it
// over the cursor, but not all platforms (namely Android) use that.
diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h
index 8bdf4e7749..1877493fcf 100644
--- a/src/widgets/widgets/qsplashscreen.h
+++ b/src/widgets/widgets/qsplashscreen.h
@@ -55,7 +55,11 @@ class Q_WIDGETS_EXPORT QSplashScreen : public QWidget
Q_OBJECT
public:
explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags());
+ QSplashScreen(QScreen *screen, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags());
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("Use the constructor taking a QScreen *")
QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags());
+#endif
virtual ~QSplashScreen();
void setPixmap(const QPixmap &pixmap);
diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h
index ec980d9ee3..658914ae39 100644
--- a/src/widgets/widgets/qsplitter.h
+++ b/src/widgets/widgets/qsplitter.h
@@ -50,7 +50,6 @@ QT_BEGIN_NAMESPACE
class QSplitterPrivate;
class QTextStream;
-template <typename T> class QList;
class QSplitterHandle;
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 0ccbad7eaa..dd2ea3f18f 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -237,7 +237,7 @@ void QTextEditPrivate::_q_hoveredBlockWithMarkerChanged(const QTextBlock &block)
Qt::CursorShape cursor = cursorToRestoreAfterHover;
if (block.isValid() && !q->isReadOnly()) {
QTextBlockFormat::MarkerType marker = block.blockFormat().marker();
- if (marker != QTextBlockFormat::NoMarker) {
+ if (marker != QTextBlockFormat::MarkerType::NoMarker) {
if (viewport->cursor().shape() != Qt::PointingHandCursor)
cursorToRestoreAfterHover = viewport->cursor().shape();
cursor = Qt::PointingHandCursor;
@@ -772,6 +772,7 @@ void QTextEdit::setAlignment(Qt::Alignment a)
QTextCursor cursor = d->control->textCursor();
cursor.mergeBlockFormat(fmt);
d->control->setTextCursor(cursor);
+ d->relayoutDocument();
}
/*!
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index d50e19a5ed..961a261e8f 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -533,7 +533,7 @@ bool QToolBarLayout::layoutActions(const QSize &size)
if (expanded)
rperp(o, size) = rowHeight;
else
- rperp(o, size) = perp(o, rect.size()) - perp(o, QSize(margins.top(), margins.left()));
+ rperp(o, size) = perp(o, rect.size()) - perp(o, margins);
QRect r(pos, size);
if (o == Qt::Horizontal)
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index fdbaf29dd8..094c59a0c9 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1810,11 +1810,11 @@ void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton but
if (markerBlock == blockWithMarkerUnderMouse) {
auto fmt = blockWithMarkerUnderMouse.blockFormat();
switch (fmt.marker()) {
- case QTextBlockFormat::Unchecked :
- fmt.setMarker(QTextBlockFormat::Checked);
+ case QTextBlockFormat::MarkerType::Unchecked :
+ fmt.setMarker(QTextBlockFormat::MarkerType::Checked);
break;
- case QTextBlockFormat::Checked:
- fmt.setMarker(QTextBlockFormat::Unchecked);
+ case QTextBlockFormat::MarkerType::Checked:
+ fmt.setMarker(QTextBlockFormat::MarkerType::Unchecked);
break;
default:
break;
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 8d232237bf..3e8b18d449 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -4984,7 +4984,7 @@ bool QDomElement::hasAttribute(const QString& name) const
\sa setAttributeNS(), attributeNodeNS(), setAttributeNodeNS(), attribute()
*/
-QString QDomElement::attributeNS(const QString nsURI, const QString& localName, const QString& defValue) const
+QString QDomElement::attributeNS(const QString& nsURI, const QString& localName, const QString& defValue) const
{
if (!impl)
return defValue;
@@ -5003,7 +5003,7 @@ QString QDomElement::attributeNS(const QString nsURI, const QString& localName,
\sa attributeNS(), setAttributeNodeNS(), setAttribute()
*/
-void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, const QString& value)
+void QDomElement::setAttributeNS(const QString& nsURI, const QString& qName, const QString& value)
{
if (!impl)
return;
@@ -5011,13 +5011,13 @@ void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, cons
}
/*!
- \fn void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, int value)
+ \fn void QDomElement::setAttributeNS(const QString& nsURI, const QString& qName, int value)
\overload
*/
/*!
- \fn void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, uint value)
+ \fn void QDomElement::setAttributeNS(const QString& nsURI, const QString& qName, uint value)
\overload
*/
@@ -5025,7 +5025,7 @@ void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, cons
/*!
\overload
*/
-void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qlonglong value)
+void QDomElement::setAttributeNS(const QString& nsURI, const QString& qName, qlonglong value)
{
if (!impl)
return;
@@ -5037,7 +5037,7 @@ void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qlon
/*!
\overload
*/
-void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qulonglong value)
+void QDomElement::setAttributeNS(const QString& nsURI, const QString& qName, qulonglong value)
{
if (!impl)
return;
@@ -5049,7 +5049,7 @@ void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qulo
/*!
\overload
*/
-void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, double value)
+void QDomElement::setAttributeNS(const QString& nsURI, const QString& qName, double value)
{
if (!impl)
return;
diff --git a/src/xml/dom/qdom.h b/src/xml/dom/qdom.h
index 0a7db7dcd7..2d07e34f3b 100644
--- a/src/xml/dom/qdom.h
+++ b/src/xml/dom/qdom.h
@@ -493,15 +493,15 @@ public:
QDomNodeList elementsByTagName(const QString& tagname) const;
bool hasAttribute(const QString& name) const;
- QString attributeNS(const QString nsURI, const QString& localName, const QString& defValue = QString()) const;
- void setAttributeNS(const QString nsURI, const QString& qName, const QString& value);
- inline void setAttributeNS(const QString nsURI, const QString& qName, int value)
+ QString attributeNS(const QString& nsURI, const QString& localName, const QString& defValue = QString()) const;
+ void setAttributeNS(const QString& nsURI, const QString& qName, const QString& value);
+ inline void setAttributeNS(const QString& nsURI, const QString& qName, int value)
{ setAttributeNS(nsURI, qName, qlonglong(value)); }
- inline void setAttributeNS(const QString nsURI, const QString& qName, uint value)
+ inline void setAttributeNS(const QString& nsURI, const QString& qName, uint value)
{ setAttributeNS(nsURI, qName, qulonglong(value)); }
- void setAttributeNS(const QString nsURI, const QString& qName, qlonglong value);
- void setAttributeNS(const QString nsURI, const QString& qName, qulonglong value);
- void setAttributeNS(const QString nsURI, const QString& qName, double value);
+ void setAttributeNS(const QString& nsURI, const QString& qName, qlonglong value);
+ void setAttributeNS(const QString& nsURI, const QString& qName, qulonglong value);
+ void setAttributeNS(const QString& nsURI, const QString& qName, double value);
void removeAttributeNS(const QString& nsURI, const QString& localName);
QDomAttr attributeNodeNS(const QString& nsURI, const QString& localName);
QDomAttr setAttributeNodeNS(const QDomAttr& newAttr);